From 740b30688bd745a527f96f9116c19acb3480971a Mon Sep 17 00:00:00 2001 From: Bertrand Marc Date: Wed, 6 Jun 2012 20:47:48 +0200 Subject: Imported Upstream version 0.9.3 --- AUTHORS | 3 + ChangeLog | 883 ++++ Makefile.in | 2 + README | 44 +- configure | 585 ++- configure.ac | 209 +- contrib/Makefile.am | 42 +- contrib/Makefile.in | 153 +- contrib/gnunet-gns-import.sh | 4 + contrib/gnunet_janitor.py.in | 12 +- contrib/hellos/02UK | Bin 0 -> 312 bytes contrib/hellos/1G1M | Bin 0 -> 312 bytes contrib/hellos/7RAV | Bin 0 -> 292 bytes contrib/hellos/8B4T | Bin 0 -> 292 bytes contrib/hellos/94CH | Bin 0 -> 292 bytes contrib/hellos/ATF4 | Bin 0 -> 312 bytes contrib/hellos/F1GT | Bin 0 -> 312 bytes contrib/hellos/KD9V | Bin 0 -> 292 bytes contrib/hellos/KUPL | Bin 0 -> 312 bytes contrib/hellos/LJR8 | Bin 0 -> 312 bytes contrib/hellos/R69Q | Bin 0 -> 292 bytes contrib/hellos/R6OV | Bin 0 -> 312 bytes contrib/hellos/RL7P | Bin 0 -> 312 bytes contrib/timeout_watchdog_w32.c | 190 + doc/Makefile.in | 2 + doc/man/Makefile.am | 4 + doc/man/Makefile.in | 6 + doc/man/gnunet-arm.1 | 3 + doc/man/gnunet-core.1 | 35 + doc/man/gnunet-gns.1 | 36 + doc/man/gnunet-namestore.1 | 58 + doc/man/gnunet-rsa.1 | 40 + gnunet_config.h | 33 +- gnunet_config.h.in | 19 +- m4/Makefile.in | 2 + pkgconfig/Makefile.in | 13 +- pkgconfig/gnunetregex.pc.in | 12 + po/POTFILES.in | 42 +- po/de.gmo | Bin 6870 -> 6753 bytes po/de.po | 3390 +++++++++------- po/es.gmo | Bin 6270 -> 6270 bytes po/es.po | 3357 +++++++++------- po/gnunet.pot | 3089 +++++++------- po/sv.gmo | Bin 4058 -> 3950 bytes po/sv.po | 3349 ++++++++------- po/vi.gmo | Bin 14375 -> 13248 bytes po/vi.po | 3391 +++++++++------- po/zh_CN.gmo | Bin 4364 -> 4304 bytes po/zh_CN.po | 3188 ++++++++------- src/Makefile.am | 16 +- src/Makefile.in | 19 +- src/arm/Makefile.in | 2 + src/arm/arm.conf.in | 2 +- src/arm/arm.h | 21 + src/arm/arm_api.c | 498 ++- src/arm/do_start_process.c | 1 + src/arm/gnunet-arm.c | 56 +- src/arm/gnunet-service-arm.c | 354 +- src/arm/mockup-service.c | 31 - src/arm/test_exponential_backoff.c | 88 +- src/ats/Makefile.am | 13 +- src/ats/Makefile.in | 35 +- src/ats/ats.conf.in | 18 +- src/ats/ats.h | 9 + src/ats/ats_api_performance.c | 4 +- src/ats/ats_api_scheduling.c | 112 +- src/ats/gnunet-service-ats.c | 9 +- src/ats/gnunet-service-ats_addresses.c | 282 +- src/ats/gnunet-service-ats_addresses.h | 15 +- src/ats/gnunet-service-ats_addresses_mlp.c | 225 +- src/ats/gnunet-service-ats_addresses_mlp.h | 16 +- src/ats/gnunet-service-ats_performance.c | 2 +- src/ats/gnunet-service-ats_scheduling.c | 51 +- src/ats/gnunet-service-ats_scheduling.h | 13 + src/ats/perf_ats_mlp.c | 372 +- src/ats/test_ats_api.conf | 30 +- src/ats/test_ats_api_reset_backoff.c | 308 ++ src/ats/test_ats_api_scheduling.c | 13 +- src/ats/test_ats_mlp.c | 14 +- src/ats/test_ats_mlp_averaging.c | 14 +- src/block/Makefile.in | 2 + src/block/block.c | 2 +- src/block/plugin_block_test.c | 5 +- src/chat/Makefile.in | 2 + src/chat/chat.c | 2 +- src/chat/gnunet-chat.c | 102 +- src/chat/test_chat.c | 2 +- src/chat/test_chat_private.c | 2 +- src/core/Makefile.am | 15 +- src/core/Makefile.in | 42 +- src/core/core.conf.in | 2 +- src/core/core.h | 36 +- src/core/core_api.c | 167 +- src/core/core_api_is_connected.c | 232 ++ src/core/core_api_iterate_peers.c | 56 +- src/core/gnunet-core-list-connections.c | 207 - src/core/gnunet-core.c | 99 + src/core/gnunet-service-core.c | 2 - src/core/gnunet-service-core_clients.c | 115 +- src/core/gnunet-service-core_clients.h | 3 +- src/core/gnunet-service-core_kx.c | 326 +- src/core/gnunet-service-core_neighbours.c | 16 +- src/core/gnunet-service-core_sessions.c | 12 +- src/core/test_core_api.c | 2 +- src/core/test_core_api_peer2.conf | 26 +- src/core/test_core_api_reliability.c | 34 +- src/core/test_core_api_send_to_self.c | 2 +- src/core/test_core_api_start_only.c | 2 +- src/core/test_core_defaults.conf | 6 + ...t_core_quota_asymmetric_recv_limited_peer2.conf | 10 +- ...est_core_quota_asymmetric_send_limit_peer2.conf | 12 +- src/core/test_core_quota_compliance.c | 51 +- src/core/test_core_quota_peer2.conf | 12 +- src/datacache/Makefile.am | 2 + src/datacache/Makefile.in | 6 + src/datacache/datacache.c | 9 - src/datacache/plugin_datacache_mysql.c | 575 +-- src/datacache/plugin_datacache_postgres.c | 216 +- src/datacache/plugin_datacache_sqlite.c | 20 +- src/datastore/Makefile.am | 2 + src/datastore/Makefile.in | 6 + src/datastore/datastore.h | 5 +- src/datastore/datastore_api.c | 94 +- src/datastore/gnunet-service-datastore.c | 56 +- src/datastore/perf_datastore_api.c | 5 +- src/datastore/plugin_datastore_mysql.c | 689 +--- src/datastore/plugin_datastore_postgres.c | 305 +- src/datastore/plugin_datastore_sqlite.c | 27 - src/datastore/test_datastore_api.c | 4 +- src/datastore/test_datastore_api_management.c | 5 +- src/datastore/test_defaults.conf | 3 + src/dht/Makefile.am | 11 + src/dht/Makefile.in | 41 +- src/dht/dht.conf.in | 2 +- src/dht/dht.h | 179 +- src/dht/dht_api.c | 605 ++- src/dht/gnunet-dht-get.c | 2 +- src/dht/gnunet-dht-monitor.c | 325 ++ src/dht/gnunet-dht-put.c | 30 +- src/dht/gnunet-service-dht_clients.c | 437 +- src/dht/gnunet-service-dht_clients.h | 86 +- src/dht/gnunet-service-dht_datacache.c | 2 - src/dht/gnunet-service-dht_neighbours.c | 84 +- src/dht/gnunet-service-dht_neighbours.h | 9 + src/dht/gnunet-service-dht_routing.c | 67 +- src/dht/plugin_block_dht.c | 14 +- src/dht/test_dht_2dtorus.conf | 4 +- src/dht/test_dht_api.c | 8 +- src/dht/test_dht_api_data.conf | 3 +- src/dht/test_dht_api_peer1.conf | 2 +- src/dht/test_dht_line.conf | 2 + src/dht/test_dht_monitor.c | 177 +- src/dht/test_dht_multipeer.c | 31 +- src/dht/test_dht_multipeer_data.conf | 7 +- src/dht/test_dht_topo.c | 107 +- src/dht/test_dht_twopeer.c | 21 +- src/dht/test_dht_twopeer_data.conf | 8 +- src/dht/test_dht_twopeer_get_put.c | 21 +- src/dht/test_dht_twopeer_path_tracking.c | 4 +- src/dht/test_dht_twopeer_put_get.c | 42 +- src/dns/Makefile.am | 5 +- src/dns/Makefile.in | 8 +- src/dns/dns.h | 4 +- src/dns/dns_api.c | 2 +- src/dns/gnunet-service-dns.c | 54 +- src/dns/plugin_block_dns.c | 2 +- src/dv/Makefile.in | 2 + src/dv/dv_api.c | 2 +- src/dv/gnunet-service-dv.c | 17 +- src/dv/plugin_transport_dv.c | 4 +- src/dv/test_transport_api_dv.c | 2 +- src/exit/Makefile.in | 2 + src/exit/exit.h | 6 +- src/exit/gnunet-daemon-exit.c | 41 +- src/fragmentation/Makefile.am | 2 +- src/fragmentation/Makefile.in | 4 +- src/fragmentation/defragmentation.c | 18 +- src/fragmentation/fragmentation.c | 36 +- src/fs/Makefile.am | 14 +- src/fs/Makefile.in | 33 +- src/fs/fs.conf.in | 13 +- src/fs/fs_api.c | 134 +- src/fs/fs_api.h | 154 +- src/fs/fs_dirmetascan.c | 26 +- src/fs/fs_download.c | 577 +-- src/fs/fs_file_information.c | 10 +- src/fs/fs_list_indexed.c | 2 +- src/fs/fs_publish.c | 34 +- src/fs/fs_publish_ksk.c | 2 +- src/fs/fs_search.c | 266 +- src/fs/fs_tree.c | 7 +- src/fs/fs_unindex.c | 349 +- src/fs/fs_uri.c | 16 +- src/fs/gnunet-directory.c | 2 +- src/fs/gnunet-download.c | 3 +- src/fs/gnunet-helper-fs-publish.c | 55 +- src/fs/gnunet-pseudonym.c | 22 +- src/fs/gnunet-publish.c | 6 + src/fs/gnunet-service-fs.h | 2 +- src/fs/gnunet-service-fs_indexing.c | 2 +- src/fs/gnunet-service-fs_lc.c | 6 +- src/fs/gnunet-service-fs_pr.c | 4 +- src/fs/gnunet-service-fs_put.c | 74 +- src/fs/perf_gnunet_service_fs_p2p.c | 2 +- src/fs/test_fs_defaults.conf | 3 + src/fs/test_fs_download.c | 4 +- src/fs/test_fs_download_indexed.c | 20 +- src/fs/test_fs_download_persistence.c | 4 +- src/fs/test_fs_list_indexed.c | 2 +- src/fs/test_fs_namespace.c | 19 +- src/fs/test_fs_namespace_list_updateable.c | 2 +- src/fs/test_fs_publish.c | 2 +- src/fs/test_fs_publish_persistence.c | 2 +- src/fs/test_fs_search.c | 12 +- src/fs/test_fs_search_persistence.c | 2 +- src/fs/test_fs_search_probes.c | 268 ++ src/fs/test_fs_start_stop.c | 2 +- src/fs/test_fs_test_lib.c | 7 - src/fs/test_fs_unindex.c | 2 +- src/fs/test_fs_unindex_persistence.c | 2 +- src/fs/test_gnunet_fs_idx.py.in | 0 src/fs/test_gnunet_fs_ns.py.in | 0 src/fs/test_gnunet_fs_psd.py.in | 0 src/fs/test_gnunet_fs_rec.py.in | 0 src/fs/test_gnunet_service_fs_migration.c | 4 +- src/fs/test_gnunet_service_fs_p2p.c | 2 +- src/gns/Makefile.am | 260 +- src/gns/Makefile.in | 641 ++- src/gns/gns.conf.in | 25 +- src/gns/gns.h | 125 +- src/gns/gns_api.c | 919 +++-- src/gns/gns_proxy_proto.h | 49 + src/gns/gnunet-gns-fcfsd.c | 811 ++++ src/gns/gnunet-gns-proxy.c | 815 ++++ src/gns/gnunet-gns.c | 262 ++ src/gns/gnunet-service-gns.c | 1801 ++++----- src/gns/gnunet-service-gns_interceptor.c | 394 ++ src/gns/gnunet-service-gns_interceptor.h | 23 + src/gns/gnunet-service-gns_resolver.c | 2751 +++++++++++++ src/gns/gnunet-service-gns_resolver.h | 356 ++ src/gns/namestore_stub_api.c | 438 -- src/gns/nss/Makefile.am | 59 + src/gns/nss/Makefile.in | 769 ++++ src/gns/nss/map-file | 14 + src/gns/nss/nss_gns.c | 264 ++ src/gns/nss/nss_gns_query.c | 65 + src/gns/nss/nss_gns_query.h | 66 + src/gns/plugin_block_gns.c | 165 +- src/gns/test_gns_defaults.conf | 69 + src/gns/test_gns_dht_default.conf | 94 + src/gns/test_gns_dht_delegated_lookup.c | 411 ++ src/gns/test_gns_dht_threepeer.c | 524 +++ src/gns/test_gns_max_queries.c | 381 ++ src/gns/test_gns_pseu_shorten.c | 643 +++ src/gns/test_gns_simple_delegated_lookup.c | 355 ++ src/gns/test_gns_simple_get_authority.c | 388 ++ src/gns/test_gns_simple_lookup.c | 317 ++ src/gns/test_gns_simple_lookup.conf | 112 + src/gns/test_gns_simple_mx_lookup.c | 396 ++ src/gns/test_gns_simple_shorten.c | 388 ++ src/gns/test_gns_simple_zkey_lookup.c | 358 ++ src/gns/test_gns_twopeer.c | 463 --- src/gns/test_gns_twopeer.conf | 80 - src/gns/test_gnunet_gns.sh | 22 - src/hello/Makefile.am | 13 + src/hello/Makefile.in | 65 +- src/hello/gnunet-hello.c | 204 + src/hello/hello.c | 41 + src/hello/test_hello.c | 2 +- src/hostlist/Makefile.in | 2 + src/hostlist/hostlist-client.c | 70 +- src/hostlist/hostlist-server.c | 181 +- src/hostlist/hostlist.conf | 5 +- src/hostlist/learning_data.conf | 6 - src/hostlist/test_gnunet_daemon_hostlist.c | 12 +- .../test_gnunet_daemon_hostlist_learning.c | 53 +- .../test_gnunet_daemon_hostlist_peer1.conf | 1 + .../test_gnunet_daemon_hostlist_reconnect.c | 2 +- src/hostlist/test_hostlist_defaults.conf | 6 + src/include/Makefile.am | 6 + src/include/Makefile.in | 24 +- src/include/block_dns.h | 2 +- src/include/block_gns.h | 14 +- src/include/gnunet_arm_service.h | 25 + src/include/gnunet_ats_service.h | 14 +- src/include/gnunet_client_lib.h | 19 +- src/include/gnunet_common.h | 28 +- src/include/gnunet_configuration_lib.h | 13 + src/include/gnunet_connection_lib.h | 95 +- src/include/gnunet_container_lib.h | 21 +- src/include/gnunet_core_service.h | 31 +- src/include/gnunet_crypto_lib.h | 187 +- src/include/gnunet_datastore_service.h | 4 +- src/include/gnunet_dht_service.h | 143 +- src/include/gnunet_disk_lib.h | 10 +- src/include/gnunet_dnsparser_lib.h | 2 +- src/include/gnunet_fs_service.h | 6 +- src/include/gnunet_gns_service.h | 162 +- src/include/gnunet_helper_lib.h | 23 +- src/include/gnunet_lockmanager_service.h | 165 + src/include/gnunet_mysql_lib.h | 214 + src/include/gnunet_namestore_plugin.h | 33 +- src/include/gnunet_namestore_service.h | 202 +- src/include/gnunet_nat_lib.h | 5 +- src/include/gnunet_network_lib.h | 20 + src/include/gnunet_os_lib.h | 5 +- src/include/gnunet_peerinfo_service.h | 40 +- src/include/gnunet_postgres_lib.h | 163 + src/include/gnunet_program_lib.h | 22 + src/include/gnunet_protocols.h | 76 +- src/include/gnunet_pseudonym_lib.h | 72 +- src/include/gnunet_regex_lib.h | 180 + src/include/gnunet_scheduler_lib.h | 56 +- src/include/gnunet_server_lib.h | 80 +- src/include/gnunet_service_lib.h | 45 +- src/include/gnunet_signatures.h | 6 + src/include/gnunet_statistics_service.h | 1 + src/include/gnunet_stream_lib.h | 94 +- src/include/gnunet_strings_lib.h | 173 +- src/include/gnunet_testbed_service.h | 1029 +++++ src/include/gnunet_testing_lib-new.h | 299 ++ src/include/gnunet_testing_lib.h | 29 +- src/include/gnunet_time_lib.h | 70 +- src/include/gnunet_transport_plugin.h | 43 +- src/include/gnunet_tun_lib.h | 6 +- src/include/platform.h | 8 + src/include/plibc.h | 7 +- src/integration-tests/Makefile.am | 60 +- src/integration-tests/Makefile.in | 284 +- .../confs/c_bootstrap_server.conf | 8 + src/integration-tests/confs/c_nat_client.conf | 11 +- src/integration-tests/confs/c_no_nat_client.conf | 8 + src/integration-tests/confs/c_no_nat_client_2.conf | 7 + .../confs/c_no_nat_client_http.conf | 363 ++ .../confs/c_no_nat_client_http_2.conf | 352 ++ .../confs/c_no_nat_client_unix.conf | 366 ++ .../confs/c_no_nat_client_unix_2.conf | 355 ++ .../confs/c_normal_client_tcp.conf | 360 ++ .../confs/c_normal_client_tcp_udp.conf | 360 ++ .../confs/c_normal_client_tcp_udp_http.conf | 360 ++ src/integration-tests/connection_watchdog.c | 1099 +++++ src/integration-tests/gnunet_testing.py.in | 79 +- src/integration-tests/test_connection_stability.c | 126 + .../test_connection_stability.conf | 82 + .../test_integration_bootstrap_and_connect.py.in | 6 +- ...tion_bootstrap_and_connect_and_disconnect.py.in | 8 +- ..._bootstrap_and_connect_and_disconnect_nat.py.in | 8 +- .../test_integration_clique.py.in | 14 +- .../test_integration_clique_nat.py.in | 14 +- .../test_integration_connect_on_restart.py.in | 180 + .../test_integration_connection_values_tcp.py.in | 124 + ...est_integration_connection_values_tcp_udp.py.in | 124 + ...ntegration_connection_values_tcp_udp_http.py.in | 124 + .../test_integration_disconnect.py.in | 8 +- .../test_integration_restart.py.in | 10 +- src/lockmanager/Makefile.am | 68 + src/lockmanager/Makefile.in | 933 +++++ src/lockmanager/gnunet-service-lockmanager.c | 899 +++++ src/lockmanager/lockmanager.conf.in | 13 + src/lockmanager/lockmanager.h | 71 + src/lockmanager/lockmanager_api.c | 677 ++++ src/lockmanager/test_lockmanager_api.c | 279 ++ src/lockmanager/test_lockmanager_api.conf | 73 + src/lockmanager/test_lockmanager_api_lockrelease.c | 301 ++ src/lockmanager/test_lockmanager_api_servercrash.c | 326 ++ src/mesh/Makefile.am | 2 +- src/mesh/Makefile.in | 4 +- src/mesh/gnunet-service-mesh.c | 53 +- src/mesh/mesh_api.c | 69 +- src/mesh/mesh_tunnel_tree.c | 12 +- src/mesh/test_mesh.conf | 5 +- src/mesh/test_mesh_2dtorus.c | 4 +- src/mesh/test_mesh_api.c | 2 +- src/mesh/test_mesh_local_1.c | 2 +- src/mesh/test_mesh_local_2.c | 2 +- src/mesh/test_mesh_path.conf | 2 +- src/mesh/test_mesh_small.c | 2 +- src/mysql/Makefile.am | 20 + src/mysql/Makefile.in | 654 +++ src/mysql/mysql.c | 698 ++++ src/namestore/Makefile.am | 142 +- src/namestore/Makefile.in | 489 ++- src/namestore/gnunet-namestore.c | 507 +++ src/namestore/gnunet-service-namestore.c | 1501 ++++++- src/namestore/hostkey | Bin 913 -> 0 bytes src/namestore/namestore.conf.in | 1 + src/namestore/namestore.h | 441 +- src/namestore/namestore_api.c | 736 +++- src/namestore/namestore_common.c | 582 ++- src/namestore/plugin_namestore_sqlite.c | 352 +- src/namestore/test_hostkey | Bin 0 -> 914 bytes src/namestore/test_namestore_api.c | 35 +- src/namestore/test_namestore_api.conf | 7 +- src/namestore/test_namestore_api_create.c | 478 +++ src/namestore/test_namestore_api_create_update.c | 517 +++ src/namestore/test_namestore_api_lookup.c | 317 ++ .../test_namestore_api_lookup_specific_type.c | 399 ++ src/namestore/test_namestore_api_put.c | 249 ++ src/namestore/test_namestore_api_remove.c | 366 ++ ...test_namestore_api_remove_not_existing_record.c | 299 ++ src/namestore/test_namestore_api_sign_verify.c | 150 + src/namestore/test_namestore_api_zone_iteration.c | 334 +- ...st_namestore_api_zone_iteration_specific_zone.c | 451 +++ .../test_namestore_api_zone_iteration_stop.c | 501 +++ src/namestore/test_namestore_api_zone_to_name.c | 288 ++ .../test_namestore_record_serialization.c | 29 +- src/namestore/test_plugin_namestore.c | 9 +- ...34DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey | Bin 0 -> 913 bytes ...FUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey | Bin 0 -> 914 bytes src/nat/Makefile.in | 2 + src/nat/gnunet-nat-server.c | 10 - src/nat/nat.c | 37 +- src/nat/nat.h | 1 - src/nat/nat_mini.c | 10 +- src/nat/nat_test.c | 31 +- src/nat/test_nat.c | 19 +- src/nat/test_nat_data.conf | 4 +- src/nat/test_nat_test.c | 25 +- src/nat/test_nat_test_data.conf | 11 +- src/nse/Makefile.in | 2 + src/nse/gnunet-nse-profiler.c | 6 +- src/nse/gnunet-service-nse.c | 94 +- src/nse/nse.conf.in | 2 +- src/nse/nse_api.c | 14 +- src/nse/nse_profiler_test.conf | 34 +- src/nse/test_nse_api.c | 13 +- src/peerinfo-tool/Makefile.am | 5 +- src/peerinfo-tool/Makefile.in | 11 +- src/peerinfo-tool/gnunet-peerinfo.c | 801 +++- src/peerinfo-tool/gnunet-peerinfo_plugins.c | 178 + src/peerinfo-tool/gnunet-peerinfo_plugins.h | 58 + src/peerinfo-tool/test_gnunet_peerinfo.py.in | 8 +- src/peerinfo/Makefile.in | 2 + src/peerinfo/gnunet-service-peerinfo.c | 170 +- src/peerinfo/peerinfo.h | 1 - src/peerinfo/peerinfo_api.c | 533 ++- src/peerinfo/peerinfo_api_notify.c | 12 +- src/peerinfo/perf_peerinfo_api.c | 35 +- src/peerinfo/test_peerinfo_api.c | 15 +- src/postgres/Makefile.am | 20 + src/postgres/Makefile.in | 654 +++ src/postgres/postgres.c | 189 + src/pt/Makefile.in | 2 + src/regex/Makefile.am | 42 + src/regex/Makefile.in | 800 ++++ src/regex/regex.c | 2252 +++++++++++ src/regex/test_regex_eval_api.c | 311 ++ src/regex/test_regex_iterate_api.c | 71 + src/statistics/Makefile.am | 11 +- src/statistics/Makefile.in | 31 +- src/statistics/gnunet-service-statistics.c | 233 +- src/statistics/gnunet-statistics.c | 78 +- src/statistics/statistics.conf.in | 2 +- src/statistics/statistics.h | 1 - src/statistics/statistics_api.c | 244 +- src/statistics/test_statistics_api.c | 19 +- src/statistics/test_statistics_api_data.conf | 15 +- src/statistics/test_statistics_api_loop.c | 2 +- src/statistics/test_statistics_api_watch.c | 2 +- .../test_statistics_api_watch_zero_value.c | 201 + src/stream/Makefile.am | 29 +- src/stream/Makefile.in | 67 +- src/stream/README | 12 +- src/stream/stream_api.c | 2193 +++++++--- src/stream/stream_protocol.h | 8 +- src/stream/test_stream_2peers.c | 560 +++ src/stream/test_stream_2peers_halfclose.c | 786 ++++ src/stream/test_stream_local.c | 272 +- src/stream/test_stream_local.conf | 14 +- src/template/Makefile.in | 2 + src/testbed/Makefile.am | 39 + src/testbed/Makefile.in | 713 ++++ src/testbed/testbed.conf | 0 src/testbed/testbed.h | 535 +++ src/testbed/testbed_api.c | 150 + src/testbed/testbed_api_hosts.c | 200 + src/testbed/testbed_api_hosts.h | 105 + src/testbed/testbed_api_operations.c | 194 + src/testbed/testbed_api_operations.h | 132 + src/testbed/testbed_api_peers.c | 297 ++ src/testbed/testbed_api_peers.h | 71 + src/testbed/testbed_api_services.c | 61 + src/testbed/testbed_api_test.c | 67 + src/testbed/testbed_api_testbed.c | 153 + src/testbed/testbed_api_topology.c | 127 + src/testing/Makefile.am | 43 +- src/testing/Makefile.in | 126 +- src/testing/gnunet-testing.c | 2 +- src/testing/test_testing_2dtorus.c | 2 +- src/testing/test_testing_2dtorus.conf | 6 +- .../test_testing_data_topology_2d_torus.conf | 3 +- src/testing/test_testing_defaults.conf | 6 + src/testing/test_testing_group_remote.c | 2 +- src/testing/test_testing_new_peerstartup.c | 161 + src/testing/test_testing_new_portreservation.c | 90 + src/testing/test_testing_new_servicestartup.c | 110 + src/testing/test_testing_topology.c | 105 +- src/testing/test_testing_topology_blacklist.c | 2 +- src/testing/test_testing_topology_churn.c | 28 - src/testing/testing.c | 235 +- src/testing/testing_group.c | 354 +- src/testing/testing_new.c | 1000 +++++ src/testing/testing_peergroup.c | 72 +- src/topology/Makefile.in | 2 + src/topology/gnunet-daemon-topology.c | 172 +- src/topology/test_gnunet_daemon_topology.c | 14 - src/topology/test_gnunet_daemon_topology_data.conf | 3 +- src/transport/Makefile.am | 4 +- src/transport/Makefile.in | 88 +- src/transport/gnunet-helper-transport-wlan-dummy.c | 302 +- src/transport/gnunet-helper-transport-wlan.c | 1453 ++++--- src/transport/gnunet-service-transport.c | 61 +- src/transport/gnunet-service-transport_blacklist.c | 55 +- src/transport/gnunet-service-transport_blacklist.h | 2 + src/transport/gnunet-service-transport_clients.c | 36 +- src/transport/gnunet-service-transport_hello.c | 17 +- .../gnunet-service-transport_neighbours.c | 4246 +++++++++++--------- .../gnunet-service-transport_neighbours.h | 30 +- .../gnunet-service-transport_validation.c | 53 +- .../gnunet-service-transport_validation.h | 7 +- .../gnunet-transport-certificate-creation | 2 +- .../gnunet-transport-certificate-creation.c | 4 +- src/transport/gnunet-transport-wlan-sender.c | 80 +- src/transport/gnunet-transport.c | 51 +- src/transport/plugin_transport_http.c | 452 ++- src/transport/plugin_transport_http.h | 63 +- src/transport/plugin_transport_http_client.c | 199 +- src/transport/plugin_transport_http_server.c | 269 +- src/transport/plugin_transport_tcp.c | 876 ++-- src/transport/plugin_transport_udp.c | 783 ++-- src/transport/plugin_transport_udp_broadcasting.c | 106 +- src/transport/plugin_transport_unix.c | 572 ++- src/transport/plugin_transport_wlan.c | 3849 ++++++------------ src/transport/plugin_transport_wlan.h | 167 +- src/transport/template_cfg_peer1.conf | 3 + src/transport/template_cfg_peer2.conf | 3 + ...test_quota_compliance_tcp_asymmetric_peer1.conf | 1 + ...test_quota_compliance_tcp_asymmetric_peer2.conf | 1 + src/transport/test_quota_compliance_tcp_peer1.conf | 1 + src/transport/test_quota_compliance_tcp_peer2.conf | 1 + src/transport/test_transport_api.c | 58 +- .../test_transport_api_bidirectional_connect.c | 58 +- ..._transport_api_bidirectional_connect_peer1.conf | 33 +- ..._transport_api_bidirectional_connect_peer2.conf | 31 +- src/transport/test_transport_api_blacklisting.c | 18 +- .../test_transport_api_disconnect_tcp_peer1.conf | 1 + .../test_transport_api_disconnect_tcp_peer2.conf | 1 + src/transport/test_transport_api_limited_sockets.c | 26 +- ...st_transport_api_limited_sockets_tcp_peer1.conf | 1 + ...st_transport_api_limited_sockets_tcp_peer2.conf | 1 + src/transport/test_transport_api_reliability.c | 2 +- ...st_transport_api_reliability_tcp_nat_peer1.conf | 1 + ...st_transport_api_reliability_tcp_nat_peer2.conf | 1 + .../test_transport_api_reliability_tcp_peer1.conf | 1 + .../test_transport_api_reliability_tcp_peer2.conf | 1 + src/transport/test_transport_api_restart_1peer.c | 55 +- src/transport/test_transport_api_restart_2peers.c | 70 +- .../test_transport_api_tcp_nat_peer1.conf | 1 + .../test_transport_api_tcp_nat_peer2.conf | 1 + src/transport/test_transport_api_tcp_peer1.conf | 1 + src/transport/test_transport_api_tcp_peer2.conf | 1 + src/transport/test_transport_api_timeout.c | 27 +- .../test_transport_api_timeout_tcp_peer1.conf | 1 + .../test_transport_api_timeout_tcp_peer2.conf | 1 + src/transport/test_transport_defaults.conf | 6 + src/transport/transport-testing.c | 103 +- src/transport/transport.conf.in | 4 +- src/transport/transport.h | 7 +- src/transport/transport_api.c | 54 +- src/transport/transport_api_address_lookup.c | 10 +- src/transport/transport_api_address_to_string.c | 14 +- src/transport/transport_api_blacklist.c | 4 +- src/tun/Makefile.in | 2 + src/util/Makefile.am | 36 +- src/util/Makefile.in | 90 +- src/util/client.c | 503 +-- src/util/common_logging.c | 17 +- src/util/configuration.c | 37 +- src/util/connection.c | 1184 +++--- src/util/container_bloomfilter.c | 31 +- src/util/container_heap.c | 14 +- src/util/container_slist.c | 29 +- src/util/crypto_aes.c | 87 +- src/util/crypto_hash.c | 235 +- src/util/crypto_hkdf.c | 1 + src/util/crypto_ksk.c | 195 +- src/util/crypto_random.c | 6 +- src/util/crypto_rsa.c | 163 +- src/util/disk.c | 106 +- src/util/getopt.c | 15 +- src/util/getopt_helpers.c | 9 +- src/util/gnunet-rsa.c | 128 + src/util/gnunet-service-resolver.c | 8 +- src/util/helper.c | 142 +- src/util/load.c | 1 - src/util/network.c | 211 +- src/util/os_installation.c | 2 +- src/util/os_priority.c | 193 +- src/util/program.c | 54 +- src/util/pseudonym.c | 205 +- src/util/resolver.conf.in | 2 +- src/util/resolver.h | 2 - src/util/resolver_api.c | 40 +- src/util/scheduler.c | 160 +- src/util/server.c | 753 ++-- src/util/server_mst.c | 13 +- src/util/server_nc.c | 100 +- src/util/server_tc.c | 5 +- src/util/service.c | 408 +- src/util/speedup.c | 92 + src/util/strings.c | 697 +++- src/util/test_client.c | 6 +- src/util/test_common_logging_runtime_loglevels.c | 2 +- src/util/test_configuration.c | 7 +- src/util/test_connection.c | 6 +- src/util/test_connection_addressing.c | 7 +- src/util/test_connection_receive_cancel.c | 7 +- src/util/test_connection_timeout.c | 4 +- src/util/test_connection_transmit_cancel.c | 2 +- src/util/test_disk.c | 2 +- src/util/test_os_start_process.c | 75 +- src/util/test_pseudonym.c | 30 +- src/util/test_resolver_api.c | 28 +- src/util/test_scheduler.c | 44 +- src/util/test_server.c | 2 +- src/util/test_server_disconnect.c | 2 +- src/util/test_server_mst_interrupt.c | 81 + src/util/test_server_with_client.c | 2 +- src/util/test_server_with_client_unix.c | 2 +- src/util/test_service.c | 63 +- src/util/test_speedup.c | 120 + src/util/test_speedup_data.conf | 3 + src/util/test_strings.c | 2 + src/util/test_time.c | 24 +- src/util/time.c | 77 +- src/util/util.conf | 2 + src/util/winproc.c | 3 +- src/vpn/Makefile.in | 2 + src/vpn/gnunet-service-vpn.c | 168 +- src/vpn/test_gnunet_vpn.c | 46 +- src/vpn/test_gnunet_vpn.conf | 8 +- src/vpn/vpn.h | 2 +- src/vpn/vpn_api.c | 4 +- 643 files changed, 81645 insertions(+), 29393 deletions(-) create mode 100755 contrib/gnunet-gns-import.sh create mode 100644 contrib/hellos/02UK create mode 100644 contrib/hellos/1G1M create mode 100644 contrib/hellos/7RAV create mode 100644 contrib/hellos/8B4T create mode 100644 contrib/hellos/94CH create mode 100644 contrib/hellos/ATF4 create mode 100644 contrib/hellos/F1GT create mode 100644 contrib/hellos/KD9V create mode 100644 contrib/hellos/KUPL create mode 100644 contrib/hellos/LJR8 create mode 100644 contrib/hellos/R69Q create mode 100644 contrib/hellos/R6OV create mode 100644 contrib/hellos/RL7P create mode 100644 contrib/timeout_watchdog_w32.c create mode 100644 doc/man/gnunet-core.1 create mode 100644 doc/man/gnunet-gns.1 create mode 100644 doc/man/gnunet-namestore.1 create mode 100644 doc/man/gnunet-rsa.1 create mode 100644 pkgconfig/gnunetregex.pc.in create mode 100644 src/ats/test_ats_api_reset_backoff.c create mode 100644 src/core/core_api_is_connected.c delete mode 100644 src/core/gnunet-core-list-connections.c create mode 100644 src/core/gnunet-core.c create mode 100644 src/dht/gnunet-dht-monitor.c create mode 100644 src/fs/test_fs_search_probes.c mode change 100755 => 100644 src/fs/test_gnunet_fs_idx.py.in mode change 100755 => 100644 src/fs/test_gnunet_fs_ns.py.in mode change 100755 => 100644 src/fs/test_gnunet_fs_psd.py.in mode change 100755 => 100644 src/fs/test_gnunet_fs_rec.py.in create mode 100644 src/gns/gns_proxy_proto.h create mode 100644 src/gns/gnunet-gns-fcfsd.c create mode 100644 src/gns/gnunet-gns-proxy.c create mode 100644 src/gns/gnunet-gns.c create mode 100644 src/gns/gnunet-service-gns_interceptor.c create mode 100644 src/gns/gnunet-service-gns_interceptor.h create mode 100644 src/gns/gnunet-service-gns_resolver.c create mode 100644 src/gns/gnunet-service-gns_resolver.h delete mode 100644 src/gns/namestore_stub_api.c create mode 100644 src/gns/nss/Makefile.am create mode 100644 src/gns/nss/Makefile.in create mode 100644 src/gns/nss/map-file create mode 100644 src/gns/nss/nss_gns.c create mode 100644 src/gns/nss/nss_gns_query.c create mode 100644 src/gns/nss/nss_gns_query.h create mode 100644 src/gns/test_gns_defaults.conf create mode 100644 src/gns/test_gns_dht_default.conf create mode 100644 src/gns/test_gns_dht_delegated_lookup.c create mode 100644 src/gns/test_gns_dht_threepeer.c create mode 100644 src/gns/test_gns_max_queries.c create mode 100644 src/gns/test_gns_pseu_shorten.c create mode 100644 src/gns/test_gns_simple_delegated_lookup.c create mode 100644 src/gns/test_gns_simple_get_authority.c create mode 100644 src/gns/test_gns_simple_lookup.c create mode 100644 src/gns/test_gns_simple_lookup.conf create mode 100644 src/gns/test_gns_simple_mx_lookup.c create mode 100644 src/gns/test_gns_simple_shorten.c create mode 100644 src/gns/test_gns_simple_zkey_lookup.c delete mode 100644 src/gns/test_gns_twopeer.c delete mode 100644 src/gns/test_gns_twopeer.conf delete mode 100755 src/gns/test_gnunet_gns.sh create mode 100644 src/hello/gnunet-hello.c create mode 100644 src/include/gnunet_lockmanager_service.h create mode 100644 src/include/gnunet_mysql_lib.h create mode 100644 src/include/gnunet_postgres_lib.h create mode 100644 src/include/gnunet_regex_lib.h create mode 100644 src/include/gnunet_testbed_service.h create mode 100644 src/include/gnunet_testing_lib-new.h create mode 100644 src/integration-tests/confs/c_no_nat_client_http.conf create mode 100644 src/integration-tests/confs/c_no_nat_client_http_2.conf create mode 100644 src/integration-tests/confs/c_no_nat_client_unix.conf create mode 100644 src/integration-tests/confs/c_no_nat_client_unix_2.conf create mode 100644 src/integration-tests/confs/c_normal_client_tcp.conf create mode 100644 src/integration-tests/confs/c_normal_client_tcp_udp.conf create mode 100644 src/integration-tests/confs/c_normal_client_tcp_udp_http.conf create mode 100644 src/integration-tests/connection_watchdog.c create mode 100644 src/integration-tests/test_connection_stability.c create mode 100644 src/integration-tests/test_connection_stability.conf create mode 100755 src/integration-tests/test_integration_connect_on_restart.py.in create mode 100755 src/integration-tests/test_integration_connection_values_tcp.py.in create mode 100755 src/integration-tests/test_integration_connection_values_tcp_udp.py.in create mode 100755 src/integration-tests/test_integration_connection_values_tcp_udp_http.py.in create mode 100644 src/lockmanager/Makefile.am create mode 100644 src/lockmanager/Makefile.in create mode 100644 src/lockmanager/gnunet-service-lockmanager.c create mode 100644 src/lockmanager/lockmanager.conf.in create mode 100644 src/lockmanager/lockmanager.h create mode 100644 src/lockmanager/lockmanager_api.c create mode 100644 src/lockmanager/test_lockmanager_api.c create mode 100644 src/lockmanager/test_lockmanager_api.conf create mode 100644 src/lockmanager/test_lockmanager_api_lockrelease.c create mode 100644 src/lockmanager/test_lockmanager_api_servercrash.c create mode 100644 src/mysql/Makefile.am create mode 100644 src/mysql/Makefile.in create mode 100644 src/mysql/mysql.c create mode 100644 src/namestore/gnunet-namestore.c delete mode 100644 src/namestore/hostkey create mode 100644 src/namestore/test_hostkey create mode 100644 src/namestore/test_namestore_api_create.c create mode 100644 src/namestore/test_namestore_api_create_update.c create mode 100644 src/namestore/test_namestore_api_lookup.c create mode 100644 src/namestore/test_namestore_api_lookup_specific_type.c create mode 100644 src/namestore/test_namestore_api_put.c create mode 100644 src/namestore/test_namestore_api_remove.c create mode 100644 src/namestore/test_namestore_api_remove_not_existing_record.c create mode 100644 src/namestore/test_namestore_api_sign_verify.c create mode 100644 src/namestore/test_namestore_api_zone_iteration_specific_zone.c create mode 100644 src/namestore/test_namestore_api_zone_iteration_stop.c create mode 100644 src/namestore/test_namestore_api_zone_to_name.c create mode 100644 src/namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey create mode 100644 src/namestore/zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey create mode 100644 src/peerinfo-tool/gnunet-peerinfo_plugins.c create mode 100644 src/peerinfo-tool/gnunet-peerinfo_plugins.h mode change 100755 => 100644 src/peerinfo-tool/test_gnunet_peerinfo.py.in mode change 100755 => 100644 src/peerinfo/perf_peerinfo_api.c create mode 100644 src/postgres/Makefile.am create mode 100644 src/postgres/Makefile.in create mode 100644 src/postgres/postgres.c create mode 100644 src/regex/Makefile.am create mode 100644 src/regex/Makefile.in create mode 100644 src/regex/regex.c create mode 100644 src/regex/test_regex_eval_api.c create mode 100644 src/regex/test_regex_iterate_api.c create mode 100644 src/statistics/test_statistics_api_watch_zero_value.c create mode 100644 src/stream/test_stream_2peers.c create mode 100644 src/stream/test_stream_2peers_halfclose.c create mode 100644 src/testbed/Makefile.am create mode 100644 src/testbed/Makefile.in create mode 100644 src/testbed/testbed.conf create mode 100644 src/testbed/testbed.h create mode 100644 src/testbed/testbed_api.c create mode 100644 src/testbed/testbed_api_hosts.c create mode 100644 src/testbed/testbed_api_hosts.h create mode 100644 src/testbed/testbed_api_operations.c create mode 100644 src/testbed/testbed_api_operations.h create mode 100644 src/testbed/testbed_api_peers.c create mode 100644 src/testbed/testbed_api_peers.h create mode 100644 src/testbed/testbed_api_services.c create mode 100644 src/testbed/testbed_api_test.c create mode 100644 src/testbed/testbed_api_testbed.c create mode 100644 src/testbed/testbed_api_topology.c create mode 100644 src/testing/test_testing_new_peerstartup.c create mode 100644 src/testing/test_testing_new_portreservation.c create mode 100644 src/testing/test_testing_new_servicestartup.c create mode 100644 src/testing/testing_new.c create mode 100644 src/util/gnunet-rsa.c create mode 100644 src/util/speedup.c create mode 100644 src/util/test_server_mst_interrupt.c create mode 100644 src/util/test_speedup.c create mode 100644 src/util/test_speedup_data.conf diff --git a/AUTHORS b/AUTHORS index 61de3fa..22db535 100644 --- a/AUTHORS +++ b/AUTHORS @@ -18,6 +18,9 @@ Nils Durner Safey Allah Mohammed Philipp Tölke , Vitaly Minko +Sree Harsha Totakura --- http://sreeharsha.totakura.in/ +Martin Schanzenbach +Maximilian Szengel Code contributions also came from: Adam Warrington [ UPnP ] diff --git a/ChangeLog b/ChangeLog index d238cfa..d1ebc0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,886 @@ +2012-06-02 14:39 grothoff + + * [r21729] configure.ac, src/include/plibc.h, src/util/server.c, + src/util/winproc.c: LRN: Update plibc and utf8ization + +2012-06-01 18:51 wachs + + * [r21714] src/transport/plugin_transport_http_client.c, + src/transport/plugin_transport_http_server.c: fix for 2395 + +2012-06-01 15:36 wachs + + * [r21704] src/ats/gnunet-service-ats_addresses.c: fix for 0002392 + +2012-06-01 08:58 schanzen + + * [r21684] src/gns/nss/Makefile.am, src/gns/nss/nss_gns.c, + src/gns/nss/nss_gns_query.c, src/gns/nss/nss_gns_query.h, + src/gns/nss/query.c, src/gns/nss/query.h, src/gns/nss/util.c, + src/gns/nss/util.h: cleanup + +2012-06-01 08:53 wachs + + * [r21683] src/transport/plugin_transport_unix.c: additional error + message + +2012-06-01 08:53 wachs + + * [r21682] src/transport/plugin_transport_http_server.c: remove + unused variable + +2012-05-30 21:21 harsha + + * [r21647] src/testing/Makefile.am, src/testing/testing_new.c: test + case for peer startup in new testing library + +2012-05-30 14:47 wachs + + * [r21646] src/util/Makefile.am, src/util/program.c, + src/util/service.c, src/util/speedup.c, src/util/test_speedup.c, + src/util/test_speedup_data.conf, src/util/util.conf: speedup + mechanism to manipulate gnunet time + +2012-05-30 14:34 harsha + + * [r21645] src/testing/testing_new.c: comments and fixed NULL check + for tm + +2012-05-30 14:26 harsha + + * [r21644] src/testing/testing_new.c: refined + GNUNET_TESTING_service_run + +2012-05-29 14:06 harsha + + * [r21634] src/testing/testing_new.c: removed double rsa key free + +2012-05-27 21:46 grothoff + + * [r21608] src/ats/gnunet-service-ats_addresses.c, + src/ats/gnunet-service-ats_addresses_mlp.c, + src/ats/test_ats_api_update_address.c, + src/core/core_api_is_connected.c, + src/core/core_api_iterate_peers.c, src/dns/plugin_block_dns.c, + src/dv/gnunet-service-dv.c, + src/gns/gnunet-service-gns_resolver.c, + src/gns/plugin_block_gns.c, + src/gns/test_gns_dht_delegated_lookup.c, + src/gns/test_gns_max_queries.c, src/gns/test_gns_pseu_shorten.c, + src/gns/test_gns_simple_delegated_lookup.c, + src/gns/test_gns_simple_get_authority.c, + src/gns/test_gns_simple_lookup.c, + src/gns/test_gns_simple_mx_lookup.c, + src/gns/test_gns_simple_shorten.c, + src/gns/test_gns_simple_zkey_lookup.c, + src/hostlist/hostlist-client.c, src/include/gnunet_time_lib.h, + src/integration-tests/connection_watchdog.c, + src/mesh/gnunet-service-mesh.c, src/mesh/test_mesh_2dtorus.c, + src/mesh/test_mesh_small.c, src/namestore/gnunet-namestore.c, + src/namestore/gnunet-service-namestore.c, + src/namestore/namestore_api.c, + src/namestore/test_namestore_api.c, + src/namestore/test_namestore_api_create.c, + src/namestore/test_namestore_api_create_update.c, + src/namestore/test_namestore_api_lookup.c, + src/namestore/test_namestore_api_lookup_specific_type.c, + src/namestore/test_namestore_api_put.c, + src/namestore/test_namestore_api_remove.c, + src/namestore/test_namestore_api_remove_not_existing_record.c, + src/namestore/test_namestore_api_zone_iteration.c, + src/namestore/test_namestore_api_zone_iteration_specific_zone.c, + src/namestore/test_namestore_api_zone_iteration_stop.c, + src/namestore/test_namestore_record_serialization.c, + src/nse/gnunet-nse-profiler.c, src/nse/nse_profiler_test.conf, + src/testing/test_testing_2dtorus.c, src/testing/testing_group.c, + src/transport/plugin_transport_http.c, + src/transport/plugin_transport_http_server.c, + src/transport/plugin_transport_udp.c, src/util/test_time.c, + src/util/time.c: renaming GNUNET_TIME_relative_get_forever and + GNUNET_TIME_absolute_get_forever methods, adding underscore, to + make it clear that the respective #defines should be used + instead; replacing use of direct function calls with respective + macros where applicable; adding additional + GNUNET_TIME_relative_get_xxx-functions to avoid calls to + GNUNET_TIME_relative_multiply, which turn out to have gotten + performance-relevant + +2012-05-27 21:11 grothoff + + * [r21607] src/util/server.c: use + GNUNET_SCHEDULER_add_read_net_with_priority instead of + constructing fd sets in server with only one active listen socket + +2012-05-27 21:10 grothoff + + * [r21606] src/gns/gnunet-service-gns.c, + src/include/gnunet_scheduler_lib.h, src/util/scheduler.c: adding + GNUNET_SCHEDULER_add_read_net_with_priority + +2012-05-26 15:14 harsha + + * [r21586] src/testing/test_testing_new_portreservation.c, + src/testing/testing_new.c: port reservation - release + +2012-05-26 14:04 harsha + + * [r21585] src/testing, src/testing/Makefile.am, + src/testing/test_testing_new_portreservation.c, + src/testing/testing_new.c: port reservation and test cases + +2012-05-25 14:40 harsha + + * [r21578] src/testing/testing_new.c: testing port reservation + +2012-05-25 09:34 wachs + + * [r21573] src/transport/plugin_transport_tcp.c, + src/transport/plugin_transport_udp.c: session timeout for udp and + tcp + +2012-05-25 08:25 wachs + + * [r21572] src/transport/gnunet-service-transport_neighbours.c: + +2012-05-23 07:10 wachs + + * [r21562] contrib/gnunet_janitor.py.in: LRN's patch + +2012-05-22 15:43 harsha + + * [r21561] src/stream, src/testing/testing_new.c: testing port + checking (incomplete) + +2012-05-22 15:03 harsha + + * [r21560] src/stream/test_stream_2peers.c, + src/stream/test_stream_2peers_halfclose.c, + src/stream/test_stream_local.c: fixed segmentation fault due to + missing GNUNET_STREAM_OPTION_END + +2012-05-20 15:06 harsha + + * [r21552] src/testing/testing_new.c: testing system + +2012-05-15 14:07 harsha + + * [r21499] src/lockmanager, src/lockmanager/lockmanager_api.c, + src/lockmanager/test_lockmanager_api.c, + src/lockmanager/test_lockmanager_api_servercrash.c: handling + replies continuously from server + +2012-05-15 13:09 harsha + + * [r21497] src/lockmanager/Makefile.am, + src/lockmanager/lockmanager_api.c, + src/lockmanager/test_lockmanager_api_servercrash.c: server crash + test case + +2012-05-15 10:00 wachs + + * [r21492] src/transport/gnunet-service-transport_neighbours.c: fix + for mantis 2356 + +2012-05-15 09:11 wachs + + * [r21491] src/transport/plugin_transport_wlan.c: fix memleak + +2012-05-15 08:09 wachs + + * [r21490] src/transport/gnunet-service-transport_neighbours.c: fix + for mantis 2355 + +2012-05-14 13:32 harsha + + * [r21476] src/lockmanager/lockmanager_api.c: removed local + function + +2012-05-14 13:04 harsha + + * [r21475] src/stream/stream_api.c, + src/stream/test_stream_2peers_halfclose.c: warnings + +2012-05-14 09:06 wachs + + * [r21469] src/transport/plugin_transport_udp.c: fix for mantis + 2346 + +2012-05-13 18:07 harsha + + * [r21463] src/include/gnunet_lockmanager_service.h, + src/lockmanager/lockmanager_api.c: change in API documentation + and function for finding lockingRequest in hashmap + +2012-05-13 17:21 harsha + + * [r21462] src/lockmanager, src/lockmanager/Makefile.am, + src/lockmanager/gnunet-service-lockmanager.c, + src/lockmanager/lockmanager_api.c, + src/lockmanager/test_lockmanager_api.conf, + src/lockmanager/test_lockmanager_api_lockrelease.c: clean + shutdown in lockmanager, test case for lock release and message + format checks for incoming msg in lockmanager API + +2012-05-12 08:40 harsha + + * [r21447] src/stream/stream_api.c: peer ids in logging and + indentation + +2012-05-11 21:50 harsha + + * [r21442] src/lockmanager/gnunet-service-lockmanager.c: inlining + of helper functions + +2012-05-11 13:55 grothoff + + * [r21440] src/lockmanager/gnunet-service-lockmanager.c, + src/transport/plugin_transport_wlan.c: doxygen + +2012-05-11 08:18 harsha + + * [r21435] src/stream/stream_api.c: logging and indentation + +2012-05-10 16:26 wachs + + * [r21421] src/transport/plugin_transport_wlan.c: fixing WLAN + +2012-05-10 15:44 harsha + + * [r21420] src/lockmanager/gnunet-service-lockmanager.c: NULL check + on disconnect handler + +2012-05-10 15:26 harsha + + * [r21419] src/lockmanager/gnunet-service-lockmanager.c: + lockmanager with new datastructure + +2012-05-09 14:29 szengel + + * [r21387] src/regex/regex.c: fixes + +2012-05-09 13:32 wachs + + * [r21383] src/util/server_nc.c: fix for mantis 2330#c5818 + GNUNET_SERVER_notification_context_destroy does not cancel + transmit_ready + +2012-05-09 13:25 szengel + + * [r21382] src/regex/regex.c: Fixed warning + +2012-05-09 09:59 harsha + + * [r21369] src/lockmanager/gnunet-service-lockmanager.c: processing + upon lock release + +2012-05-09 08:29 harsha + + * [r21367] src/lockmanager/gnunet-service-lockmanager.c: lock + acquire and release + +2012-05-09 07:09 harsha + + * [r21366] src/lockmanager/gnunet-service-lockmanager.c: added list + processing + +2012-05-08 17:10 bartpolot + + * [r21352] src/arm/gnunet-service-arm.c, + src/ats/test_ats_api_bandwidth_consumption.c, + src/ats/test_ats_api_scheduling.c, src/chat/test_chat.c, + src/chat/test_chat_private.c, src/core/test_core_api.c, + src/core/test_core_api_reliability.c, + src/core/test_core_api_send_to_self.c, + src/core/test_core_api_start_only.c, + src/core/test_core_quota_compliance.c, + src/datastore/perf_datastore_api.c, + src/datastore/test_datastore_api.c, + src/datastore/test_datastore_api_management.c, + src/dht/test_dht_api.c, src/fs/test_fs.c, + src/fs/test_fs_download.c, src/fs/test_fs_download_indexed.c, + src/fs/test_fs_download_persistence.c, + src/fs/test_fs_download_recursive.c, + src/fs/test_fs_list_indexed.c, src/fs/test_fs_namespace.c, + src/fs/test_fs_namespace_list_updateable.c, + src/fs/test_fs_publish.c, src/fs/test_fs_publish_persistence.c, + src/fs/test_fs_search.c, src/fs/test_fs_search_persistence.c, + src/fs/test_fs_search_probes.c, src/fs/test_fs_search_ranking.c, + src/fs/test_fs_start_stop.c, src/fs/test_fs_unindex.c, + src/fs/test_fs_unindex_persistence.c, + src/hostlist/test_gnunet_daemon_hostlist.c, + src/hostlist/test_gnunet_daemon_hostlist_learning.c, + src/hostlist/test_gnunet_daemon_hostlist_reconnect.c, + src/include/gnunet_os_lib.h, + src/lockmanager/test_lockmanager_api.c, src/mesh/test_mesh_api.c, + src/mesh/test_mesh_local_1.c, src/mesh/test_mesh_local_2.c, + src/namestore/test_namestore_api.c, + src/namestore/test_namestore_api_create.c, + src/namestore/test_namestore_api_create_update.c, + src/namestore/test_namestore_api_lookup.c, + src/namestore/test_namestore_api_lookup_specific_type.c, + src/namestore/test_namestore_api_put.c, + src/namestore/test_namestore_api_remove.c, + src/namestore/test_namestore_api_remove_not_existing_record.c, + src/namestore/test_namestore_api_zone_iteration.c, + src/namestore/test_namestore_api_zone_iteration_specific_zone.c, + src/namestore/test_namestore_api_zone_iteration_stop.c, + src/namestore/test_namestore_api_zone_to_name.c, src/nat/nat.c, + src/nat/nat_mini.c, src/nat/test_nat_test.c, + src/nse/test_nse_api.c, src/peerinfo/perf_peerinfo_api.c, + src/peerinfo/test_peerinfo_api.c, + src/statistics/test_statistics_api.c, + src/statistics/test_statistics_api_loop.c, + src/statistics/test_statistics_api_watch.c, + src/statistics/test_statistics_api_watch_zero_value.c, + src/stream/test_stream_api.c, src/stream/test_stream_local.c, + src/testing/test_testing_large_topology.c, + src/testing/test_testing_topology.c, src/testing/testing.c, + src/testing/testing_group.c, + src/transport/gnunet-transport-certificate-creation.c, + src/transport/gnunet-transport.c, + src/transport/plugin_transport_http_server.c, + src/transport/plugin_transport_wlan.c, + src/transport/transport-testing.c, src/util/crypto_random.c, + src/util/helper.c, src/util/os_priority.c, + src/util/test_common_logging_runtime_loglevels.c, + src/util/test_os_start_process.c, src/util/test_resolver_api.c, + src/vpn/test_gnunet_vpn.c: Renamed GNUNET_OS_process_close to + GNUNET_OS_process_destroy + +2012-05-07 17:31 szengel + + * [r21330] src/regex/regex.c, src/regex/test_regex_iterate_api.c: + Fixed compilation warnings + +2012-05-07 13:35 grothoff + + * [r21324] contrib/Makefile.am, contrib/timeout_watchdog_w32.c: + LRN: creating watchdog helper binary for W32 + +2012-05-07 08:25 wachs + + * [r21315] src/transport/gnunet-service-transport_neighbours.c: fix + for mantis 2320 + +2012-05-04 12:57 bartpolot + + * [r21271] src/dht/dht.h, src/dht/dht_api.c, + src/dht/gnunet-service-dht_clients.c: Added stop operation for + dht monitoring + +2012-05-03 13:49 grothoff + + * [r21248] src/peerinfo/peerinfo_api.c: doxygen + +2012-05-03 11:36 grothoff + + * [r21244] src/peerinfo/perf_peerinfo_api.c, + src/peerinfo/test_peerinfo_api.c: f-xi + +2012-05-02 13:24 wachs + + * [r21223] src/peerinfo-tool/gnunet-peerinfo.c: fix 2297 + +2012-04-27 13:44 wachs + + * [r21203] src/transport/plugin_transport_unix.c: working string + toaddress + +2012-04-22 19:52 grothoff + + * [r21075] src/arm/gnunet-service-arm.c, + src/ats/gnunet-service-ats.c, src/include/gnunet_server_lib.h, + src/include/gnunet_service_lib.h, + src/namestore/gnunet-service-namestore.c, + src/peerinfo/gnunet-service-peerinfo.c, + src/statistics/gnunet-service-statistics.c, + src/transport/gnunet-service-transport.c, + src/transport/gnunet-service-transport_blacklist.c, + src/transport/gnunet-service-transport_clients.c, + src/transport/plugin_transport_tcp.c, src/util/server.c, + src/util/service.c: introducing soft shutdown concept for + services; during soft shutdown, services that are still managing + non-monitor clients continue to run until those clients + disconnect; however, the services do stop to accept new + connections (will stop listening); soft shutdown is now used by + ats, transport, peerinfo, namestore and most importantly + statistics; this should fix #2197 + +2012-04-21 18:16 grothoff + + * [r21060] src/include/gnunet_container_lib.h, + src/util/container_bloomfilter.c: changing bloomfilter to allow + GNUNET_CONTAINER_bloomfilter_init with sizes that are not powers + of 2 -- GNUNET_CONTAINER_bloomfilter_load will continue to round + up to power of two + +2012-04-20 12:35 szengel + + * [r21054] src/regex/regex.c, src/regex/test_regex_iterate_api.c: + recursion for dfa construction + +2012-04-19 11:39 szengel + + * [r21025] src/regex/regex.c, src/regex/test_regex_eval_api.c, + src/regex/test_regex_iterate_api.c: dfa minimization fix + +2012-04-18 14:02 szengel + + * [r21011] src/include/gnunet_regex_lib.h, src/regex/Makefile.am, + src/regex/regex.c, src/regex/test_regex.c, + src/regex/test_regex_eval_api.c, + src/regex/test_regex_iterate_api.c: test update + +2012-04-18 13:49 wachs + + * [r21009] src/statistics/statistics_api.c: fix 2273 + +2012-04-18 09:55 wachs + + * [r21005] src/statistics/Makefile.am, + src/statistics/gnunet-service-statistics.c, + src/statistics/test_statistics_api_watch_zero_value.c: fixing bug + 2272: added functionality for watch to notifz about fresh created + entries with value 0 + +2012-04-18 09:30 szengel + + * [r21004] src/include/gnunet_regex_lib.h, src/regex/regex.c: added + accepting state info to api + +2012-04-17 20:43 szengel + + * [r21001] src/include/gnunet_regex_lib.h, src/regex/regex.c: api + changes + +2012-04-12 13:28 szengel + + * [r20965] src/regex/regex.c: bugfix + +2012-04-12 11:48 szengel + + * [r20959] src/regex/regex.c, src/regex/test_regex.c: Added '?' + operator + +2012-04-11 15:30 szengel + + * [r20947] src/regex/regex.c: comments + +2012-04-11 14:13 szengel + + * [r20943] src/regex/regex.c: doxygen fix + +2012-04-10 14:37 szengel + + * [r20925] src/regex/regex.c, src/regex/test_regex.c: fix + +2012-04-10 14:30 szengel + + * [r20924] src/regex/regex.c, src/regex/test_regex.c: dfa + minimization wip + +2012-04-09 14:56 szengel + + * [r20911] src/regex/regex.c, src/regex/test_regex.c: fixes + +2012-04-05 14:28 szengel + + * [r20905] src/regex/regex.c, src/regex/test_regex.c: removing + unreachable states + +2012-04-05 12:38 szengel + + * [r20904] src/regex/test_regex.c: better testing + +2012-04-05 11:46 szengel + + * [r20902] src/regex/regex.c, src/regex/test_regex.c: Automatic + regex generation for testing + +2012-04-04 08:21 grothoff + + * [r20893] configure.ac, src/fs/fs.conf.in: adding configure option + to run GNUnet with monkey + +2012-04-03 13:46 szengel + + * [r20883] src/include/gnunet_regex_lib.h, src/regex/Makefile.am, + src/regex/regex.c, src/regex/regex.h, src/regex/test_regex.c: fix + +2012-04-02 11:20 wachs + + * [r20848] src/transport/plugin_transport_http.c, + src/transport/transport.conf.in: fixing 0002249: report only new + addresses + +2012-04-02 10:19 szengel + + * [r20847] src/regex/regex.c, src/regex/test_regex.c: NFA + evaluation + +2012-04-02 09:39 szengel + + * [r20845] src/include/gnunet_regex_lib.h, src/regex/regex.c, + src/regex/test_regex.c: DFA evaluation + +2012-04-01 09:13 grothoff + + * [r20826] src/core/gnunet-service-core_kx.c: implementing + rekeying, some code cleanup + +2012-04-01 07:56 grothoff + + * [r20825] doc/man/Makefile.am, doc/man/gnunet-core.1, + src/core/Makefile.am, src/core/gnunet-core-list-connections.c, + src/core/gnunet-core.c, src/include/gnunet_fs_service.h: renaming + gnunet-core-list-connections to gnunet-core, adding man page + +2012-03-30 15:43 wachs + + * [r20819] src/transport/gnunet-service-transport_neighbours.c: + +2012-03-28 19:27 szengel + + * [r20801] src/include/gnunet_regex_lib.h, src/regex/regex.c: + doxygen fix + +2012-03-28 15:49 szengel + + * [r20800] src/include/gnunet_regex_lib.h, src/regex/regex.c, + src/regex/test_regex.c: api changes + +2012-03-27 16:37 szengel + + * [r20790] src/regex/regex.c, src/regex/test_regex.c: formatting + +2012-03-24 19:13 grothoff + + * [r20751] src/fs/fs_api.c, src/fs/fs_publish.c, src/fs/fs_tree.c: + fixing issue with gnunet-publish not closing files early enough + when publishing directories with more than FD_MAX files (#2239) + +2012-03-24 09:05 harsha + + * [r20740] src/include/gnunet_stream_lib.h, + src/stream/stream_api.c: fixed compile error from r20729 + +2012-03-23 17:40 szengel + + * [r20738] src/include/gnunet_regex_lib.h, src/regex/regex.c, + src/regex/test_regex.c: towards dfa + +2012-03-23 11:15 harsha + + * [r20714] src/stream/stream_api.c: bugfix + +2012-03-23 10:58 harsha + + * [r20711] src/stream/stream_api.c, src/stream/stream_protocol.h: + fixed read packets removal after read processor, + byte ordering bugs, + ack_bitmap handling in handle_ack + ack_task cancelling in socket close + +2012-03-23 08:04 szengel + + * [r20699] src/regex/regex.c: fix + +2012-03-22 21:25 szengel + + * [r20698] src/regex/regex.c: cleanup + +2012-03-22 19:41 szengel + + * [r20697] configure.ac, pkgconfig/gnunetregex.pc, + src/include/gnunet_regex_lib.h, src/regex/Makefile.am, + src/regex/regex.c, src/regex/regex.h, src/regex/test_regex.c: + Added initial version of regex lib + +2012-03-22 18:47 grothoff + + * [r20693] configure.ac, src/Makefile.am, + src/datacache/Makefile.am, + src/datacache/plugin_datacache_postgres.c, + src/datastore/plugin_datastore_postgres.c, + src/include/Makefile.am, src/include/gnunet_mysql_lib.h, + src/include/gnunet_postgres_lib.h, src/postgres, + src/postgres/Makefile.am, src/postgres/postgres.c: adding + libgnunetpostgres for shared postgres functionality between + postgres datastore/datacache backends + +2012-03-22 11:05 wachs + + * [r20670] src/include/gnunet_namestore_service.h, + src/namestore/gnunet-service-namestore.c, + src/namestore/namestore.h, src/namestore/namestore_common.c: + +2012-03-21 12:32 harsha + + * [r20644] src/stream/stream_api.c, src/stream/test_stream_local.c: + fixed read timeout problem and added ack sending incase of + ignored data messages + +2012-03-21 09:43 grothoff + + * [r20643] src/Makefile.am, src/include/Makefile.am, src/mysql, + src/mysql/Makefile.am, src/mysql/mysql.c: creating mysql helper + library for the various mysql backends + +2012-03-21 07:06 harsha + + * [r20639] src/stream/stream_api.c, src/stream/test_stream_local.c: + fixed listen callback to happen after reaching ESTABLISHED state + +2012-03-19 14:53 grothoff + + * [r20606] configure.ac, src/core/core.conf.in, + src/dht/dht.conf.in, src/nse/nse.conf.in, + src/statistics/statistics.conf.in: add configure option + --enable-javaports to open ports of services with Java bindings + by default (#2228) + +2012-03-19 10:17 grothoff + + * [r20598] doc/man/gnunet-rsa.1, src/datastore/datastore.h, + src/exit/exit.h, src/fs/gnunet-service-fs.h, + src/include/block_dns.h, src/include/gnunet_common.h, + src/include/gnunet_crypto_lib.h, + src/include/gnunet_strings_lib.h, src/util/crypto_hash.c, + src/util/gnunet-rsa.c, src/util/strings.c, src/vpn/vpn.h: adding + API for short (256-bit) hash codes + +2012-03-16 14:47 grothoff + + * [r20570] src/gns/gnunet-gns-fcfsd.c: fix + +2012-03-15 21:24 wachs + + * [r20551] src/namestore/gnunet-namestore.c: + +2012-03-15 18:22 wachs + + * [r20548] src/namestore/gnunet-service-namestore.c: fix segfault + +2012-03-15 10:59 grothoff + + * [r20515] doc/man/gnunet-rsa.1, src/util/gnunet-rsa.c: add -P + option for printing peer identities with gnunet-rsa + +2012-03-11 22:51 grothoff + + * [r20445] src/hostlist/hostlist-server.c, + src/hostlist/hostlist.conf: vminko: implementing BINDTO option + for hostlist service (#2140) + +2012-03-10 23:17 grothoff + + * [r20431] src/include/gnunet_transport_plugin.h, + src/transport/plugin_transport_http.c, + src/transport/plugin_transport_tcp.c, + src/transport/plugin_transport_udp.c, + src/transport/plugin_transport_unix.c, + src/transport/plugin_transport_wlan.c: add support for stub-mode + for transport plugins + +2012-03-10 15:09 harsha + + * [r20424] src/stream/stream_api.c: using + GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH + +2012-03-10 09:13 harsha + + * [r20423] src/stream/stream_api.c, src/stream/test_stream_local.c: + fixed retransmission task + +2012-03-09 15:16 grothoff + + * [r20415] src/fs/fs_api.c, src/fs/fs_api.h, src/fs/fs_unindex.c: + implementing removal of KBlocks during unindex operation (#1926) + +2012-03-09 12:53 harsha + + * [r20407] src/stream/stream_api.c, src/stream/stream_protocol.h, + src/stream/test_stream_local.c: fixed byte conversion bugs + +2012-03-09 11:39 grothoff + + * [r20398] src/arm/gnunet-service-arm.c: adding code to measure and + report shutdown time for services to gnunet-service-arm at INFO + level logging + +2012-03-09 08:50 harsha + + * [r20390] src/stream/stream_api.c: corrected HELLO_ACK message + size + +2012-03-08 17:26 wachs + + * [r20375] src/namestore/gnunet-service-namestore.c, + src/namestore/hostkey, src/namestore/hostkey2, + src/namestore/namestore.conf.in, + src/namestore/test_namestore_api.c, + src/namestore/test_namestore_api.conf, + src/namestore/test_namestore_api_create.c, + src/namestore/test_namestore_api_create_update.c, + src/namestore/test_namestore_api_lookup.c, + src/namestore/test_namestore_api_lookup_specific_type.c, + src/namestore/test_namestore_api_put.c, + src/namestore/test_namestore_api_remove.c, + src/namestore/test_namestore_api_remove_not_existing_record.c, + src/namestore/test_namestore_api_sign_verify.c, + src/namestore/test_namestore_api_zone_iteration.c, + src/namestore/test_namestore_api_zone_iteration_specific_zone.c, + src/namestore/test_namestore_api_zone_iteration_stop.c, + src/namestore/test_namestore_api_zone_to_name.c, + src/namestore/zonefiles, + src/namestore/zonefiles/4UCICULTINKC87UO4326KEEDQ9MTEP2AJT88MJFVGTGNK12QNGMQI2S41VI07UUU6EO19BTB06PDL0HE6VP1OM50HOJEI75RHP4JP80.zone, + src/namestore/zonefiles/KJI3AL00K91EDPFJF58DAJM7H61D189TLP70N56JL8SVDCJE1SJ3SNNBOQPPONTL37FMHPS39SMK2NMVC0GQMGA6QCMHITT78O8GF80.zone: + namestore manages zonekey files with private keys + +2012-03-08 16:30 harsha + + * [r20373] src/stream/stream_api.c: peer interning + +2012-03-08 13:23 harsha + + * [r20365] src/stream/stream_api.c, src/stream/test_stream_local.c: + more assertions + +2012-03-08 07:45 harsha + + * [r20362] src/stream/stream_api.c, src/stream/test_stream_local.c: + Data message retransmissions + +2012-03-07 12:45 wachs + + * [r20336] src/gns/gnunet-gns-fcfsd.c, + src/gns/namestore_stub_api.c, + src/gns/test_gns_dht_delegated_lookup.c, + src/gns/test_gns_simple_delegated_lookup.c, + src/gns/test_gns_simple_lookup.c, src/gns/test_gns_twopeer.c, + src/include/gnunet_namestore_service.h, + src/namestore/gnunet-namestore.c, + src/namestore/gnunet-service-namestore.c, + src/namestore/namestore_api.c, + src/namestore/test_namestore_api.conf, + src/namestore/test_namestore_api_create.c, + src/namestore/test_namestore_api_create_update.c, + src/namestore/test_namestore_api_zone_iteration.c, + src/namestore/test_namestore_api_zone_iteration_specific_zone.c, + src/namestore/test_namestore_api_zone_iteration_stop.c: namestore + api change: include block expiration time in record create + +2012-03-07 10:11 grothoff + + * [r20329] src/namestore/namestore_common.c: implementing more of + GNUNET_NAMESTORE_value_to_string + +2012-03-06 09:50 grothoff + + * [r20302] src/namestore/namestore.h: breaking stuff + +2012-03-05 21:04 grothoff + + * [r20294] src/statistics/gnunet-service-statistics.c: fix + +2012-03-05 15:38 grothoff + + * [r20282] src/include/gnunet_gns_service.h: fix + +2012-03-04 22:55 grothoff + + * [r20258] src/fs/fs.conf.in, src/fs/fs_api.c: adding fs/ to all + default directory names relating to file sharing + +2012-03-04 22:10 grothoff + + * [r20252] src/fs/fs_api.c: fixing #1927 by further limiting the + time a download probe can be active at a time in the download + queue; this is equivalent to it having a low priority + +2012-03-04 20:59 grothoff + + * [r20246] src/statistics/gnunet-service-statistics.c, + src/statistics/statistics.h, src/statistics/statistics_api.c: + make gnunet-service-statistics not exit on external shutdown + signal as long as there are connected clients to be managed + +2012-03-04 15:02 grothoff + + * [r20241] doc/man/Makefile.am, doc/man/gnunet-gns.1, + src/gns/Makefile.am, src/gns/gnunet-gns.c: adding gnunet-gns, a + new tool for zone manipulations + +2012-03-04 14:37 grothoff + + * [r20237] doc/man/Makefile.am, doc/man/gnunet-rsa.1, + src/util/Makefile.am, src/util/gnunet-rsa.c: adding gnunet-rsa, a + new tool to create RSA keys and to print the public key + +2012-03-04 13:51 grothoff + + * [r20232] src/include/gnunet_crypto_lib.h, src/util/crypto_hash.c: + LRN: adding generic functions for conversion of binary data to + ascii and back: GNUNET_CRYPTO_string_to_data and + GNUNET_CRYPTO_data_to_string + +2012-03-02 17:29 wachs + + * [r20206] src/namestore/Makefile.am, + src/namestore/gnunet-service-namestore.c, + src/namestore/namestore.h, src/namestore/namestore_api.c, + src/namestore/test_namestore_api_put.c: + +2012-03-02 15:39 wachs + + * [r20205] src/transport/plugin_transport_tcp.c: fix for mantis + 2189 + +2012-03-01 11:58 szengel + + * [r20164] src/arm/gnunet-service-arm.c: Using GNUNET_snprintf. + +2012-03-01 08:24 grothoff + + * [r20154] src/chat/gnunet-chat.c, src/fs/fs_uri.c, + src/fs/gnunet-pseudonym.c, src/include/gnunet_pseudonym_lib.h, + src/util/pseudonym.c, src/util/test_pseudonym.c: LRN: updates to + pseudonym API from #1952, change pseudonym management + +2012-02-29 19:21 wachs + + * [r20150] src/include/gnunet_crypto_lib.h, src/util/crypto_rsa.c: + serialize privat key + +2012-02-29 12:50 grothoff + + * [r20143] src/include/gnunet_common.h, + src/include/gnunet_dnsparser_lib.h, src/include/gnunet_tun_lib.h: + LRN: Enforce GCC bitfield layout for some structs on W32 + +2012-02-29 11:11 wachs + + * [r20142] src/include/gnunet_namestore_plugin.h, + src/include/gnunet_namestore_service.h, + src/namestore/gnunet-service-namestore.c, + src/namestore/namestore_api.c, + src/namestore/plugin_namestore_sqlite.c, + src/namestore/test_namestore_api_lookup.c: nametore api change + +2012-02-29 08:59 szengel + + * [r20135] src/arm/arm.h, src/arm/arm_api.c, src/arm/gnunet-arm.c, + src/arm/gnunet-service-arm.c, src/include/gnunet_arm_service.h, + src/include/gnunet_protocols.h: Adding arm list/info feature. + +2012-02-28 19:08 grothoff + + * [r20127] src/include/gnunet_crypto_lib.h, src/util/crypto_rsa.c, + src/vpn/test_gnunet_vpn.c: adding GNUNET_CRYPTO_setup_hostkey to + setup a hostkey ahead of time, using this function in the VPN + testcases to avoid timeouts in cases where creating a hostkey + just takes too long --- such as on our UltraSprac + 2012-02-28 17:29 grothoff * [r20121] src/util/os_priority.c: LRN: Apparently cleanup is not diff --git a/Makefile.in b/Makefile.in index b1af2c5..015c1d7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -202,6 +202,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -235,6 +236,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/README b/README index b2b7233..7a3d4cf 100644 --- a/README +++ b/README @@ -100,17 +100,21 @@ certain binaries that require additional priviledges will not be installed properly (and autonomous NAT traversal, WLAN, DNS/GNS and the VPN will then not work). -Note that additional, per-user configuration files -(~/.gnunet/gnunet.conf) need to be created by each user (for example, -by running gnunet-setup). Note that gnunet-setup is a separate -download and requires recent versions of GTK+ and Glade; you can also -edit the configuration file by hand, but this is not recommended. For -more general information about the GNU build process read the INSTALL -file. - -If you are compiling the code from subversion, you have to run -". bootstrap" before ./configure. If you receive an error during the -running of ". bootstrap" that looks like "macro `AM_PATH_GTK' not +If you run 'configure' and 'make install' as root or use the SUDO +option, GNUnet's build system will install "libnss_gns*" libraries to +"/lib/" regardless (!) of the $GNUNET_PREFIX you might have specified, +as those libraries must be in "/lib/". If you are packaging GNUnet +for binary distribution, this may cause your packaging script to miss +those plugins, so you might need to do some additional manual work to +include those libraries in your binary package(s). Similarly, if you +want to use the GNUnet naming system and did NOT run GNUnet's 'make +install' process with SUDO rights, the libraries will be installed to +"$GNUNET_PREFIX/lib" and you will have to move them to "/lib/" +manually. + +Finally, if you are compiling the code from subversion, you have to +run ". bootstrap" before ./configure. If you receive an error during +the running of ". bootstrap" that looks like "macro `AM_PATH_GTK' not found in library", you may need to run aclocal by hand with the -I option, pointing to your aclocal m4 macros, i.e. @@ -120,6 +124,14 @@ $ aclocal -I /usr/local/share/aclocal Configuration ============= +Note that additional, per-user configuration files +(~/.gnunet/gnunet.conf) need to be created by each user (for example, +by running gnunet-setup). Note that gnunet-setup is a separate +download and requires recent versions of GTK+ and Glade; you can also +edit the configuration file by hand, but this is not recommended. For +more general information about the GNU build process read the INSTALL +file. + GNUnet uses two types of configuration files, one that specifies the system-wide defaults (typically located in $GNUNET_PREFIX/share/gnunet/config.d/) and a second one that overrides @@ -221,18 +233,18 @@ Running http on port 80 and https on port 443 In order to hide GNUnet's HTTP/HTTPS traffic perfectly, you might consider running GNUnet's HTTP/HTTPS transport on port 80/443. However, we do not recommend running GNUnet as root. Instead, forward -port 80 to say 8080 with this command (as root, in your startup +port 80 to say 1080 with this command (as root, in your startup scripts): -# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 +# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 1080 or for HTTPS # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 4433 -Then set in the HTTP section of gnunet.conf the "ADVERTISED-PORT" to -"80" and "PORT" to 8080 and similarly in the HTTPS section the -"ADVERTISED-PORT" to "443" and "PORT" to 4433. +Then set in the HTTP section of gnunet.conf the "ADVERTISED_PORT" to +"80" and "PORT" to 1080 and similarly in the HTTPS section the +"ADVERTISED_PORT" to "443" and "PORT" to 4433. You can do the same trick for the TCP and UDP transports if you want to map them to a priviledged port (from the point of view of the diff --git a/configure b/configure index 102c357..b625925 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for gnunet 0.9.2. +# Generated by GNU Autoconf 2.67 for gnunet 0.9.3. # # Report bugs to . # @@ -705,8 +705,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='gnunet' PACKAGE_TARNAME='gnunet' -PACKAGE_VERSION='0.9.2' -PACKAGE_STRING='gnunet 0.9.2' +PACKAGE_VERSION='0.9.3' +PACKAGE_STRING='gnunet 0.9.3' PACKAGE_BUGREPORT='bug-gnunet@gnu.org' PACKAGE_URL='' @@ -759,11 +759,17 @@ HAVE_EXPERIMENTAL_FALSE HAVE_EXPERIMENTAL_TRUE HAVE_BENCHMARKS_FALSE HAVE_BENCHMARKS_TRUE +JAVAPORT HAVE_EXPENSIVE_TESTS_FALSE HAVE_EXPENSIVE_TESTS_TRUE +MONKEYPREFIX +ENABLE_MONKEY_FALSE +ENABLE_MONKEY_TRUE ENABLE_TEST_RUN_FALSE ENABLE_TEST_RUN_TRUE GNUNETDNS_GROUP +HAVE_SUDO_FALSE +HAVE_SUDO_TRUE SUDO_BINARY DLLDIR LIBPREFIX @@ -828,6 +834,8 @@ LIBUNISTRING HAVE_LIBUNISTRING LTLIBICONV LIBICONV +HAVE_GLIBCNSS_FALSE +HAVE_GLIBCNSS_TRUE HAVE_LIBGLPK_FALSE HAVE_LIBGLPK_TRUE LIBCURL @@ -1043,7 +1051,9 @@ enable_framework with_sudo with_gnunetdns enable_testruns +enable_monkey enable_expensivetests +enable_javaports enable_benchmarks enable_experimental enable_windows_workarounds @@ -1607,7 +1617,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures gnunet 0.9.2 to adapt to many kinds of systems. +\`configure' configures gnunet 0.9.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1682,7 +1692,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of gnunet 0.9.2:";; + short | recursive ) echo "Configuration of gnunet 0.9.3:";; esac cat <<\_ACEOF @@ -1712,8 +1722,10 @@ Optional Features: --disable-nls do not use Native Language Support --enable-framework enable Mac OS X framework build helpers --disable-testruns disable running tests on make check (default is YES) - --enable-expensive-tests - enable running expensive testcases + --enable-monkey enable running with monkey + --enable-expensivetests enable running expensive testcases + --enable-javaports use non-zero ports for services with Java bindings + (default is NO) --enable-benchmarks enable running benchmarks during make check --enable-experimental enable compiling experimental code --enable-windows_workarounds @@ -1838,7 +1850,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -gnunet configure 0.9.2 +gnunet configure 0.9.3 generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2701,7 +2713,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by gnunet $as_me 0.9.2, which was +It was created by gnunet $as_me 0.9.3, which was generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -3631,7 +3643,7 @@ fi # Define the identity of the package. PACKAGE=gnunet - VERSION=0.9.2 + VERSION=0.9.3 cat >>confdefs.h <<_ACEOF @@ -6383,13 +6395,13 @@ if test "${lt_cv_nm_interface+set}" = set; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:6386: $ac_compile\"" >&5) + (eval echo "\"\$as_me:6398: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:6389: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:6401: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:6392: output\"" >&5) + (eval echo "\"\$as_me:6404: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -7581,7 +7593,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 7584 "configure"' > conftest.$ac_ext + echo '#line 7596 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -9796,11 +9808,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9799: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9811: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9803: \$? = $ac_status" >&5 + echo "$as_me:9815: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -10135,11 +10147,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10138: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10150: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:10142: \$? = $ac_status" >&5 + echo "$as_me:10154: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -10240,11 +10252,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10243: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10255: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10247: \$? = $ac_status" >&5 + echo "$as_me:10259: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10295,11 +10307,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10298: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10310: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10302: \$? = $ac_status" >&5 + echo "$as_me:10314: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -12679,7 +12691,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12682 "configure" +#line 12694 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12775,7 +12787,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12778 "configure" +#line 12790 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14731,11 +14743,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14734: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14746: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14738: \$? = $ac_status" >&5 + echo "$as_me:14750: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14830,11 +14842,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14833: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14845: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14837: \$? = $ac_status" >&5 + echo "$as_me:14849: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14882,11 +14894,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14885: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14897: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14889: \$? = $ac_status" >&5 + echo "$as_me:14901: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16294,7 +16306,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 16297 "configure" +#line 16309 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17191,6 +17203,8 @@ fi # Use Linux interface name unless the OS has a different preference DEFAULT_INTERFACE="\"eth0\"" +funcstocheck="socket select inet_ntoa getnameinfo gethostname gethostbyname gethostbyaddr getaddrinfo" + # Check system type case "$host_os" in *darwin* | *rhapsody* | *macosx*) @@ -18581,7 +18595,7 @@ fi LDFLAGS="$LDFLAGS -Wl,-no-undefined -Wl,--export-all-symbols" LIBS="$LIBS -lws2_32 -lplibc -lgnurx -lole32" CFLAGS="-mms-bitfields $CFLAGS" - CPPFLAGS="-D_WIN32_WINNT=0x0501 $CPPFLAGS" + CPPFLAGS="-D_WIN32_WINNT=0x0501 -DHAVE_STAT64=1 $CPPFLAGS" build_target="mingw" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' @@ -18970,6 +18984,7 @@ fi LIBPREFIX=lib DLLDIR=bin UNIXONLY="" + funcstocheck="" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: Unrecognised OS $host_os" >&5 @@ -18993,6 +19008,7 @@ _ACEOF # sockets in default configuratin: + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build target" >&5 $as_echo_n "checking for build target... " >&6; } if test "$build_target" = "darwin"; then @@ -20160,6 +20176,46 @@ $as_echo "#define HAVE_LIBGLPK 1" >>confdefs.h fi + +for ac_header in nss.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "nss.h" "ac_cv_header_nss_h" "$ac_includes_default" +if test "x$ac_cv_header_nss_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NSS_H 1 +_ACEOF + nss=true +else + nss=false +fi + +done + +if test x$nss = xfalse +then + if false; then + HAVE_GLIBCNSS_TRUE= + HAVE_GLIBCNSS_FALSE='#' +else + HAVE_GLIBCNSS_TRUE='#' + HAVE_GLIBCNSS_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No GNU libc nss header, will not build NSS plugin" >&5 +$as_echo "$as_me: WARNING: No GNU libc nss header, will not build NSS plugin" >&2;} +else + if true; then + HAVE_GLIBCNSS_TRUE= + HAVE_GLIBCNSS_FALSE='#' +else + HAVE_GLIBCNSS_TRUE='#' + HAVE_GLIBCNSS_FALSE= +fi + +fi + + + # test for kvm and kstat (for CPU stats under BSD/Solaris) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for kvm_open in -lkvm" >&5 $as_echo_n "checking for kvm_open in -lkvm... " >&6; } @@ -23523,13 +23579,13 @@ $as_echo "$with_microhttpd" >&6; } yes) for ac_header in microhttpd.h do : - ac_fn_c_check_header_compile "$LINENO" "microhttpd.h" "ac_cv_header_microhttpd_h" "#include \"src/include/platform.h\" + ac_fn_c_check_header_compile "$LINENO" "microhttpd.h" "ac_cv_header_microhttpd_h" "#include \"$srcdir/src/include/platform.h\" " if test "x$ac_cv_header_microhttpd_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MICROHTTPD_H 1 _ACEOF - ac_fn_c_check_decl "$LINENO" "MHD_OPTION_PER_IP_CONNECTION_LIMIT" "ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" "#include \"src/include/platform.h\" + ac_fn_c_check_decl "$LINENO" "MHD_OPTION_PER_IP_CONNECTION_LIMIT" "ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" "#include \"$srcdir/src/include/platform.h\" #include " if test "x$ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" = x""yes; then : @@ -23570,7 +23626,32 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_microhttpd_MHD_start_daemon" >&5 $as_echo "$ac_cv_lib_microhttpd_MHD_start_daemon" >&6; } if test "x$ac_cv_lib_microhttpd_MHD_start_daemon" = x""yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmicrohttpd >= 0.9.18" >&5 +$as_echo_n "checking for libmicrohttpd >= 0.9.18... " >&6; } + if test "$cross_compiling" = yes; then : lmhd=1 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include "$srcdir/src/include/platform.h" + #include + int main () { return MHD_VERSION >= 0x0091200 ? 0 : 1; } + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + lmhd=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + fi fi @@ -23585,13 +23666,13 @@ done CPPFLAGS="-I$with_microhttpd/include $CPPFLAGS" for ac_header in microhttpd.h do : - ac_fn_c_check_header_compile "$LINENO" "microhttpd.h" "ac_cv_header_microhttpd_h" "#include \"src/include/platform.h\" + ac_fn_c_check_header_compile "$LINENO" "microhttpd.h" "ac_cv_header_microhttpd_h" "#include \"$srcdir/src/include/platform.h\" " if test "x$ac_cv_header_microhttpd_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MICROHTTPD_H 1 _ACEOF - ac_fn_c_check_decl "$LINENO" "MHD_OPTION_PER_IP_CONNECTION_LIMIT" "ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" "#include \"src/include/platform.h\" + ac_fn_c_check_decl "$LINENO" "MHD_OPTION_PER_IP_CONNECTION_LIMIT" "ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" "#include \"$srcdir/src/include/platform.h\" #include " if test "x$ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" = x""yes; then : @@ -23633,7 +23714,32 @@ fi $as_echo "$ac_cv_lib_microhttpd_MHD_start_daemon" >&6; } if test "x$ac_cv_lib_microhttpd_MHD_start_daemon" = x""yes; then : EXT_LIB_PATH="-L$with_microhttpd/lib $EXT_LIB_PATH" - lmhd=1 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmicrohttpd >= 0.9.18" >&5 +$as_echo_n "checking for libmicrohttpd >= 0.9.18... " >&6; } + if test "$cross_compiling" = yes; then : + lmhd=1 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include "$srcdir/src/include/platform.h" + #include + int main () { return MHD_VERSION >= 0x0091200 ? 0 : 1; } + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + lmhd=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + fi fi @@ -23650,13 +23756,13 @@ else $as_echo "--with-microhttpd not specified" >&6; } for ac_header in microhttpd.h do : - ac_fn_c_check_header_compile "$LINENO" "microhttpd.h" "ac_cv_header_microhttpd_h" "#include \"src/include/platform.h\" + ac_fn_c_check_header_compile "$LINENO" "microhttpd.h" "ac_cv_header_microhttpd_h" "#include \"$srcdir/src/include/platform.h\" " if test "x$ac_cv_header_microhttpd_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MICROHTTPD_H 1 _ACEOF - ac_fn_c_check_decl "$LINENO" "MHD_OPTION_PER_IP_CONNECTION_LIMIT" "ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" "#include \"src/include/platform.h\" + ac_fn_c_check_decl "$LINENO" "MHD_OPTION_PER_IP_CONNECTION_LIMIT" "ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" "#include \"$srcdir/src/include/platform.h\" #include " if test "x$ac_cv_have_decl_MHD_OPTION_PER_IP_CONNECTION_LIMIT" = x""yes; then : @@ -23697,7 +23803,32 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_microhttpd_MHD_start_daemon" >&5 $as_echo "$ac_cv_lib_microhttpd_MHD_start_daemon" >&6; } if test "x$ac_cv_lib_microhttpd_MHD_start_daemon" = x""yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmicrohttpd >= 0.9.18" >&5 +$as_echo_n "checking for libmicrohttpd >= 0.9.18... " >&6; } + if test "$cross_compiling" = yes; then : lmhd=1 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include "$srcdir/src/include/platform.h" + #include + int main () { return MHD_VERSION >= 0x0091200 ? 0 : 1; } + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + lmhd=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + fi fi @@ -26392,7 +26523,7 @@ $as_echo "#define gid_t int" >>confdefs.h fi -for ac_func in floor gethostname memmove rmdir strncasecmp strrchr strtol atoll dup2 fdatasync ftruncate gettimeofday memset mkdir mkfifo select socket strcasecmp strchr strdup strerror strstr clock_gettime getrusage rand uname setlocale getcwd mktime gmtime_r gmtime strlcpy strlcat ftruncate stat64 sbrk mmap mremap setrlimit sysconf gethostbyaddr initgroups getifaddrs freeifaddrs getnameinfo getaddrinfo inet_ntoa localtime_r nl_langinfo putenv realpath strndup gethostbyname2 gethostbyname getpeerucred getpeereid setresuid +for ac_func in floor memmove rmdir strncasecmp strrchr strtol atoll dup2 fdatasync ftruncate gettimeofday memset mkdir mkfifo strcasecmp strchr strdup strerror strstr clock_gettime getrusage rand uname setlocale getcwd mktime gmtime_r gmtime strlcpy strlcat ftruncate stat64 sbrk mmap mremap setrlimit sysconf initgroups getifaddrs freeifaddrs localtime_r nl_langinfo putenv realpath strndup gethostbyname2 gethostbyname getpeerucred getpeereid setresuid $funcstocheck do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -26528,6 +26659,13 @@ $as_echo "no" >&6; } fi + if test "x$SUDO_BINARY" != "x" -o -w /; then + HAVE_SUDO_TRUE= + HAVE_SUDO_FALSE='#' +else + HAVE_SUDO_TRUE='#' + HAVE_SUDO_FALSE= +fi # test for gnunetdns group name @@ -26580,6 +26718,36 @@ else fi + +# should monkey be used when running (certain) services? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to run with monkey" >&5 +$as_echo_n "checking whether to run with monkey... " >&6; } +# Check whether --enable-monkey was given. +if test "${enable_monkey+set}" = set; then : + enableval=$enable_monkey; enable_monkey=${enableval} +else + enable_monkey=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_monkey" >&5 +$as_echo "$enable_monkey" >&6; } + if test "x$enable_monkey" = "xyes"; then + ENABLE_MONKEY_TRUE= + ENABLE_MONKEY_FALSE='#' +else + ENABLE_MONKEY_TRUE='#' + ENABLE_MONKEY_FALSE= +fi + +if test "x$enable_monkey" = "xyes" +then + MONKEYPREFIX="monkey" +else + MONKEYPREFIX="" +fi + + + # should expensive tests be run? { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to run expensive tests" >&5 $as_echo_n "checking whether to run expensive tests... " >&6; } @@ -26601,6 +26769,26 @@ else fi +# should ports be open for Java services? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable ports for gnunet-java" >&5 +$as_echo_n "checking whether to enable ports for gnunet-java... " >&6; } +# Check whether --enable-javaports was given. +if test "${enable_javaports+set}" = set; then : + enableval=$enable_javaports; enable_java_ports=${enableval} +else + enable_java_ports=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_java_ports" >&5 +$as_echo "$enable_java_ports" >&6; } +if test "x$enable_java_ports" = "xyes" +then + JAVAPORT="" +else + JAVAPORT="$UNIXONLY" +fi + + # should benchmarks be run? { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to run benchmarks during make check" >&5 $as_echo_n "checking whether to run benchmarks during make check... " >&6; } @@ -26648,6 +26836,280 @@ fi if test $build_target = "mingw" then workarounds=1 + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + + int s = socket (0, 0, 0); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +cat >>confdefs.h <<_ACEOF +#define HAVE_SOCKET 1 +_ACEOF + + +else + + +cat >>confdefs.h <<_ACEOF +#define HAVE_SOCKET 0 +_ACEOF + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + + int s = select (0, NULL, NULL, NULL, NULL); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +cat >>confdefs.h <<_ACEOF +#define HAVE_SELECT 1 +_ACEOF + + +else + + +cat >>confdefs.h <<_ACEOF +#define HAVE_SELECT 0 +_ACEOF + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + + struct in_addr i; + char *s = inet_ntoa (i); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +cat >>confdefs.h <<_ACEOF +#define HAVE_INET_NTOA 1 +_ACEOF + + +else + + +cat >>confdefs.h <<_ACEOF +#define HAVE_INET_NTOA 0 +_ACEOF + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + + int s = getnameinfo (NULL, 0, NULL, 0, NULL, 0, 0); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETNAMEINFO 1 +_ACEOF + + +else + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETNAMEINFO 0 +_ACEOF + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + + int s = gethostname (NULL, 0); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETHOSTNAME 1 +_ACEOF + + +else + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETHOSTNAME 0 +_ACEOF + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + + void *s = gethostbyname (NULL); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETHOSTBYNAME 1 +_ACEOF + + +else + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETHOSTBYNAME 0 +_ACEOF + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + + void *s = gethostbyaddr (NULL, 0, 0); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETHOSTBYADDR 1 +_ACEOF + + +else + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETHOSTBYADDR 0 +_ACEOF + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + + int s = getaddrinfo (NULL, NULL, NULL, NULL); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETADDRINFO 1 +_ACEOF + + +else + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GETADDRINFO 1 +_ACEOF + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable windows workarounds" >&5 $as_echo_n "checking whether to enable windows workarounds... " >&6; } @@ -26695,7 +27157,7 @@ fi -ac_config_files="$ac_config_files Makefile contrib/Makefile doc/Makefile doc/man/Makefile m4/Makefile po/Makefile.in src/Makefile src/arm/Makefile src/arm/arm.conf src/ats/Makefile src/ats/ats.conf src/block/Makefile src/chat/Makefile src/chat/chat.conf src/core/Makefile src/core/core.conf src/datacache/Makefile src/datastore/Makefile src/datastore/datastore.conf src/dht/Makefile src/dht/dht.conf src/dns/Makefile src/dns/dns.conf src/dv/Makefile src/dv/dv.conf src/exit/Makefile src/fragmentation/Makefile src/fs/Makefile src/fs/fs.conf src/gns/Makefile src/gns/gns.conf src/hello/Makefile src/include/Makefile src/include/gnunet_directories.h src/hostlist/Makefile src/mesh/Makefile src/mesh/mesh.conf src/namestore/Makefile src/namestore/namestore.conf src/nat/Makefile src/nse/Makefile src/nse/nse.conf src/peerinfo/Makefile src/peerinfo/peerinfo.conf src/peerinfo-tool/Makefile src/pt/Makefile src/statistics/Makefile src/statistics/statistics.conf src/stream/Makefile src/template/Makefile src/testing/Makefile src/topology/Makefile src/transport/Makefile src/transport/transport.conf src/tun/Makefile src/util/Makefile src/util/resolver.conf src/vpn/Makefile src/vpn/vpn.conf src/integration-tests/Makefile pkgconfig/Makefile pkgconfig/gnunetarm.pc pkgconfig/gnunetblock.pc pkgconfig/gnunetcore.pc pkgconfig/gnunetdatacache.pc pkgconfig/gnunetdatastore.pc pkgconfig/gnunetdht.pc pkgconfig/gnunetdhtlog.pc pkgconfig/gnunetdv.pc pkgconfig/gnunetfragmentation.pc pkgconfig/gnunetfs.pc pkgconfig/gnunethello.pc pkgconfig/gnunetnat.pc pkgconfig/gnunetnse.pc pkgconfig/gnunetpeerinfo.pc pkgconfig/gnunetstatistics.pc pkgconfig/gnunettesting.pc pkgconfig/gnunettransport.pc pkgconfig/gnunetutil.pc" +ac_config_files="$ac_config_files Makefile contrib/Makefile doc/Makefile doc/man/Makefile m4/Makefile po/Makefile.in src/Makefile src/arm/Makefile src/arm/arm.conf src/ats/Makefile src/ats/ats.conf src/block/Makefile src/chat/Makefile src/chat/chat.conf src/core/Makefile src/core/core.conf src/datacache/Makefile src/datastore/Makefile src/datastore/datastore.conf src/dht/Makefile src/dht/dht.conf src/dns/Makefile src/dns/dns.conf src/dv/Makefile src/dv/dv.conf src/exit/Makefile src/fragmentation/Makefile src/fs/Makefile src/fs/fs.conf src/gns/Makefile src/gns/gns.conf src/gns/nss/Makefile src/hello/Makefile src/include/Makefile src/include/gnunet_directories.h src/hostlist/Makefile src/lockmanager/Makefile src/lockmanager/lockmanager.conf src/mesh/Makefile src/mesh/mesh.conf src/mysql/Makefile src/namestore/Makefile src/namestore/namestore.conf src/nat/Makefile src/nse/Makefile src/nse/nse.conf src/peerinfo/Makefile src/peerinfo/peerinfo.conf src/peerinfo-tool/Makefile src/postgres/Makefile src/pt/Makefile src/regex/Makefile src/statistics/Makefile src/statistics/statistics.conf src/stream/Makefile src/template/Makefile src/testbed/Makefile src/testing/Makefile src/topology/Makefile src/transport/Makefile src/transport/transport.conf src/tun/Makefile src/util/Makefile src/util/resolver.conf src/vpn/Makefile src/vpn/vpn.conf src/integration-tests/Makefile pkgconfig/Makefile pkgconfig/gnunetarm.pc pkgconfig/gnunetblock.pc pkgconfig/gnunetcore.pc pkgconfig/gnunetdatacache.pc pkgconfig/gnunetdatastore.pc pkgconfig/gnunetdht.pc pkgconfig/gnunetdhtlog.pc pkgconfig/gnunetdv.pc pkgconfig/gnunetfragmentation.pc pkgconfig/gnunetfs.pc pkgconfig/gnunethello.pc pkgconfig/gnunetnat.pc pkgconfig/gnunetnse.pc pkgconfig/gnunetpeerinfo.pc pkgconfig/gnunetregex.pc pkgconfig/gnunetstatistics.pc pkgconfig/gnunettesting.pc pkgconfig/gnunettransport.pc pkgconfig/gnunetutil.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -26896,6 +27358,14 @@ if test -z "${HAVE_LIBGLPK_TRUE}" && test -z "${HAVE_LIBGLPK_FALSE}"; then as_fn_error $? "conditional \"HAVE_LIBGLPK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_GLIBCNSS_TRUE}" && test -z "${HAVE_GLIBCNSS_FALSE}"; then + as_fn_error $? "conditional \"HAVE_GLIBCNSS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_GLIBCNSS_TRUE}" && test -z "${HAVE_GLIBCNSS_FALSE}"; then + as_fn_error $? "conditional \"HAVE_GLIBCNSS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${HAVE_SQLITE_TRUE}" && test -z "${HAVE_SQLITE_FALSE}"; then as_fn_error $? "conditional \"HAVE_SQLITE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -26936,10 +27406,18 @@ if test -z "${WANT_FRAMEWORK_TRUE}" && test -z "${WANT_FRAMEWORK_FALSE}"; then as_fn_error $? "conditional \"WANT_FRAMEWORK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_SUDO_TRUE}" && test -z "${HAVE_SUDO_FALSE}"; then + as_fn_error $? "conditional \"HAVE_SUDO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ENABLE_TEST_RUN_TRUE}" && test -z "${ENABLE_TEST_RUN_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TEST_RUN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${ENABLE_MONKEY_TRUE}" && test -z "${ENABLE_MONKEY_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_MONKEY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${HAVE_EXPENSIVE_TESTS_TRUE}" && test -z "${HAVE_EXPENSIVE_TESTS_FALSE}"; then as_fn_error $? "conditional \"HAVE_EXPENSIVE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -27364,7 +27842,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by gnunet $as_me 0.9.2, which was +This file was extended by gnunet $as_me 0.9.3, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -27430,7 +27908,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -gnunet config.status 0.9.2 +gnunet config.status 0.9.3 configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" @@ -27953,12 +28431,16 @@ do "src/fs/fs.conf") CONFIG_FILES="$CONFIG_FILES src/fs/fs.conf" ;; "src/gns/Makefile") CONFIG_FILES="$CONFIG_FILES src/gns/Makefile" ;; "src/gns/gns.conf") CONFIG_FILES="$CONFIG_FILES src/gns/gns.conf" ;; + "src/gns/nss/Makefile") CONFIG_FILES="$CONFIG_FILES src/gns/nss/Makefile" ;; "src/hello/Makefile") CONFIG_FILES="$CONFIG_FILES src/hello/Makefile" ;; "src/include/Makefile") CONFIG_FILES="$CONFIG_FILES src/include/Makefile" ;; "src/include/gnunet_directories.h") CONFIG_FILES="$CONFIG_FILES src/include/gnunet_directories.h" ;; "src/hostlist/Makefile") CONFIG_FILES="$CONFIG_FILES src/hostlist/Makefile" ;; + "src/lockmanager/Makefile") CONFIG_FILES="$CONFIG_FILES src/lockmanager/Makefile" ;; + "src/lockmanager/lockmanager.conf") CONFIG_FILES="$CONFIG_FILES src/lockmanager/lockmanager.conf" ;; "src/mesh/Makefile") CONFIG_FILES="$CONFIG_FILES src/mesh/Makefile" ;; "src/mesh/mesh.conf") CONFIG_FILES="$CONFIG_FILES src/mesh/mesh.conf" ;; + "src/mysql/Makefile") CONFIG_FILES="$CONFIG_FILES src/mysql/Makefile" ;; "src/namestore/Makefile") CONFIG_FILES="$CONFIG_FILES src/namestore/Makefile" ;; "src/namestore/namestore.conf") CONFIG_FILES="$CONFIG_FILES src/namestore/namestore.conf" ;; "src/nat/Makefile") CONFIG_FILES="$CONFIG_FILES src/nat/Makefile" ;; @@ -27967,11 +28449,14 @@ do "src/peerinfo/Makefile") CONFIG_FILES="$CONFIG_FILES src/peerinfo/Makefile" ;; "src/peerinfo/peerinfo.conf") CONFIG_FILES="$CONFIG_FILES src/peerinfo/peerinfo.conf" ;; "src/peerinfo-tool/Makefile") CONFIG_FILES="$CONFIG_FILES src/peerinfo-tool/Makefile" ;; + "src/postgres/Makefile") CONFIG_FILES="$CONFIG_FILES src/postgres/Makefile" ;; "src/pt/Makefile") CONFIG_FILES="$CONFIG_FILES src/pt/Makefile" ;; + "src/regex/Makefile") CONFIG_FILES="$CONFIG_FILES src/regex/Makefile" ;; "src/statistics/Makefile") CONFIG_FILES="$CONFIG_FILES src/statistics/Makefile" ;; "src/statistics/statistics.conf") CONFIG_FILES="$CONFIG_FILES src/statistics/statistics.conf" ;; "src/stream/Makefile") CONFIG_FILES="$CONFIG_FILES src/stream/Makefile" ;; "src/template/Makefile") CONFIG_FILES="$CONFIG_FILES src/template/Makefile" ;; + "src/testbed/Makefile") CONFIG_FILES="$CONFIG_FILES src/testbed/Makefile" ;; "src/testing/Makefile") CONFIG_FILES="$CONFIG_FILES src/testing/Makefile" ;; "src/topology/Makefile") CONFIG_FILES="$CONFIG_FILES src/topology/Makefile" ;; "src/transport/Makefile") CONFIG_FILES="$CONFIG_FILES src/transport/Makefile" ;; @@ -27997,6 +28482,7 @@ do "pkgconfig/gnunetnat.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/gnunetnat.pc" ;; "pkgconfig/gnunetnse.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/gnunetnse.pc" ;; "pkgconfig/gnunetpeerinfo.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/gnunetpeerinfo.pc" ;; + "pkgconfig/gnunetregex.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/gnunetregex.pc" ;; "pkgconfig/gnunetstatistics.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/gnunetstatistics.pc" ;; "pkgconfig/gnunettesting.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/gnunettesting.pc" ;; "pkgconfig/gnunettransport.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/gnunettransport.pc" ;; @@ -29809,6 +30295,13 @@ then $as_echo "$as_me: NOTICE: sqlite not found. sqLite support will not be compiled." >&6;} fi +# java ports +if test "x$enable_java_ports" = "xyes" +then + { $as_echo "$as_me:${as_lineno-$LINENO}: NOTICE: opening ports for gnunet-java bindings by default." >&5 +$as_echo "$as_me: NOTICE: opening ports for gnunet-java bindings by default." >&6;} +fi + if test "x$lmhd" != "x1" then { $as_echo "$as_me:${as_lineno-$LINENO}: NOTICE: libmicrohttpd not found, http transport will not be installed." >&5 @@ -29824,6 +30317,12 @@ then $as_echo "$as_me: NOTICE: Mac OS X framework build enabled." >&6;} fi +if test "x$SUDO_BINARY" = "x" -a ! -w / +then + { $as_echo "$as_me:${as_lineno-$LINENO}: NOTICE: --with-sudo not specified and not running as 'root', will not install GNS NSS library" >&5 +$as_echo "$as_me: NOTICE: --with-sudo not specified and not running as 'root', will not install GNS NSS library" >&6;} +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: ******************************************** You can compile GNUnet with make diff --git a/configure.ac b/configure.ac index a558ffd..2a8d612 100644 --- a/configure.ac +++ b/configure.ac @@ -22,13 +22,13 @@ # AC_PREREQ(2.61) # Checks for programs. -AC_INIT([gnunet], [0.9.2],[bug-gnunet@gnu.org]) +AC_INIT([gnunet], [0.9.3],[bug-gnunet@gnu.org]) AC_CANONICAL_TARGET AC_CANONICAL_HOST AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE([gnunet], [0.9.2]) +AM_INIT_AUTOMAKE([gnunet], [0.9.3]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS([gnunet_config.h]) AH_TOP([#define _GNU_SOURCE 1]) @@ -68,6 +68,8 @@ fi # Use Linux interface name unless the OS has a different preference DEFAULT_INTERFACE="\"eth0\"" +funcstocheck="socket select inet_ntoa getnameinfo gethostname gethostbyname gethostbyaddr getaddrinfo" + # Check system type case "$host_os" in *darwin* | *rhapsody* | *macosx*) @@ -152,12 +154,13 @@ netbsd*) LDFLAGS="$LDFLAGS -Wl,-no-undefined -Wl,--export-all-symbols" LIBS="$LIBS -lws2_32 -lplibc -lgnurx -lole32" CFLAGS="-mms-bitfields $CFLAGS" - CPPFLAGS="-D_WIN32_WINNT=0x0501 $CPPFLAGS" + CPPFLAGS="-D_WIN32_WINNT=0x0501 -DHAVE_STAT64=1 $CPPFLAGS" build_target="mingw" AC_PROG_CXX LIBPREFIX=lib DLLDIR=bin UNIXONLY="" + funcstocheck="" ;; *) AC_MSG_RESULT(Unrecognised OS $host_os) @@ -172,6 +175,7 @@ AC_SUBST(DEFAULT_INTERFACE) # sockets in default configuratin: AC_SUBST(UNIXONLY) + AC_MSG_CHECKING([for build target]) AM_CONDITIONAL(DARWIN, test "$build_target" = "darwin") AM_CONDITIONAL(CYGWIN, test "$build_target" = "cygwin") @@ -335,6 +339,18 @@ else fi + +AC_CHECK_HEADERS([nss.h],[nss=true],[nss=false]) +if test x$nss = xfalse +then + AM_CONDITIONAL(HAVE_GLIBCNSS, false) + AC_MSG_WARN([No GNU libc nss header, will not build NSS plugin]) +else + AM_CONDITIONAL(HAVE_GLIBCNSS, true) +fi + + + # test for kvm and kstat (for CPU stats under BSD/Solaris) AC_CHECK_LIB([kvm],[kvm_open]) AC_CHECK_LIB([kstat],[kstat_open]) @@ -566,10 +582,17 @@ AC_ARG_WITH(microhttpd, AC_CHECK_HEADERS([microhttpd.h], AC_CHECK_DECL(MHD_OPTION_PER_IP_CONNECTION_LIMIT, AC_CHECK_LIB([microhttpd], [MHD_start_daemon], - lmhd=1), - [],[#include "src/include/platform.h" + [AC_MSG_CHECKING([for libmicrohttpd >= 0.9.18]) + AC_RUN_IFELSE([ + #include "$srcdir/src/include/platform.h" + #include + int main () { return MHD_VERSION >= 0x0091200 ? 0 : 1; } + ], [ + AC_MSG_RESULT(ok) + lmhd=1],[AC_MSG_RESULT(failed)],lmhd=1)]), + [],[#include "$srcdir/src/include/platform.h" #include ]),, - [#include "src/include/platform.h"]) + [#include "$srcdir/src/include/platform.h"]) ;; *) LDFLAGS="-L$with_microhttpd/lib $LDFLAGS" @@ -578,10 +601,17 @@ AC_ARG_WITH(microhttpd, AC_CHECK_DECL(MHD_OPTION_PER_IP_CONNECTION_LIMIT, AC_CHECK_LIB([microhttpd], [MHD_start_daemon], EXT_LIB_PATH="-L$with_microhttpd/lib $EXT_LIB_PATH" - lmhd=1), - [],[#include "src/include/platform.h" + [AC_MSG_CHECKING([for libmicrohttpd >= 0.9.18]) + AC_RUN_IFELSE([ + #include "$srcdir/src/include/platform.h" + #include + int main () { return MHD_VERSION >= 0x0091200 ? 0 : 1; } + ], [ + AC_MSG_RESULT(ok) + lmhd=1],[AC_MSG_RESULT(failed)],lmhd=1)]), + [],[#include "$srcdir/src/include/platform.h" #include ]),, - [#include "src/include/platform.h"]) + [#include "$srcdir/src/include/platform.h"]) ;; esac ], @@ -589,10 +619,17 @@ AC_ARG_WITH(microhttpd, AC_CHECK_HEADERS([microhttpd.h], AC_CHECK_DECL(MHD_OPTION_PER_IP_CONNECTION_LIMIT, AC_CHECK_LIB([microhttpd], [MHD_start_daemon], - lmhd=1), - [],[#include "src/include/platform.h" + [AC_MSG_CHECKING([for libmicrohttpd >= 0.9.18]) + AC_RUN_IFELSE([ + #include "$srcdir/src/include/platform.h" + #include + int main () { return MHD_VERSION >= 0x0091200 ? 0 : 1; } + ], [ + AC_MSG_RESULT(ok) + lmhd=1],[AC_MSG_RESULT(failed)],lmhd=1)]), + [],[#include "$srcdir/src/include/platform.h" #include ]),, - [#include "src/include/platform.h"])]) + [#include "$srcdir/src/include/platform.h"])]) AM_CONDITIONAL(HAVE_MHD, test x$lmhd = x1) AC_DEFINE_UNQUOTED([HAVE_MHD], $lmhd, [We have libmicrohttpd]) @@ -664,7 +701,7 @@ AC_FUNC_VPRINTF AC_HEADER_SYS_WAIT AC_TYPE_OFF_T AC_TYPE_UID_T -AC_CHECK_FUNCS([floor gethostname memmove rmdir strncasecmp strrchr strtol atoll dup2 fdatasync ftruncate gettimeofday memset mkdir mkfifo select socket strcasecmp strchr strdup strerror strstr clock_gettime getrusage rand uname setlocale getcwd mktime gmtime_r gmtime strlcpy strlcat ftruncate stat64 sbrk mmap mremap setrlimit sysconf gethostbyaddr initgroups getifaddrs freeifaddrs getnameinfo getaddrinfo inet_ntoa localtime_r nl_langinfo putenv realpath strndup gethostbyname2 gethostbyname getpeerucred getpeereid setresuid]) +AC_CHECK_FUNCS([floor memmove rmdir strncasecmp strrchr strtol atoll dup2 fdatasync ftruncate gettimeofday memset mkdir mkfifo strcasecmp strchr strdup strerror strstr clock_gettime getrusage rand uname setlocale getcwd mktime gmtime_r gmtime strlcpy strlcat ftruncate stat64 sbrk mmap mremap setrlimit sysconf initgroups getifaddrs freeifaddrs localtime_r nl_langinfo putenv realpath strndup gethostbyname2 gethostbyname getpeerucred getpeereid setresuid $funcstocheck]) # restore LIBS LIBS=$SAVE_LIBS @@ -741,7 +778,7 @@ AC_ARG_WITH(sudo, ], [AC_MSG_RESULT([no])]) AC_SUBST(SUDO_BINARY) - +AM_CONDITIONAL([HAVE_SUDO], [test "x$SUDO_BINARY" != "x" -o -w /]) # test for gnunetdns group name GNUNETDNS_GROUP=gnunetdns @@ -774,15 +811,48 @@ AC_ARG_ENABLE([testruns], AC_MSG_RESULT($enable_test_run) AM_CONDITIONAL([ENABLE_TEST_RUN], [test "x$enable_tests_run" = "xyes"]) + +# should monkey be used when running (certain) services? +AC_MSG_CHECKING(whether to run with monkey) +AC_ARG_ENABLE([monkey], + [AS_HELP_STRING([--enable-monkey], [enable running with monkey])], + [enable_monkey=${enableval}], + [enable_monkey=no]) +AC_MSG_RESULT($enable_monkey) +AM_CONDITIONAL([ENABLE_MONKEY], [test "x$enable_monkey" = "xyes"]) +if test "x$enable_monkey" = "xyes" +then + MONKEYPREFIX="monkey" +else + MONKEYPREFIX="" +fi +AC_SUBST(MONKEYPREFIX) + + # should expensive tests be run? AC_MSG_CHECKING(whether to run expensive tests) AC_ARG_ENABLE([expensivetests], - [AS_HELP_STRING([--enable-expensive-tests], [enable running expensive testcases])], + [AS_HELP_STRING([--enable-expensivetests], [enable running expensive testcases])], [enable_expensive=${enableval}], [enable_expensive=no]) AC_MSG_RESULT($enable_expensive) AM_CONDITIONAL([HAVE_EXPENSIVE_TESTS], [test "x$enable_expensive" = "xyes"]) +# should ports be open for Java services? +AC_MSG_CHECKING(whether to enable ports for gnunet-java) +AC_ARG_ENABLE([javaports], + [AS_HELP_STRING([--enable-javaports], [use non-zero ports for services with Java bindings (default is NO)])], + [enable_java_ports=${enableval}], + [enable_java_ports=no]) +AC_MSG_RESULT($enable_java_ports) +if test "x$enable_java_ports" = "xyes" +then + JAVAPORT="" +else + JAVAPORT="$UNIXONLY" +fi +AC_SUBST(JAVAPORT) + # should benchmarks be run? AC_MSG_CHECKING(whether to run benchmarks during make check) AC_ARG_ENABLE([benchmarks], @@ -806,6 +876,96 @@ AM_CONDITIONAL([HAVE_EXPERIMENTAL], [test "x$enable_experimental" = "xyes"]) if test $build_target = "mingw" then workarounds=1 + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + ],[ + int s = socket (0, 0, 0);]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_SOCKET],1,[Define this if socket() is available]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_SOCKET],0,[Define this if socket() is available]) + ]) + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + ],[ + int s = select (0, NULL, NULL, NULL, NULL);]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_SELECT],1,[Define this if select() is available]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_SELECT],0,[Define this if select() is available]) + ]) + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + ],[ + struct in_addr i; + char *s = inet_ntoa (i);]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_INET_NTOA],1,[Define this if inet_ntoa() is available]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_INET_NTOA],0,[Define this if inet_ntoa() is available]) + ]) + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + ],[ + int s = getnameinfo (NULL, 0, NULL, 0, NULL, 0, 0);]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETNAMEINFO],1,[Define this if getnameinfo() is available]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETNAMEINFO],0,[Define this if getnameinfo() is available]) + ]) + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + ],[ + int s = gethostname (NULL, 0);]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETHOSTNAME],1,[Define this if gethostname() is available]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETHOSTNAME],0,[Define this if gethostname() is available]) + ]) + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + ],[ + void *s = gethostbyname (NULL);]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETHOSTBYNAME],1,[Define this if gethostbyname() is available]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETHOSTBYNAME],0,[Define this if gethostbyname() is available]) + ]) + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + ],[ + void *s = gethostbyaddr (NULL, 0, 0);]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETHOSTBYADDR],1,[Define this if gethostbyaddr() is available]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETHOSTBYADDR],0,[Define this if gethostbyaddr() is available]) + ]) + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + ],[ + int s = getaddrinfo (NULL, NULL, NULL, NULL);]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETADDRINFO],1,[Define this if getaddrinfo() is available]) + ],[ + AC_DEFINE_UNQUOTED([HAVE_GETADDRINFO],1,[Define this if getaddrinfo() is available]) + ]) + else AC_MSG_CHECKING(whether to enable windows workarounds) AC_ARG_ENABLE([windows_workarounds], @@ -865,12 +1025,16 @@ src/fs/Makefile src/fs/fs.conf src/gns/Makefile src/gns/gns.conf +src/gns/nss/Makefile src/hello/Makefile src/include/Makefile src/include/gnunet_directories.h src/hostlist/Makefile +src/lockmanager/Makefile +src/lockmanager/lockmanager.conf src/mesh/Makefile src/mesh/mesh.conf +src/mysql/Makefile src/namestore/Makefile src/namestore/namestore.conf src/nat/Makefile @@ -879,11 +1043,14 @@ src/nse/nse.conf src/peerinfo/Makefile src/peerinfo/peerinfo.conf src/peerinfo-tool/Makefile +src/postgres/Makefile src/pt/Makefile +src/regex/Makefile src/statistics/Makefile src/statistics/statistics.conf src/stream/Makefile src/template/Makefile +src/testbed/Makefile src/testing/Makefile src/topology/Makefile src/transport/Makefile @@ -909,6 +1076,7 @@ pkgconfig/gnunethello.pc pkgconfig/gnunetnat.pc pkgconfig/gnunetnse.pc pkgconfig/gnunetpeerinfo.pc +pkgconfig/gnunetregex.pc pkgconfig/gnunetstatistics.pc pkgconfig/gnunettesting.pc pkgconfig/gnunettransport.pc @@ -930,6 +1098,12 @@ then AC_MSG_NOTICE([NOTICE: sqlite not found. sqLite support will not be compiled.]) fi +# java ports +if test "x$enable_java_ports" = "xyes" +then + AC_MSG_NOTICE([NOTICE: opening ports for gnunet-java bindings by default.]) +fi + if test "x$lmhd" != "x1" then AC_MSG_NOTICE([NOTICE: libmicrohttpd not found, http transport will not be installed.]) @@ -942,6 +1116,11 @@ then AC_MSG_NOTICE([NOTICE: Mac OS X framework build enabled.]) fi +if test "x$SUDO_BINARY" = "x" -a ! -w / +then + AC_MSG_NOTICE([NOTICE: --with-sudo not specified and not running as 'root', will not install GNS NSS library]) +fi + AC_MSG_NOTICE([******************************************** You can compile GNUnet with make diff --git a/contrib/Makefile.am b/contrib/Makefile.am index df6bdc2..0d65393 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -1,29 +1,36 @@ INCLUDES = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include -if !MINGW noinst_PROGRAMS = \ timeout_watchdog +if !MINGW timeout_watchdog_SOURCES = \ timeout_watchdog.c +else +timeout_watchdog_SOURCES = \ + timeout_watchdog_w32.c endif noinst_SCRIPTS = \ gnunet_pyexpect.py \ gnunet_janitor.py +bin_SCRIPTS = \ + gnunet-gns-import.sh + dist_pkgdata_DATA = \ - gnunet-logo-color.png + gnunet-logo-color.png \ + testing_hostkeys.dat EXTRA_DIST = \ coverage.sh \ hostlist.cgi \ hostlist.php \ report.sh \ - testing_hostkeys.dat \ gnunet_pyexpect.py.in \ - gnunet_janitor.py.in + gnunet_janitor.py.in \ + gnunet-gns-import.sh do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' @@ -45,3 +52,30 @@ check_PROGRAMS = \ test_gnunet_prefix_SOURCES = \ test_gnunet_prefix.c + +test_gnunet_prefix_LDADD = \ + $(GCLIBADD) $(WINLIB) \ + $(LTLIBICONV) \ + -lltdl -lunistring $(XLIB) + +pkghellodir= $(pkgdatadir)/hellos + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(pkghellodir) + @$(NORMAL_INSTALL) + for hello in $(srcdir)/hellos/*; do \ + if test -f $$hello; then \ + $(INSTALL_DATA) $$hello $(DESTDIR)$(pkghellodir)/ ; \ + fi \ + done + +dist-hook: + if test -d $(srcdir)/hellos; then \ + mkdir -p $(distdir)/hellos; \ + for hello in $(srcdir)/hellos/*; do \ + if test -f $$hello; then \ + cp -p $$hello $(distdir)/hellos; \ + fi \ + done \ + fi + diff --git a/contrib/Makefile.in b/contrib/Makefile.in index 04a23bf..80134e5 100644 --- a/contrib/Makefile.in +++ b/contrib/Makefile.in @@ -37,7 +37,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -@MINGW_FALSE@noinst_PROGRAMS = timeout_watchdog$(EXEEXT) +noinst_PROGRAMS = timeout_watchdog$(EXEEXT) check_PROGRAMS = test_gnunet_prefix$(EXEEXT) subdir = contrib DIST_COMMON = $(dist_pkgdata_DATA) $(srcdir)/Makefile.am \ @@ -64,15 +64,41 @@ CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am_test_gnunet_prefix_OBJECTS = test_gnunet_prefix.$(OBJEXT) test_gnunet_prefix_OBJECTS = $(am_test_gnunet_prefix_OBJECTS) -test_gnunet_prefix_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +test_gnunet_prefix_DEPENDENCIES = $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) am__v_lt_0 = --silent -am__timeout_watchdog_SOURCES_DIST = timeout_watchdog.c +am__timeout_watchdog_SOURCES_DIST = timeout_watchdog.c \ + timeout_watchdog_w32.c @MINGW_FALSE@am_timeout_watchdog_OBJECTS = timeout_watchdog.$(OBJEXT) +@MINGW_TRUE@am_timeout_watchdog_OBJECTS = \ +@MINGW_TRUE@ timeout_watchdog_w32.$(OBJEXT) timeout_watchdog_OBJECTS = $(am_timeout_watchdog_OBJECTS) timeout_watchdog_LDADD = $(LDADD) -SCRIPTS = $(noinst_SCRIPTS) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" +SCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -102,28 +128,6 @@ am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(test_gnunet_prefix_SOURCES) $(timeout_watchdog_SOURCES) DIST_SOURCES = $(test_gnunet_prefix_SOURCES) \ $(am__timeout_watchdog_SOURCES_DIST) -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(pkgdatadir)" DATA = $(dist_pkgdata_DATA) ETAGS = etags CTAGS = ctags @@ -183,6 +187,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -216,6 +221,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -336,26 +342,39 @@ INCLUDES = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include @MINGW_FALSE@timeout_watchdog_SOURCES = \ @MINGW_FALSE@ timeout_watchdog.c +@MINGW_TRUE@timeout_watchdog_SOURCES = \ +@MINGW_TRUE@ timeout_watchdog_w32.c + noinst_SCRIPTS = \ gnunet_pyexpect.py \ gnunet_janitor.py +bin_SCRIPTS = \ + gnunet-gns-import.sh + dist_pkgdata_DATA = \ - gnunet-logo-color.png + gnunet-logo-color.png \ + testing_hostkeys.dat EXTRA_DIST = \ coverage.sh \ hostlist.cgi \ hostlist.php \ report.sh \ - testing_hostkeys.dat \ gnunet_pyexpect.py.in \ - gnunet_janitor.py.in + gnunet_janitor.py.in \ + gnunet-gns-import.sh do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' test_gnunet_prefix_SOURCES = \ test_gnunet_prefix.c +test_gnunet_prefix_LDADD = \ + $(GCLIBADD) $(WINLIB) \ + $(LTLIBICONV) \ + -lltdl -lunistring $(XLIB) + +pkghellodir = $(pkgdatadir)/hellos all: all-am .SUFFIXES: @@ -414,6 +433,40 @@ test_gnunet_prefix$(EXEEXT): $(test_gnunet_prefix_OBJECTS) $(test_gnunet_prefix_ timeout_watchdog$(EXEEXT): $(timeout_watchdog_OBJECTS) $(timeout_watchdog_DEPENDENCIES) @rm -f timeout_watchdog$(EXEEXT) $(AM_V_CCLD)$(LINK) $(timeout_watchdog_OBJECTS) $(timeout_watchdog_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -423,6 +476,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gnunet_prefix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeout_watchdog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeout_watchdog_w32.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -556,12 +610,15 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(pkgdatadir)"; do \ + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -612,13 +669,13 @@ info: info-am info-am: -install-data-am: install-dist_pkgdataDATA +install-data-am: install-data-local install-dist_pkgdataDATA install-dvi: install-dvi-am install-dvi-am: -install-exec-am: +install-exec-am: install-binSCRIPTS install-html: install-html-am @@ -658,16 +715,17 @@ ps: ps-am ps-am: -uninstall-am: uninstall-dist_pkgdataDATA +uninstall-am: uninstall-binSCRIPTS uninstall-dist_pkgdataDATA .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool \ - clean-noinstPROGRAMS ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dist_pkgdataDATA \ + clean-noinstPROGRAMS ctags dist-hook distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-binSCRIPTS install-data \ + install-data-am install-data-local install-dist_pkgdataDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ @@ -675,13 +733,32 @@ uninstall-am: uninstall-dist_pkgdataDATA installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-dist_pkgdataDATA + uninstall-am uninstall-binSCRIPTS uninstall-dist_pkgdataDATA %.py: %.py.in Makefile $(do_subst) < $< > $@ chmod +x $@ +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(pkghellodir) + @$(NORMAL_INSTALL) + for hello in $(srcdir)/hellos/*; do \ + if test -f $$hello; then \ + $(INSTALL_DATA) $$hello $(DESTDIR)$(pkghellodir)/ ; \ + fi \ + done + +dist-hook: + if test -d $(srcdir)/hellos; then \ + mkdir -p $(distdir)/hellos; \ + for hello in $(srcdir)/hellos/*; do \ + if test -f $$hello; then \ + cp -p $$hello $(distdir)/hellos; \ + fi \ + done \ + fi + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/contrib/gnunet-gns-import.sh b/contrib/gnunet-gns-import.sh new file mode 100755 index 0000000..82d7cda --- /dev/null +++ b/contrib/gnunet-gns-import.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# This shell-script will import some GNS authorities into your GNS +# namestore. +gnunet-namestore -a -e never -n fcfs -p -t PKEY -V 72QC35CO20UJN1E91KPJFNT9TG4CLKAPB4VK9S3Q758S9MLBRKOG diff --git a/contrib/gnunet_janitor.py.in b/contrib/gnunet_janitor.py.in index c11ff4f..056ab9b 100644 --- a/contrib/gnunet_janitor.py.in +++ b/contrib/gnunet_janitor.py.in @@ -34,6 +34,9 @@ import signal if os.name == 'nt': from win32com.client import GetObject WMI = GetObject('winmgmts:') + killsignal = signal.SIGTERM # any valid value will result in TerminateProcess() +else: + killsignal = signal.SIGKILL def get_process_list (): result = [] @@ -44,7 +47,10 @@ def get_process_list (): else: pids = [pid for pid in os.listdir('/proc') if pid.isdigit ()] for pid in pids: - result.append ((pid, open (os.path.join ('/proc', pid, 'comm'), 'rb').read ())) + with open (os.path.join ('/proc', pid, 'cmdline'), 'rb') as p: + cmdline = p.read ().split ('\x00') + if len (cmdline) > 0: + result.append ((pid, cmdline[0])) return result def main (): @@ -57,7 +63,7 @@ def main (): if re.match (r'gnunet-service-arm', p[1]): print ("killing arm process {0:5} {1}".format (p[0], p[1])) try: - os.kill (p[0], signal.SIGTERM) + os.kill (int (p[0]), killsignal) except OSError as e: print ("failed: {0}".format (e)) pass @@ -65,7 +71,7 @@ def main (): if not re.match (r'gnunet-service-arm', p[1]): print ("killing non-arm process {0:5} {1}".format (p[0], p[1])) try: - os.kill (p[0], signal.SIGTERM) + os.kill (int (p[0]), killsignal) except OSError as e: print ("failed: {0}".format (e)) pass diff --git a/contrib/hellos/02UK b/contrib/hellos/02UK new file mode 100644 index 0000000..172a343 Binary files /dev/null and b/contrib/hellos/02UK differ diff --git a/contrib/hellos/1G1M b/contrib/hellos/1G1M new file mode 100644 index 0000000..6c13510 Binary files /dev/null and b/contrib/hellos/1G1M differ diff --git a/contrib/hellos/7RAV b/contrib/hellos/7RAV new file mode 100644 index 0000000..84128df Binary files /dev/null and b/contrib/hellos/7RAV differ diff --git a/contrib/hellos/8B4T b/contrib/hellos/8B4T new file mode 100644 index 0000000..23a319e Binary files /dev/null and b/contrib/hellos/8B4T differ diff --git a/contrib/hellos/94CH b/contrib/hellos/94CH new file mode 100644 index 0000000..9a93382 Binary files /dev/null and b/contrib/hellos/94CH differ diff --git a/contrib/hellos/ATF4 b/contrib/hellos/ATF4 new file mode 100644 index 0000000..cd6c83a Binary files /dev/null and b/contrib/hellos/ATF4 differ diff --git a/contrib/hellos/F1GT b/contrib/hellos/F1GT new file mode 100644 index 0000000..31ae9f7 Binary files /dev/null and b/contrib/hellos/F1GT differ diff --git a/contrib/hellos/KD9V b/contrib/hellos/KD9V new file mode 100644 index 0000000..ab6f76b Binary files /dev/null and b/contrib/hellos/KD9V differ diff --git a/contrib/hellos/KUPL b/contrib/hellos/KUPL new file mode 100644 index 0000000..a35a341 Binary files /dev/null and b/contrib/hellos/KUPL differ diff --git a/contrib/hellos/LJR8 b/contrib/hellos/LJR8 new file mode 100644 index 0000000..c573e06 Binary files /dev/null and b/contrib/hellos/LJR8 differ diff --git a/contrib/hellos/R69Q b/contrib/hellos/R69Q new file mode 100644 index 0000000..087a565 Binary files /dev/null and b/contrib/hellos/R69Q differ diff --git a/contrib/hellos/R6OV b/contrib/hellos/R6OV new file mode 100644 index 0000000..569a856 Binary files /dev/null and b/contrib/hellos/R6OV differ diff --git a/contrib/hellos/RL7P b/contrib/hellos/RL7P new file mode 100644 index 0000000..3076952 Binary files /dev/null and b/contrib/hellos/RL7P differ diff --git a/contrib/timeout_watchdog_w32.c b/contrib/timeout_watchdog_w32.c new file mode 100644 index 0000000..46a6157 --- /dev/null +++ b/contrib/timeout_watchdog_w32.c @@ -0,0 +1,190 @@ +/* + This file is part of GNUnet + (C) 2010 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file contrib/timeout_watchdog_w32.c + * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period + * @author LRN + */ + +#include +#include +#include + +int +main (int argc, char *argv[]) +{ + int i; + DWORD wait_result; + wchar_t *commandline; + wchar_t **wargv; + wchar_t *arg; + unsigned int cmdlen; + wchar_t *idx; + STARTUPINFOW start; + PROCESS_INFORMATION proc; + + wchar_t wpath[MAX_PATH + 1]; + + wchar_t *pathbuf; + DWORD pathbuf_len, alloc_len; + wchar_t *ptr; + wchar_t *non_const_filename; + wchar_t *wcmd; + int wargc; + int timeout = 0; + + HANDLE job; + + if (argc < 3) + { + printf + ("arg 1: timeout in sec., arg 2: executable, arg arguments\n"); + exit (1); + } + + timeout = atoi (argv[1]); + + if (timeout == 0) + timeout = 600; + + commandline = GetCommandLineW (); + if (commandline == NULL) + { + printf ("Failed to get commandline: %lu\n", GetLastError ()); + exit (2); + } + + wargv = CommandLineToArgvW (commandline, &wargc); + if (wargv == NULL || wargc <= 1) + { + printf ("Failed to get parse commandline: %lu\n", GetLastError ()); + exit (3); + } + + job = CreateJobObject (NULL, NULL); + if (job == NULL) + { + printf ("Failed to create a job: %lu\n", GetLastError ()); + exit (4); + } + + pathbuf_len = GetEnvironmentVariableW (L"PATH", (wchar_t *) &pathbuf, 0); + + alloc_len = pathbuf_len + 1; + + pathbuf = malloc (alloc_len * sizeof (wchar_t)); + + ptr = pathbuf; + + alloc_len = GetEnvironmentVariableW (L"PATH", ptr, pathbuf_len); + + cmdlen = wcslen (wargv[2]); + if (cmdlen < 5 || wcscmp (&wargv[2][cmdlen - 4], L".exe") != 0) + { + non_const_filename = malloc (sizeof (wchar_t) * (cmdlen + 5)); + _snwprintf (non_const_filename, cmdlen + 5, L"%s.exe", wargv[2]); + } + else + { + non_const_filename = wcsdup (wargv[2]); + } + + /* Check that this is the full path. If it isn't, search. */ + if (non_const_filename[1] == L':') + _snwprintf (wpath, sizeof (wpath) / sizeof (wchar_t), L"%s", non_const_filename); + else if (!SearchPathW + (pathbuf, non_const_filename, NULL, sizeof (wpath) / sizeof (wchar_t), + wpath, NULL)) + { + printf ("Failed to get find executable: %lu\n", GetLastError ()); + exit (5); + } + free (pathbuf); + free (non_const_filename); + + cmdlen = wcslen (wpath) + 4; + i = 3; + while (NULL != (arg = wargv[i++])) + cmdlen += wcslen (arg) + 4; + + wcmd = idx = malloc (sizeof (wchar_t) * (cmdlen + 1)); + i = 2; + while (NULL != (arg = wargv[i++])) + { + /* This is to escape trailing slash */ + wchar_t arg_lastchar = arg[wcslen (arg) - 1]; + if (idx == wcmd) + idx += swprintf (idx, L"\"%s%s\" ", wpath, + arg_lastchar == L'\\' ? L"\\" : L""); + else + { + if (wcschr (arg, L' ') != NULL) + idx += swprintf (idx, L"\"%s%s\"%s", arg, + arg_lastchar == L'\\' ? L"\\" : L"", i == wargc ? L"" : L" "); + else + idx += swprintf (idx, L"%s%s%s", arg, + arg_lastchar == L'\\' ? L"\\" : L"", i == wargc ? L"" : L" "); + } + } + + LocalFree (wargv); + + memset (&start, 0, sizeof (start)); + start.cb = sizeof (start); + + if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, CREATE_SUSPENDED, + NULL, NULL, &start, &proc)) + { + wprintf (L"Failed to get spawn process `%s' with arguments `%s': %lu\n", wpath, wcmd, GetLastError ()); + exit (6); + } + + AssignProcessToJobObject (job, proc.hProcess); + + ResumeThread (proc.hThread); + CloseHandle (proc.hThread); + + free (wcmd); + + wait_result = WaitForSingleObject (proc.hProcess, timeout * 1000); + if (wait_result == WAIT_OBJECT_0) + { + DWORD status; + wait_result = GetExitCodeProcess (proc.hProcess, &status); + CloseHandle (proc.hProcess); + if (wait_result != 0) + { + printf ("Test process exited with result %lu\n", status); + TerminateJobObject (job, status); + exit (status); + } + printf ("Test process exited (failed to obtain exit status)\n"); + TerminateJobObject (job, 0); + exit (0); + } + printf ("Child processes were killed after timeout of %u seconds\n", + timeout); + TerminateJobObject (job, 1); + CloseHandle (proc.hProcess); + exit (1); +} + +/* end of timeout_watchdog_w32.c */ diff --git a/doc/Makefile.in b/doc/Makefile.in index 601e718..f1b7b45 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -159,6 +159,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -192,6 +193,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 6d98ffa..c640460 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1,13 +1,17 @@ man_MANS = \ gnunet-arm.1 \ + gnunet-core.1 \ gnunet-directory.1 \ gnunet-download.1 \ gnunet-download-manager.1 \ gnunet-fs.1 \ + gnunet-gns.1 \ + gnunet-namestore.1 \ gnunet-nat-server.1 \ gnunet-peerinfo.1 \ gnunet-pseudonym.1 \ gnunet-publish.1 \ + gnunet-rsa.1 \ gnunet-search.1 \ gnunet-statistics.1 \ gnunet-transport.1 \ diff --git a/doc/man/Makefile.in b/doc/man/Makefile.in index f9c665d..76f2b02 100644 --- a/doc/man/Makefile.in +++ b/doc/man/Makefile.in @@ -144,6 +144,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -177,6 +178,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -295,14 +297,18 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ man_MANS = \ gnunet-arm.1 \ + gnunet-core.1 \ gnunet-directory.1 \ gnunet-download.1 \ gnunet-download-manager.1 \ gnunet-fs.1 \ + gnunet-gns.1 \ + gnunet-namestore.1 \ gnunet-nat-server.1 \ gnunet-peerinfo.1 \ gnunet-pseudonym.1 \ gnunet-publish.1 \ + gnunet-rsa.1 \ gnunet-search.1 \ gnunet-statistics.1 \ gnunet-transport.1 \ diff --git a/doc/man/gnunet-arm.1 b/doc/man/gnunet-arm.1 index 1bd4467..86a748e 100644 --- a/doc/man/gnunet-arm.1 +++ b/doc/man/gnunet-arm.1 @@ -34,6 +34,9 @@ Stop the specified SERVICE if it is running. While this will kill the service r .IP "\-s, \-\-start" Start all GNUnet default services on this system (and also ARM). Naturally, if a service is demanded by a default service, it will then also be started. Running "gnunet-arm -s" is the usual way to start a GNUnet peer. .B +.IP "\-I, \-\-info" +List all running services. +.B .IP "\-v, \-\-version" Print GNUnet version number. diff --git a/doc/man/gnunet-core.1 b/doc/man/gnunet-core.1 new file mode 100644 index 0000000..0971b42 --- /dev/null +++ b/doc/man/gnunet-core.1 @@ -0,0 +1,35 @@ +.TH gnunet\-core "1" "1 Apr 2012" "GNUnet" +.SH NAME +gnunet\-core \- measure and control the core subsystem + +.SH SYNOPSIS +.B gnunet\-core +[\fIOPTIONS\fR] +.SH DESCRIPTION +.PP + +gnunet\-core is a tool to access various functions of GNUnet's core subsystem from the command\-line. The only function right now is to list the peers that are directly connected to this peer (with successful cryptographic handshake). + +.TP +\fB\-c \fIFILENAME\fR, \fB\-\-config=FILENAME\fR +configuration file to use +.TP +\fB\-h\fR, \fB\-\-help\fR +print help page +.TP +\fB\-L \fILOGLEVEL\fR, \fB\-\-loglevel=LOGLEVEL\fR +Change the loglevel. Possible values for LOGLEVEL are ERROR, WARNING, INFO and DEBUG. +.TP +\fB\-v\fR, \fB\-\-version\fR +print the version number +.TP +\fB\-V\fR, \fB\-\-verbose\fR +be verbose + +.SH NOTES + + +.SH "REPORTING BUGS" +Report bugs by using mantis or by sending electronic mail to +.SH "SEE ALSO" +\fBgnunet\-transport\fP(1) diff --git a/doc/man/gnunet-gns.1 b/doc/man/gnunet-gns.1 new file mode 100644 index 0000000..4d00c82 --- /dev/null +++ b/doc/man/gnunet-gns.1 @@ -0,0 +1,36 @@ +.TH GNUNET\-GNS 1 "Mar 5, 2012" "GNUnet" + +.SH NAME +gnunet\-gns \- manipulate GNUnet GNS zones + +.SH SYNOPSIS +.B gnunet\-gns +.RI [ options ] -z ZONEFILE +.br + +.SH DESCRIPTION +\fBgnunet\-gns\fP can be used to create and manipulate a GNS zone. + +.SH OPTIONS +.B +.IP "\-c FILENAME, \-\-config=FILENAME" +Use the configuration file FILENAME. +.B +.IP "\-h, \-\-help" +Print short help on options. +.B +.IP "\-L LOGLEVEL, \-\-loglevel=LOGLEVEL" +Use LOGLEVEL for logging. Valid values are DEBUG, INFO, WARNING and ERROR. +.B +.IP "\-s NAME, \-\-shorten=NAME" +GNS domain name to shorten +.B +.IP "\-v, \-\-version" +Print GNUnet version number. + +.SH BUGS +Report bugs by using Mantis or by sending electronic mail to + + +.SH "SEE ALSO" +\fBgnunet\-namestore\fP(1) diff --git a/doc/man/gnunet-namestore.1 b/doc/man/gnunet-namestore.1 new file mode 100644 index 0000000..4ecdbb0 --- /dev/null +++ b/doc/man/gnunet-namestore.1 @@ -0,0 +1,58 @@ +.TH GNUNET\-NAMESTORE 1 "Mar 5, 2012" "GNUnet" + +.SH NAME +gnunet\-namestore \- manipulate GNUnet zones + +.SH SYNOPSIS +.B gnunet\-namestore +.RI [ options ] -z ZONEFILE +.br + +.SH DESCRIPTION +\fBgnunet\-namestore\fP can be used to create and manipulate a GNS zone. + +.SH OPTIONS +.B +.IP "\-a, \-\-add" +Desired operation is adding a record +.B +.IP "\-c FILENAME, \-\-config=FILENAME" +Use the configuration file FILENAME. +.B +.IP "\-d, \-\-delete" +Desired operation is deleting a record +.B +.IP "\-D, \-\-display" +Desired operation is listing of matching records +.B +.IP "\-e TIME, \-\-expiration=TIME" +Specifies expiration time of record to add; format is relative time, i.e "1 h" or "7 d 30 m". Supported units are "ms", "s", "min" or "minutes", "h" (hours), "d" (days) and "a" (years). +.B +.IP "\-h, \-\-help" +Print short help on options. +.B +.IP "\-L LOGLEVEL, \-\-loglevel=LOGLEVEL" +Use LOGLEVEL for logging. Valid values are DEBUG, INFO, WARNING and ERROR. +.B +.IP "\-n NAME, \-\-name=NAME" +Name of the record to add/delete/display +.B +.IP "\-t TYPE, \-\-type=TYPE" +Type of the record to add/delete/display (i.e. "A", "AAAA", "NS", "PKEY", "MX" etc.) +.B +.IP "\-v, \-\-version" +Print GNUnet version number. +.B +.IP "\-V VALUE, \-\-value=VALUE" +Value to store or remove from the GNS zone. Specific format depends on the record type. A records expect a dotted decimal IPv4 address, AAAA records an IPv6 address, PKEY a public key in GNUnet's printable format, and CNAME and NS records should be a domain name. +.B +.IP "\-z FILENAME, \-\-zonekey=FILENAME" +Specifies the filename with the private key for the zone (mandatory option) + + +.SH BUGS +Report bugs by using Mantis or by sending electronic mail to + + +.SH "SEE ALSO" +\fBgnunet\-gns\fP(1) diff --git a/doc/man/gnunet-rsa.1 b/doc/man/gnunet-rsa.1 new file mode 100644 index 0000000..46f24de --- /dev/null +++ b/doc/man/gnunet-rsa.1 @@ -0,0 +1,40 @@ +.TH GNUNET\-RSA 1 "Mar 15, 2012" "GNUnet" + +.SH NAME +gnunet\-rsa \- manipulate GNUnet RSA key files + +.SH SYNOPSIS +.B gnunet\-rsa +.RI [ options ] FILENAME +.br + +.SH DESCRIPTION +\fBgnunet\-rsa\fP can be used to create an RSA private key and to print the corresponding public key. You must specify a filename containing an RSA private key in GNUnet format as an argument. If the file does not exist, gnunet\-rsa will create a key. This may then take a while. If the option \-p is given, the corresponding public key will be printed to the console. + +.SH OPTIONS +.B +.IP "\-p, \-\-print-public-key" +Print the corresponding public key to stdout. +.B +.IP "\-P, \-\-print-peer-identity" +Print the corresponding peer identity (hash of the public key) to stdout. This hash is used for the name of peers. +.B +.IP "\-s, \-\-print-short-identity" +Print the corresponding short hash (256-bit hash of the public key) to stdout. This hash is used for names in the zkey zone. +.B +.IP "\-c FILENAME, \-\-config=FILENAME" +Use the configuration file FILENAME. +.B +.IP "\-h, \-\-help" +Print short help on options. +.B +.IP "\-L LOGLEVEL, \-\-loglevel=LOGLEVEL" +Use LOGLEVEL for logging. Valid values are DEBUG, INFO, WARNING and ERROR. +.B +.IP "\-v, \-\-version" +Print GNUnet version number. + + +.SH BUGS +Report bugs by using Mantis or by sending electronic mail to + diff --git a/gnunet_config.h b/gnunet_config.h index 3d50b1a..0cbce52 100644 --- a/gnunet_config.h +++ b/gnunet_config.h @@ -34,7 +34,7 @@ /* 1 if extra logging is enabled, 2 for very verbose extra logging, 0 otherwise */ -#define GNUNET_EXTRA_LOGGING GNUNET_YES +#define GNUNET_EXTRA_LOGGING GNUNET_NO /* Define to 1 if you have the `argz_add' function. */ #define HAVE_ARGZ_ADD 1 @@ -159,22 +159,22 @@ /* Define to 1 if you have the `ftruncate' function. */ #define HAVE_FTRUNCATE 1 -/* Define to 1 if you have the `getaddrinfo' function. */ +/* Define this if getaddrinfo() is available */ #define HAVE_GETADDRINFO 1 /* Define to 1 if you have the `getcwd' function. */ #define HAVE_GETCWD 1 -/* Define to 1 if you have the `gethostbyaddr' function. */ +/* Define this if gethostbyaddr() is available */ #define HAVE_GETHOSTBYADDR 1 -/* Define to 1 if you have the `gethostbyname' function. */ +/* Define this if gethostbyname() is available */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the `gethostbyname2' function. */ #define HAVE_GETHOSTBYNAME2 1 -/* Define to 1 if you have the `gethostname' function. */ +/* Define this if gethostname() is available */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the `getifaddrs' function. */ @@ -183,7 +183,7 @@ /* getloadavg supported */ #define HAVE_GETLOADAVG 1 -/* Define to 1 if you have the `getnameinfo' function. */ +/* Define this if getnameinfo() is available */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the `getpeereid' function. */ @@ -202,10 +202,10 @@ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_GLPK_H */ +#define HAVE_GLPK_H 1 /* Define to 1 if `presolve' is a member of `glp_iocp'. */ -/* #undef HAVE_GLP_IOCP_PRESOLVE */ +#define HAVE_GLP_IOCP_PRESOLVE 1 /* Define to 1 if you have the `gmtime' function. */ #define HAVE_GMTIME 1 @@ -219,7 +219,7 @@ /* Define to 1 if you have the header file. */ #define HAVE_IFADDRS_H 1 -/* Define to 1 if you have the `inet_ntoa' function. */ +/* Define this if inet_ntoa() is available */ #define HAVE_INET_NTOA 1 /* Define to 1 if you have the `initgroups' function. */ @@ -247,7 +247,7 @@ #define HAVE_LIBDLLOADER 1 /* Have GLPK */ -/* #undef HAVE_LIBGLPK */ +#define HAVE_LIBGLPK 1 /* Define to 1 if you have the `intl' library (-lintl). */ /* #undef HAVE_LIBINTL */ @@ -348,6 +348,9 @@ /* Define to 1 if you have the `nl_langinfo' function. */ #define HAVE_NL_LANGINFO 1 +/* Define to 1 if you have the header file. */ +#define HAVE_NSS_H 1 + /* Define to 1 if the system has the type `off_t'. */ #define HAVE_OFF_T 1 @@ -378,7 +381,7 @@ /* Define to 1 if you have the `sbrk' function. */ #define HAVE_SBRK 1 -/* Define to 1 if you have the `select' function. */ +/* Define this if select() is available */ #define HAVE_SELECT 1 /* Define to 1 if you have the `setlocale' function. */ @@ -405,7 +408,7 @@ /* Do we have sockaddr_in.sin_len? */ /* #undef HAVE_SOCKADDR_IN_SIN_LEN */ -/* Define to 1 if you have the `socket' function. */ +/* Define this if socket() is available */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ @@ -706,7 +709,7 @@ #define PACKAGE_NAME "gnunet" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "gnunet 0.9.2" +#define PACKAGE_STRING "gnunet 0.9.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gnunet" @@ -715,7 +718,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.9.2" +#define PACKAGE_VERSION "0.9.3" /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void @@ -748,7 +751,7 @@ /* #undef TM_IN_SYS_TIME */ /* Version number of package */ -#define VERSION "0.9.2" +#define VERSION "0.9.3" /* This is a Windows system */ /* #undef WINDOWS */ diff --git a/gnunet_config.h.in b/gnunet_config.h.in index f1b691d..1a99e14 100644 --- a/gnunet_config.h.in +++ b/gnunet_config.h.in @@ -158,22 +158,22 @@ /* Define to 1 if you have the `ftruncate' function. */ #undef HAVE_FTRUNCATE -/* Define to 1 if you have the `getaddrinfo' function. */ +/* Define this if getaddrinfo() is available */ #undef HAVE_GETADDRINFO /* Define to 1 if you have the `getcwd' function. */ #undef HAVE_GETCWD -/* Define to 1 if you have the `gethostbyaddr' function. */ +/* Define this if gethostbyaddr() is available */ #undef HAVE_GETHOSTBYADDR -/* Define to 1 if you have the `gethostbyname' function. */ +/* Define this if gethostbyname() is available */ #undef HAVE_GETHOSTBYNAME /* Define to 1 if you have the `gethostbyname2' function. */ #undef HAVE_GETHOSTBYNAME2 -/* Define to 1 if you have the `gethostname' function. */ +/* Define this if gethostname() is available */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the `getifaddrs' function. */ @@ -182,7 +182,7 @@ /* getloadavg supported */ #undef HAVE_GETLOADAVG -/* Define to 1 if you have the `getnameinfo' function. */ +/* Define this if getnameinfo() is available */ #undef HAVE_GETNAMEINFO /* Define to 1 if you have the `getpeereid' function. */ @@ -218,7 +218,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_IFADDRS_H -/* Define to 1 if you have the `inet_ntoa' function. */ +/* Define this if inet_ntoa() is available */ #undef HAVE_INET_NTOA /* Define to 1 if you have the `initgroups' function. */ @@ -347,6 +347,9 @@ /* Define to 1 if you have the `nl_langinfo' function. */ #undef HAVE_NL_LANGINFO +/* Define to 1 if you have the header file. */ +#undef HAVE_NSS_H + /* Define to 1 if the system has the type `off_t'. */ #undef HAVE_OFF_T @@ -377,7 +380,7 @@ /* Define to 1 if you have the `sbrk' function. */ #undef HAVE_SBRK -/* Define to 1 if you have the `select' function. */ +/* Define this if select() is available */ #undef HAVE_SELECT /* Define to 1 if you have the `setlocale' function. */ @@ -404,7 +407,7 @@ /* Do we have sockaddr_in.sin_len? */ #undef HAVE_SOCKADDR_IN_SIN_LEN -/* Define to 1 if you have the `socket' function. */ +/* Define this if socket() is available */ #undef HAVE_SOCKET /* Define to 1 if you have the header file. */ diff --git a/m4/Makefile.in b/m4/Makefile.in index 43507ec..cda2c71 100644 --- a/m4/Makefile.in +++ b/m4/Makefile.in @@ -119,6 +119,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -152,6 +153,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/pkgconfig/Makefile.in b/pkgconfig/Makefile.in index d487dcb..7177ec3 100644 --- a/pkgconfig/Makefile.in +++ b/pkgconfig/Makefile.in @@ -44,8 +44,9 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/gnunetfragmentation.pc.in $(srcdir)/gnunetfs.pc.in \ $(srcdir)/gnunethello.pc.in $(srcdir)/gnunetnat.pc.in \ $(srcdir)/gnunetnse.pc.in $(srcdir)/gnunetpeerinfo.pc.in \ - $(srcdir)/gnunetstatistics.pc.in $(srcdir)/gnunettesting.pc.in \ - $(srcdir)/gnunettransport.pc.in $(srcdir)/gnunetutil.pc.in + $(srcdir)/gnunetregex.pc.in $(srcdir)/gnunetstatistics.pc.in \ + $(srcdir)/gnunettesting.pc.in $(srcdir)/gnunettransport.pc.in \ + $(srcdir)/gnunetutil.pc.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ @@ -67,8 +68,8 @@ CONFIG_CLEAN_FILES = gnunetarm.pc gnunetblock.pc gnunetcore.pc \ gnunetdatacache.pc gnunetdatastore.pc gnunetdht.pc \ gnunetdhtlog.pc gnunetdv.pc gnunetfragmentation.pc gnunetfs.pc \ gnunethello.pc gnunetnat.pc gnunetnse.pc gnunetpeerinfo.pc \ - gnunetstatistics.pc gnunettesting.pc gnunettransport.pc \ - gnunetutil.pc + gnunetregex.pc gnunetstatistics.pc gnunettesting.pc \ + gnunettransport.pc gnunetutil.pc CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) @@ -157,6 +158,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -190,6 +192,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -414,6 +417,8 @@ gnunetnse.pc: $(top_builddir)/config.status $(srcdir)/gnunetnse.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ gnunetpeerinfo.pc: $(top_builddir)/config.status $(srcdir)/gnunetpeerinfo.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +gnunetregex.pc: $(top_builddir)/config.status $(srcdir)/gnunetregex.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ gnunetstatistics.pc: $(top_builddir)/config.status $(srcdir)/gnunetstatistics.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ gnunettesting.pc: $(top_builddir)/config.status $(srcdir)/gnunettesting.pc.in diff --git a/pkgconfig/gnunetregex.pc.in b/pkgconfig/gnunetregex.pc.in new file mode 100644 index 0000000..9deed47 --- /dev/null +++ b/pkgconfig/gnunetregex.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: GNUnet regex +Description: Provides API for parsing regular expressions into finite automata +URL: http://gnunet.org +Version: @VERSION@ +Requires: +Libs: -L${libdir} -lgnunetregex +Cflags: -I${includedir} diff --git a/po/POTFILES.in b/po/POTFILES.in index a116284..198daf9 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -3,8 +3,6 @@ src/arm/do_start_process.c src/arm/gnunet-arm.c src/arm/gnunet-service-arm.c src/arm/mockup-service.c -src/ats/ats_api.c -src/ats/ats_api_peer_change_preference.c src/ats/ats_api_performance.c src/ats/ats_api_scheduling.c src/ats/gnunet-service-ats_addresses.c @@ -20,8 +18,9 @@ src/chat/chat.c src/chat/gnunet-chat.c src/chat/gnunet-service-chat.c src/core/core_api.c +src/core/core_api_is_connected.c src/core/core_api_iterate_peers.c -src/core/gnunet-core-list-connections.c +src/core/gnunet-core.c src/core/gnunet-service-core.c src/core/gnunet-service-core_clients.c src/core/gnunet-service-core_kx.c @@ -41,6 +40,7 @@ src/datastore/plugin_datastore_sqlite.c src/datastore/plugin_datastore_template.c src/dht/dht_api.c src/dht/gnunet-dht-get.c +src/dht/gnunet-dht-monitor.c src/dht/gnunet-dht-put.c src/dht/gnunet-service-dht.c src/dht/gnunet-service-dht_clients.c @@ -100,19 +100,32 @@ src/fs/gnunet-service-fs_put.c src/fs/gnunet-unindex.c src/fs/plugin_block_fs.c src/gns/gns_api.c -src/gns/gnunet-gns-lookup.c +src/gns/gnunet-gns.c +src/gns/gnunet-gns-fcfsd.c +src/gns/gnunet-gns-proxy.c src/gns/gnunet-service-gns.c -src/gns/namestore_stub_api.c +src/gns/gnunet-service-gns_interceptor.c +src/gns/gnunet-service-gns_resolver.c +src/gns/nss/nss_gns.c +src/gns/nss/nss_gns_query.c +src/gns/plugin_block_gns.c src/hello/address.c +src/hello/gnunet-hello.c src/hello/hello.c src/hostlist/gnunet-daemon-hostlist.c src/hostlist/hostlist-client.c src/hostlist/hostlist-server.c +src/integration-tests/connection_watchdog.c +src/lockmanager/gnunet-service-lockmanager.c +src/lockmanager/lockmanager_api.c src/mesh/gnunet-service-mesh.c src/mesh/mesh_api.c src/mesh/mesh_tunnel_tree.c +src/mysql/mysql.c +src/namestore/gnunet-namestore.c src/namestore/gnunet-service-namestore.c src/namestore/namestore_api.c +src/namestore/namestore_common.c src/namestore/plugin_namestore_sqlite.c src/nat/gnunet-helper-nat-client.c src/nat/gnunet-helper-nat-client-windows.c @@ -129,17 +142,29 @@ src/peerinfo/gnunet-service-peerinfo.c src/peerinfo/peerinfo_api.c src/peerinfo/peerinfo_api_notify.c src/peerinfo-tool/gnunet-peerinfo.c +src/peerinfo-tool/gnunet-peerinfo_plugins.c +src/postgres/postgres.c src/pt/gnunet-daemon-pt.c +src/regex/regex.c src/statistics/gnunet-service-statistics.c src/statistics/gnunet-statistics.c src/statistics/statistics_api.c src/stream/stream_api.c src/template/gnunet-service-template.c src/template/gnunet-template.c +src/testbed/testbed_api.c +src/testbed/testbed_api_hosts.c +src/testbed/testbed_api_operations.c +src/testbed/testbed_api_peers.c +src/testbed/testbed_api_services.c +src/testbed/testbed_api_testbed.c +src/testbed/testbed_api_test.c +src/testbed/testbed_api_topology.c src/testing/gnunet-testing.c src/testing/helper.c src/testing/testing.c src/testing/testing_group.c +src/testing/testing_new.c src/testing/testing_peergroup.c src/topology/gnunet-daemon-topology.c src/transport/gnunet-helper-transport-wlan.c @@ -153,12 +178,10 @@ src/transport/gnunet-service-transport_plugins.c src/transport/gnunet-service-transport_validation.c src/transport/gnunet-transport.c src/transport/gnunet-transport-certificate-creation.c -src/transport/gnunet-transport-connect-running-peers.c src/transport/gnunet-transport-wlan-sender.c src/transport/plugin_transport_http.c src/transport/plugin_transport_http_client.c src/transport/plugin_transport_http_server.c -src/transport/plugin_transport_smtp.c src/transport/plugin_transport_tcp.c src/transport/plugin_transport_template.c src/transport/plugin_transport_udp_broadcasting.c @@ -197,6 +220,7 @@ src/util/getopt.c src/util/getopt_helpers.c src/util/gnunet-config-diff.c src/util/gnunet-resolver.c +src/util/gnunet-rsa.c src/util/gnunet-service-resolver.c src/util/helper.c src/util/load.c @@ -216,6 +240,7 @@ src/util/server_nc.c src/util/server_tc.c src/util/service.c src/util/signal.c +src/util/speedup.c src/util/strings.c src/util/time.c src/util/winproc.c @@ -223,4 +248,7 @@ src/vpn/gnunet-helper-vpn.c src/vpn/gnunet-service-vpn.c src/vpn/gnunet-vpn.c src/vpn/vpn_api.c +src/dht/dht.h src/include/gnunet_common.h +src/include/gnunet_postgres_lib.h +src/include/gnunet_time_lib.h diff --git a/po/de.gmo b/po/de.gmo index 7a939b9..729be3a 100644 Binary files a/po/de.gmo and b/po/de.gmo differ diff --git a/po/de.po b/po/de.po index 1266419..7f15916 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GNUnet 0.7.0b\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2012-02-28 18:30+0100\n" +"POT-Creation-Date: 2012-06-05 15:47+0200\n" "PO-Revision-Date: 2006-03-17 21:37+0100\n" "Last-Translator: Nils Durner \n" "Language-Team: German \n" @@ -17,264 +17,279 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/arm/arm_api.c:187 +#: src/arm/arm_api.c:165 #, fuzzy msgid "Failed to transmit shutdown request to client.\n" msgstr "Fehler beim Senden einer `%s' Anfrage an den SMTP Server.\n" -#: src/arm/arm_api.c:378 +#: src/arm/arm_api.c:349 #, fuzzy, c-format msgid "Configuration failes to specify option `%s' in section `%s'!\n" msgstr "" "Die Konfigurationsdatei muss in der Sektion `%s' unter `%s' ein Verzeichnis " "angeben, in dem FS Daten gespeichert werden.\n" -#: src/arm/arm_api.c:392 +#: src/arm/arm_api.c:363 #, fuzzy, c-format msgid "Configuration fails to specify option `%s' in section `%s'!\n" msgstr "" "Die Konfigurationsdatei muss in der Sektion `%s' unter `%s' ein Verzeichnis " "angeben, in dem FS Daten gespeichert werden.\n" -#: src/arm/arm_api.c:467 +#: src/arm/arm_api.c:432 #, fuzzy, c-format msgid "Error receiving response to `%s' request from ARM for service `%s'\n" msgstr "Beschädigte Antwort auf `%s' von Knoten `%s' empfangen.\n" -#: src/arm/arm_api.c:523 +#: src/arm/arm_api.c:485 #, c-format msgid "Requesting start of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:524 +#: src/arm/arm_api.c:486 #, c-format msgid "Requesting termination of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:546 +#: src/arm/arm_api.c:507 #, c-format msgid "Error while trying to transmit request to start `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:548 +#: src/arm/arm_api.c:508 #, c-format msgid "Error while trying to transmit request to stop `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:581 +#: src/arm/arm_api.c:540 #, fuzzy, c-format msgid "Asked to start service `%s' within %llu ms\n" msgstr "`%s': Nachricht wurde nicht innerhalb %llu ms empfangen.\n" -#: src/arm/arm_api.c:654 +#: src/arm/arm_api.c:612 #, fuzzy, c-format msgid "Stopping service `%s' within %llu ms\n" msgstr "Keine Antwort innerhalb %llums erhalten.\n" -#: src/arm/gnunet-arm.c:149 +#: src/arm/gnunet-arm.c:159 #, fuzzy, c-format msgid "Service `%s' is unknown to ARM.\n" msgstr "Namespace `%s' hat das Rating %d.\n" -#: src/arm/gnunet-arm.c:154 +#: src/arm/gnunet-arm.c:164 #, fuzzy, c-format msgid "Service `%s' has been stopped.\n" msgstr "Dienst gelĂśscht.\n" -#: src/arm/gnunet-arm.c:157 +#: src/arm/gnunet-arm.c:167 #, fuzzy, c-format msgid "Service `%s' was already running.\n" msgstr "Diese Suche läuft bereits!\n" -#: src/arm/gnunet-arm.c:162 +#: src/arm/gnunet-arm.c:172 #, fuzzy, c-format msgid "Service `%s' has been started.\n" msgstr "Dienst gelĂśscht.\n" -#: src/arm/gnunet-arm.c:165 +#: src/arm/gnunet-arm.c:175 #, fuzzy, c-format msgid "Service `%s' was already being stopped.\n" msgstr "Dienst gelĂśscht.\n" -#: src/arm/gnunet-arm.c:169 +#: src/arm/gnunet-arm.c:179 #, fuzzy, c-format msgid "Service `%s' was already not running.\n" msgstr "Diese Suche läuft bereits!\n" -#: src/arm/gnunet-arm.c:173 +#: src/arm/gnunet-arm.c:183 #, fuzzy msgid "Request ignored as ARM is shutting down.\n" msgstr "`%s' fährt herunter.\n" -#: src/arm/gnunet-arm.c:177 +#: src/arm/gnunet-arm.c:187 #, fuzzy msgid "Error communicating with ARM service.\n" msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." -#: src/arm/gnunet-arm.c:181 +#: src/arm/gnunet-arm.c:191 #, fuzzy msgid "Timeout communicating with ARM service.\n" msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." -#: src/arm/gnunet-arm.c:185 +#: src/arm/gnunet-arm.c:195 #, fuzzy msgid "Operation failed.\n" msgstr "Absicherung fehlgeschlagen bei %s:%d.\n" -#: src/arm/gnunet-arm.c:189 +#: src/arm/gnunet-arm.c:199 msgid "Unknown response code from ARM.\n" msgstr "" -#: src/arm/gnunet-arm.c:216 +#: src/arm/gnunet-arm.c:222 +#, fuzzy +msgid "Error communicating with ARM. ARM not running?\n" +msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." + +#: src/arm/gnunet-arm.c:225 +#, fuzzy +msgid "Running services:\n" +msgstr "Collection `%s' begonnen.\n" + +#: src/arm/gnunet-arm.c:249 #, fuzzy, c-format msgid "Fatal configuration error: `%s' option in section `%s' missing.\n" msgstr "" "Es muss eine Liste von Freunden in der Konfigurationsdatei unter `%s' in der " "Sektion `%s' angegeben werden.\n" -#: src/arm/gnunet-arm.c:224 src/arm/gnunet-arm.c:324 +#: src/arm/gnunet-arm.c:257 src/arm/gnunet-arm.c:357 src/arm/gnunet-arm.c:373 msgid "Fatal error initializing ARM API.\n" msgstr "" -#: src/arm/gnunet-arm.c:247 +#: src/arm/gnunet-arm.c:280 #, fuzzy, c-format msgid "Failed to remove configuration file %s\n" msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':" -#: src/arm/gnunet-arm.c:253 +#: src/arm/gnunet-arm.c:286 #, fuzzy, c-format msgid "Failed to remove servicehome directory %s\n" msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" -#: src/arm/gnunet-arm.c:355 +#: src/arm/gnunet-arm.c:407 msgid "stop all GNUnet services" msgstr "" -#: src/arm/gnunet-arm.c:357 +#: src/arm/gnunet-arm.c:409 msgid "start a particular service" msgstr "" -#: src/arm/gnunet-arm.c:359 +#: src/arm/gnunet-arm.c:411 msgid "stop a particular service" msgstr "" -#: src/arm/gnunet-arm.c:361 +#: src/arm/gnunet-arm.c:413 msgid "start all GNUnet default services" msgstr "" -#: src/arm/gnunet-arm.c:364 +#: src/arm/gnunet-arm.c:416 msgid "stop and start all GNUnet default services" msgstr "" -#: src/arm/gnunet-arm.c:367 +#: src/arm/gnunet-arm.c:419 msgid "delete config file and directory on exit" msgstr "" -#: src/arm/gnunet-arm.c:369 +#: src/arm/gnunet-arm.c:421 msgid "don't print status messages" msgstr "" -#: src/arm/gnunet-arm.c:372 +#: src/arm/gnunet-arm.c:424 #, fuzzy msgid "timeout for completing current operation" msgstr "Zeit, die gewartet wird, bis der Durchlauf fertiggestellt wird (in ms)" -#: src/arm/gnunet-arm.c:383 +#: src/arm/gnunet-arm.c:426 +msgid "List currently running services" +msgstr "" + +#: src/arm/gnunet-arm.c:437 msgid "Control services and the Automated Restart Manager (ARM)" msgstr "" -#: src/arm/gnunet-service-arm.c:328 +#: src/arm/gnunet-service-arm.c:332 #, fuzzy, c-format msgid "Failed to start service `%s'\n" msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n" -#: src/arm/gnunet-service-arm.c:331 +#: src/arm/gnunet-service-arm.c:335 #, fuzzy, c-format msgid "Starting service `%s'\n" msgstr "Collection `%s' begonnen.\n" -#: src/arm/gnunet-service-arm.c:357 +#: src/arm/gnunet-service-arm.c:361 #, fuzzy msgid "Could not send status result to client\n" msgstr "Anfrage konnte nicht an gnunetd gesendet werden.\n" -#: src/arm/gnunet-service-arm.c:484 +#: src/arm/gnunet-service-arm.c:393 +#, fuzzy +msgid "Could not send list result to client\n" +msgstr "Anfrage konnte nicht an gnunetd gesendet werden.\n" + +#: src/arm/gnunet-service-arm.c:523 #, fuzzy, c-format msgid "Unable to create socket for service `%s': %s\n" msgstr "Fehler beim Anlegen des Benutzerkontos:" -#: src/arm/gnunet-service-arm.c:506 +#: src/arm/gnunet-service-arm.c:545 #, c-format msgid "Unable to bind listening socket for service `%s' to address `%s': %s\n" msgstr "" -#: src/arm/gnunet-service-arm.c:520 +#: src/arm/gnunet-service-arm.c:559 #, c-format msgid "ARM now monitors connections to service `%s' at `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:628 +#: src/arm/gnunet-service-arm.c:667 #, fuzzy, c-format msgid "Preparing to stop `%s'\n" msgstr "Collection `%s' begonnen.\n" -#: src/arm/gnunet-service-arm.c:782 +#: src/arm/gnunet-service-arm.c:878 #, fuzzy, c-format msgid "Restarting service `%s'.\n" msgstr "Collection `%s' begonnen.\n" -#: src/arm/gnunet-service-arm.c:877 +#: src/arm/gnunet-service-arm.c:970 msgid "exit" msgstr "" -#: src/arm/gnunet-service-arm.c:882 +#: src/arm/gnunet-service-arm.c:975 msgid "signal" msgstr "" -#: src/arm/gnunet-service-arm.c:887 +#: src/arm/gnunet-service-arm.c:980 #, fuzzy msgid "unknown" msgstr "Unbekannter Fehler" -#: src/arm/gnunet-service-arm.c:921 +#: src/arm/gnunet-service-arm.c:986 +#, fuzzy, c-format +msgid "Service `%s' took %llu ms to terminate\n" +msgstr "Dienst gelĂśscht.\n" + +#: src/arm/gnunet-service-arm.c:1021 #, c-format msgid "Service `%s' terminated with status %s/%d, will restart in %llu ms\n" msgstr "" -#: src/arm/gnunet-service-arm.c:967 src/arm/mockup-service.c:41 -#, fuzzy -msgid "Failed to transmit shutdown ACK.\n" -msgstr "Fehler beim Starten der Collection.\n" - -#: src/arm/gnunet-service-arm.c:1067 +#: src/arm/gnunet-service-arm.c:1127 #, fuzzy, c-format msgid "Configuration file `%s' for service `%s' not valid: %s\n" msgstr "Konfigurationsdatei `%s' wurde erzeugt.\n" -#: src/arm/gnunet-service-arm.c:1069 +#: src/arm/gnunet-service-arm.c:1129 msgid "option missing" msgstr "" -#: src/arm/gnunet-service-arm.c:1152 +#: src/arm/gnunet-service-arm.c:1213 #, fuzzy, c-format msgid "Starting default services `%s'\n" msgstr "Collection `%s' begonnen.\n" -#: src/arm/gnunet-service-arm.c:1163 +#: src/arm/gnunet-service-arm.c:1224 #, c-format msgid "Default service `%s' not configured correctly!\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1177 +#: src/arm/gnunet-service-arm.c:1238 msgid "" "No default services configured, GNUnet will not really start right now.\n" msgstr "" -#: src/arm/mockup-service.c:46 -msgid "Transmitting shutdown ACK.\n" -msgstr "" - -#: src/arm/mockup-service.c:69 +#: src/arm/mockup-service.c:44 msgid "Initiating shutdown as requested by client.\n" msgstr "" @@ -334,195 +349,198 @@ msgstr "" msgid "Undefined mandatory parameter: memberCallback\n" msgstr "" -#: src/chat/gnunet-chat.c:92 +#: src/chat/gnunet-chat.c:93 msgid "Joined\n" msgstr "" -#: src/chat/gnunet-chat.c:124 +#: src/chat/gnunet-chat.c:125 src/chat/gnunet-chat.c:133 +#: src/chat/gnunet-chat.c:213 src/chat/gnunet-chat.c:253 +#: src/chat/gnunet-chat.c:329 src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:400 src/chat/gnunet-chat.c:700 msgid "anonymous" msgstr "" -#: src/chat/gnunet-chat.c:130 +#: src/chat/gnunet-chat.c:144 #, fuzzy, c-format msgid "(%s) `%s' said: %s\n" msgstr "`%s' %s schlug fehl: %s\n" -#: src/chat/gnunet-chat.c:133 src/chat/gnunet-chat.c:136 +#: src/chat/gnunet-chat.c:147 src/chat/gnunet-chat.c:150 #, fuzzy, c-format msgid "(%s) `%s' said to you: %s\n" msgstr "`%s' %s schlug fehl: %s\n" -#: src/chat/gnunet-chat.c:139 +#: src/chat/gnunet-chat.c:153 #, fuzzy, c-format msgid "(%s) `%s' said for sure: %s\n" msgstr "`%s' fehlgeschlagen fĂźr Laufwerk %s: %u\n" -#: src/chat/gnunet-chat.c:142 +#: src/chat/gnunet-chat.c:156 #, fuzzy, c-format msgid "(%s) `%s' said to you for sure: %s\n" msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#: src/chat/gnunet-chat.c:145 +#: src/chat/gnunet-chat.c:159 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you received: %s\n" msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#: src/chat/gnunet-chat.c:148 +#: src/chat/gnunet-chat.c:162 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you and only you received: %s\n" msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#: src/chat/gnunet-chat.c:151 +#: src/chat/gnunet-chat.c:165 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you received from him or her: %s\n" msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#: src/chat/gnunet-chat.c:156 +#: src/chat/gnunet-chat.c:170 #, fuzzy, c-format msgid "" "(%s) `%s' was confirmed that you and only you received from him or her: %s\n" msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#: src/chat/gnunet-chat.c:159 +#: src/chat/gnunet-chat.c:173 #, fuzzy, c-format msgid "(%s) `%s' said off the record: %s\n" msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#: src/chat/gnunet-chat.c:162 +#: src/chat/gnunet-chat.c:176 #, c-format msgid "(%s) <%s> said using an unknown message type: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:193 +#: src/chat/gnunet-chat.c:217 #, c-format msgid "'%s' acknowledged message #%d\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' entered the room\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, fuzzy, c-format msgid "`%s' left the room\n" msgstr "Fehler beim Binden an UDP Port %d.\n" -#: src/chat/gnunet-chat.c:284 src/chat/gnunet-chat.c:316 +#: src/chat/gnunet-chat.c:321 src/chat/gnunet-chat.c:363 #, fuzzy msgid "Could not change username\n" msgstr "Namespace `%s' konnte nicht erstellt werden (existiert bereits?).\n" -#: src/chat/gnunet-chat.c:288 src/chat/gnunet-chat.c:630 +#: src/chat/gnunet-chat.c:334 src/chat/gnunet-chat.c:702 #, fuzzy, c-format msgid "Joining room `%s' as user `%s'...\n" msgstr "UngĂźltige Antwort auf `%s' von Knoten `%s' empfangen.\n" -#: src/chat/gnunet-chat.c:320 +#: src/chat/gnunet-chat.c:373 #, fuzzy, c-format msgid "Changed username to `%s'\n" msgstr "Benutzer/Gruppe kann nicht zu `%s' gewechselt werden: %s\n" -#: src/chat/gnunet-chat.c:333 +#: src/chat/gnunet-chat.c:388 #, c-format msgid "Users in room `%s': " msgstr "" -#: src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:434 msgid "Syntax: /msg USERNAME MESSAGE" msgstr "" -#: src/chat/gnunet-chat.c:379 -#, fuzzy, c-format -msgid "Unknown user `%s'\n" -msgstr "Unbekannte Operation `%s'\n" +#: src/chat/gnunet-chat.c:443 +#, c-format +msgid "Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n" +msgstr "" -#: src/chat/gnunet-chat.c:395 +#: src/chat/gnunet-chat.c:460 #, c-format msgid "User `%s' is currently not in the room!\n" msgstr "" -#: src/chat/gnunet-chat.c:448 +#: src/chat/gnunet-chat.c:513 #, fuzzy, c-format msgid "Unknown command `%s'\n" msgstr "Unbekannte Operation `%s'\n" -#: src/chat/gnunet-chat.c:459 +#: src/chat/gnunet-chat.c:524 msgid "" "Use `/join #roomname' to join a chat room. Joining a room will cause you to " "leave the current room" msgstr "" -#: src/chat/gnunet-chat.c:463 +#: src/chat/gnunet-chat.c:528 msgid "" "Use `/nick nickname' to change your nickname. This will cause you to leave " "the current room and immediately rejoin it with the new name." msgstr "" -#: src/chat/gnunet-chat.c:467 +#: src/chat/gnunet-chat.c:532 msgid "" "Use `/msg nickname message' to send a private message to the specified user" msgstr "" -#: src/chat/gnunet-chat.c:470 +#: src/chat/gnunet-chat.c:535 msgid "The `/notice' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:472 +#: src/chat/gnunet-chat.c:537 msgid "The `/query' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:474 +#: src/chat/gnunet-chat.c:539 msgid "Use `/sig message' to send a signed public message" msgstr "" -#: src/chat/gnunet-chat.c:477 +#: src/chat/gnunet-chat.c:542 msgid "Use `/ack message' to require signed acknowledgment of the message" msgstr "" -#: src/chat/gnunet-chat.c:480 +#: src/chat/gnunet-chat.c:545 msgid "Use `/anonymous message' to send a public anonymous message" msgstr "" -#: src/chat/gnunet-chat.c:482 +#: src/chat/gnunet-chat.c:547 msgid "The `/anon' command is an alias for `/anonymous'" msgstr "" -#: src/chat/gnunet-chat.c:484 +#: src/chat/gnunet-chat.c:549 msgid "Use `/quit' to terminate gnunet-chat" msgstr "" -#: src/chat/gnunet-chat.c:486 +#: src/chat/gnunet-chat.c:551 msgid "The `/leave' command is an alias for `/quit'" msgstr "" -#: src/chat/gnunet-chat.c:489 +#: src/chat/gnunet-chat.c:554 msgid "Use `/names' to list all of the current members in the chat room" msgstr "" -#: src/chat/gnunet-chat.c:491 +#: src/chat/gnunet-chat.c:556 msgid "Use `/help command' to get help for a specific command" msgstr "" -#: src/chat/gnunet-chat.c:606 +#: src/chat/gnunet-chat.c:672 #, fuzzy msgid "You must specify a nickname\n" msgstr "Sie mĂźssen einen Empfänger angeben!\n" -#: src/chat/gnunet-chat.c:622 +#: src/chat/gnunet-chat.c:688 #, fuzzy, c-format msgid "Failed to join room `%s'\n" msgstr "Fehler beim Binden an UDP Port %d.\n" -#: src/chat/gnunet-chat.c:655 +#: src/chat/gnunet-chat.c:727 msgid "set the nickname to use (required)" msgstr "" -#: src/chat/gnunet-chat.c:658 +#: src/chat/gnunet-chat.c:730 msgid "set the chat room to join" msgstr "" -#: src/chat/gnunet-chat.c:670 +#: src/chat/gnunet-chat.c:742 msgid "Join a chat on GNUnet." msgstr "" @@ -546,184 +564,186 @@ msgstr "Fehler beim Speichern der Konfiguration!" msgid "Failed to queue a leave notification\n" msgstr "Fehler beim Speichern der Konfiguration!" -#: src/core/core_api.c:798 +#: src/core/core_api.c:786 msgid "Client was disconnected from core service, trying to reconnect.\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:77 -#: src/peerinfo-tool/gnunet-peerinfo.c:60 +#: src/core/gnunet-core.c:54 src/peerinfo-tool/gnunet-peerinfo.c:286 #, fuzzy, c-format msgid "Peer `%s'\n" msgstr "Ich bin Peer `%s'.\n" -#: src/core/gnunet-core-list-connections.c:175 -#: src/peerinfo-tool/gnunet-peerinfo.c:194 +#: src/core/gnunet-core.c:72 src/peerinfo-tool/gnunet-peerinfo.c:817 #, fuzzy, c-format msgid "Invalid command line argument `%s'\n" msgstr "UngĂźltige Kommandozeilen Parameter:\n" -#: src/core/gnunet-core-list-connections.c:196 -#: src/peerinfo-tool/gnunet-peerinfo.c:252 -msgid "don't resolve host names" -msgstr "" - -#: src/core/gnunet-core-list-connections.c:203 +#: src/core/gnunet-core.c:95 #, fuzzy msgid "Print information about connected peers." msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." -#: src/core/gnunet-service-core.c:99 +#: src/core/gnunet-service-core.c:97 #, c-format msgid "Core service of `%4s' ready.\n" msgstr "" -#: src/core/gnunet-service-core_clients.c:360 +#: src/core/gnunet-service-core_clients.c:370 #, fuzzy msgid "# send requests dropped (disconnected)" msgstr "# gap Anfragen verworfen: Kollision in RT" -#: src/core/gnunet-service-core_clients.c:465 +#: src/core/gnunet-service-core_clients.c:475 #, fuzzy msgid "# messages discarded (session disconnected)" msgstr "# defragmentierter Nachrichten" -#: src/core/gnunet-service-core_clients.c:801 +#: src/core/gnunet-service-core_clients.c:818 #, fuzzy, c-format msgid "# bytes of messages of type %u received" msgstr "# Bytes Rauschen empfangen" -#: src/core/gnunet-service-core_kx.c:493 +#: src/core/gnunet-service-core_kx.c:565 msgid "# bytes encrypted" msgstr "# Bytes verschlĂźsselt" -#: src/core/gnunet-service-core_kx.c:543 +#: src/core/gnunet-service-core_kx.c:617 msgid "# bytes decrypted" msgstr "# Bytes entschlĂźsselt" -#: src/core/gnunet-service-core_kx.c:604 src/dv/gnunet-service-dv.c:3002 -#: src/hostlist/hostlist-server.c:436 src/peerinfo-tool/gnunet-peerinfo.c:151 +#: src/core/gnunet-service-core_kx.c:681 src/dv/gnunet-service-dv.c:3003 #, fuzzy msgid "Error in communication with PEERINFO service\n" msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." -#: src/core/gnunet-service-core_kx.c:623 +#: src/core/gnunet-service-core_kx.c:700 msgid "# Delayed connecting due to lack of public key" msgstr "" -#: src/core/gnunet-service-core_kx.c:673 +#: src/core/gnunet-service-core_kx.c:753 msgid "# key exchanges initiated" msgstr "" -#: src/core/gnunet-service-core_kx.c:694 +#: src/core/gnunet-service-core_kx.c:775 msgid "# key exchanges stopped" msgstr "" -#: src/core/gnunet-service-core_kx.c:746 +#: src/core/gnunet-service-core_kx.c:828 #, fuzzy msgid "# session keys received" msgstr "# SitzungsschlĂźssel abgelehnt" -#: src/core/gnunet-service-core_kx.c:765 +#: src/core/gnunet-service-core_kx.c:845 #, fuzzy, c-format msgid "`%s' is for `%s', not for me. Ignoring.\n" msgstr "Größe der `%s' Nachricht ist zu kurz. Nachricht wird ignoriert.\n" -#: src/core/gnunet-service-core_kx.c:803 +#: src/core/gnunet-service-core_kx.c:890 #, fuzzy msgid "# SET_KEY messages decrypted" msgstr "# defragmentierter Nachrichten" -#: src/core/gnunet-service-core_kx.c:883 -#: src/transport/gnunet-service-transport_validation.c:803 +#: src/core/gnunet-service-core_kx.c:977 +#: src/transport/gnunet-service-transport_validation.c:810 #, fuzzy msgid "# PING messages received" msgstr "# PING Nachrichten erstellt" -#: src/core/gnunet-service-core_kx.c:917 +#: src/core/gnunet-service-core_kx.c:1010 #, c-format msgid "" "Received PING from `%s' for different identity: I am `%s', PONG identity: `" "%s'\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:938 +#: src/core/gnunet-service-core_kx.c:1029 #, fuzzy msgid "# PONG messages created" msgstr "# PING Nachrichten erstellt" -#: src/core/gnunet-service-core_kx.c:1026 +#: src/core/gnunet-service-core_kx.c:1125 #, fuzzy msgid "# sessions terminated by timeout" msgstr "# Bytes verworfen von TCP (ausgehend)" -#: src/core/gnunet-service-core_kx.c:1037 +#: src/core/gnunet-service-core_kx.c:1135 #, fuzzy msgid "# keepalive messages sent" msgstr "# Klartext PING Nachrichten gesendet" -#: src/core/gnunet-service-core_kx.c:1095 -#: src/transport/gnunet-service-transport_validation.c:1026 +#: src/core/gnunet-service-core_kx.c:1236 +#: src/transport/gnunet-service-transport_validation.c:1031 #, fuzzy msgid "# PONG messages received" msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/core/gnunet-service-core_kx.c:1125 +#: src/core/gnunet-service-core_kx.c:1275 #, fuzzy msgid "# PONG messages decrypted" msgstr "# PING Nachrichten erstellt" -#: src/core/gnunet-service-core_kx.c:1157 +#: src/core/gnunet-service-core_kx.c:1303 #, fuzzy msgid "# session keys confirmed via PONG" msgstr "# KnotenankĂźndigungen empfangen" -#: src/core/gnunet-service-core_kx.c:1223 +#: src/core/gnunet-service-core_kx.c:1329 +#, fuzzy +msgid "# rekey operations confirmed via PONG" +msgstr "# KnotenankĂźndigungen empfangen" + +#: src/core/gnunet-service-core_kx.c:1381 +#: src/core/gnunet-service-core_kx.c:1398 #, fuzzy msgid "# SET_KEY and PING messages created" msgstr "# PING Nachrichten erstellt" -#: src/core/gnunet-service-core_kx.c:1364 +#: src/core/gnunet-service-core_kx.c:1402 +msgid "# REKEY operations performed" +msgstr "" + +#: src/core/gnunet-service-core_kx.c:1537 msgid "# failed to decrypt message (no session key)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1406 -#: src/core/gnunet-service-core_kx.c:1431 +#: src/core/gnunet-service-core_kx.c:1577 +#: src/core/gnunet-service-core_kx.c:1602 #, fuzzy msgid "# bytes dropped (duplicates)" msgstr "# Bytes verworfen von UDP (outgoing)" -#: src/core/gnunet-service-core_kx.c:1418 +#: src/core/gnunet-service-core_kx.c:1589 #, fuzzy msgid "# bytes dropped (out of sequence)" msgstr "# Bytes verworfen von UDP (outgoing)" -#: src/core/gnunet-service-core_kx.c:1455 +#: src/core/gnunet-service-core_kx.c:1626 #, fuzzy, c-format msgid "Message received far too old (%llu ms). Content ignored.\n" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/core/gnunet-service-core_kx.c:1459 +#: src/core/gnunet-service-core_kx.c:1630 #, fuzzy msgid "# bytes dropped (ancient message)" msgstr "# Bytes verworfen von UDP (outgoing)" -#: src/core/gnunet-service-core_kx.c:1467 +#: src/core/gnunet-service-core_kx.c:1638 #, fuzzy msgid "# bytes of payload decrypted" msgstr "# Bytes entschlĂźsselt" -#: src/core/gnunet-service-core_kx.c:1528 +#: src/core/gnunet-service-core_kx.c:1700 #, fuzzy msgid "Core service is lacking HOSTKEY configuration setting. Exiting.\n" msgstr "GNUnet Konfiguration" -#: src/core/gnunet-service-core_kx.c:1536 +#: src/core/gnunet-service-core_kx.c:1708 msgid "Core service could not access hostkey. Exiting.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1546 src/hostlist/hostlist-server.c:555 -#: src/peerinfo-tool/gnunet-peerinfo.c:202 -#: src/transport/gnunet-service-transport.c:595 +#: src/core/gnunet-service-core_kx.c:1718 src/hostlist/hostlist-server.c:551 +#: src/peerinfo-tool/gnunet-peerinfo.c:823 +#: src/transport/gnunet-service-transport.c:611 #, fuzzy msgid "Could not access PEERINFO service. Exiting.\n" msgstr "Auf die Namespace Informationen konnte nicht zugegriffen werden.\n" @@ -734,30 +754,41 @@ msgid "# sessions terminated by transport disconnect" msgstr "# KnotenankĂźndigungen empfangen" #: src/core/gnunet-service-core_neighbours.c:180 -#: src/core/gnunet-service-core_neighbours.c:342 +#: src/core/gnunet-service-core_neighbours.c:334 msgid "# neighbour entries allocated" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:251 +#: src/core/gnunet-service-core_neighbours.c:247 msgid "# encrypted bytes given to transport" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:430 +#: src/core/gnunet-service-core_neighbours.c:418 #, fuzzy, c-format msgid "Unsupported message of type %u (%u bytes) received from peer `%s'\n" msgstr "UngĂźltige Nachricht des Typs %u empfangen. Nachricht wird verworfen.\n" -#: src/core/gnunet-service-core_sessions.c:208 -#: src/core/gnunet-service-core_sessions.c:273 -msgid "# entries in session map" -msgstr "" +#: src/core/gnunet-service-core_sessions.c:206 +#: src/core/gnunet-service-core_sessions.c:269 +#: src/dht/gnunet-service-dht_neighbours.c:625 +#: src/dht/gnunet-service-dht_neighbours.c:683 +#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 +#: src/topology/gnunet-daemon-topology.c:709 +#: src/topology/gnunet-daemon-topology.c:810 +#: src/transport/gnunet-service-transport_neighbours.c:874 +#: src/transport/gnunet-service-transport_neighbours.c:1080 +#: src/transport/gnunet-service-transport_neighbours.c:1089 +#: src/transport/gnunet-service-transport_neighbours.c:2568 +#: src/transport/gnunet-service-transport_neighbours.c:2814 +#, fuzzy +msgid "# peers connected" +msgstr "# verbundener Knoten" -#: src/core/gnunet-service-core_sessions.c:238 +#: src/core/gnunet-service-core_sessions.c:236 #, fuzzy msgid "# type map refreshes sent" msgstr "# p2p Trace-Antworten gesendet" -#: src/core/gnunet-service-core_sessions.c:414 +#: src/core/gnunet-service-core_sessions.c:406 msgid "# messages discarded (expired prior to transmission)" msgstr "" @@ -771,428 +802,407 @@ msgstr "# verschlĂźsselter PING Nachrichten empfangen" msgid "# updates to my type map" msgstr "" -#: src/datacache/datacache.c:118 src/datacache/datacache.c:255 -#: src/datastore/gnunet-service-datastore.c:854 +#: src/datacache/datacache.c:115 src/datacache/datacache.c:250 +#: src/datastore/gnunet-service-datastore.c:834 #, fuzzy msgid "# bytes stored" msgstr "# bytes in der Datenbank" -#: src/datacache/datacache.c:144 src/datacache/datacache.c:151 -#: src/datastore/gnunet-service-datastore.c:1531 -#: src/datastore/gnunet-service-datastore.c:1542 +#: src/datacache/datacache.c:141 src/datacache/datacache.c:148 +#: src/datastore/gnunet-service-datastore.c:1483 +#: src/datastore/gnunet-service-datastore.c:1494 #, fuzzy, c-format msgid "No `%s' specified for `%s' in configuration!\n" msgstr "In der Konfigurationsdatei wurden keine Anwendungen definiert!\n" -#: src/datacache/datacache.c:183 +#: src/datacache/datacache.c:180 #, c-format msgid "Loading `%s' datacache plugin\n" msgstr "" -#: src/datacache/datacache.c:191 +#: src/datacache/datacache.c:188 #, fuzzy, c-format msgid "Failed to load datacache plugin for `%s'\n" msgstr "Fehler beim Aktualisieren der Daten des Moduls `%s'\n" -#: src/datacache/datacache.c:281 +#: src/datacache/datacache.c:276 #, fuzzy msgid "# requests received" msgstr "# Client Trace-Anfragen empfangen" -#: src/datacache/datacache.c:291 +#: src/datacache/datacache.c:284 msgid "# requests filtered by bloom filter" msgstr "" -#: src/datacache/plugin_datacache_mysql.c:103 -#: src/datacache/plugin_datacache_mysql.c:110 -#: src/datacache/plugin_datacache_mysql.c:517 -#: src/datacache/plugin_datacache_mysql.c:526 -#: src/datacache/plugin_datacache_mysql.c:598 -#: src/datacache/plugin_datacache_mysql.c:614 -#: src/datacache/plugin_datacache_sqlite.c:71 -#: src/datacache/plugin_datacache_sqlite.c:74 -#: src/datastore/plugin_datastore_mysql.c:139 -#: src/datastore/plugin_datastore_mysql.c:146 -#: src/datastore/plugin_datastore_mysql.c:613 -#: src/datastore/plugin_datastore_mysql.c:673 -#: src/datastore/plugin_datastore_mysql.c:685 -#: src/datastore/plugin_datastore_mysql.c:1362 -#: src/datastore/plugin_datastore_mysql.c:1376 -#: src/datastore/plugin_datastore_sqlite.c:61 -#: src/namestore/plugin_namestore_sqlite.c:49 src/util/crypto_ksk.c:49 -#: src/util/crypto_rsa.c:92 src/include/gnunet_common.h:507 -#: src/include/gnunet_common.h:514 +#: src/datacache/plugin_datacache_mysql.c:97 +#: src/datacache/plugin_datacache_mysql.c:104 +#: src/datacache/plugin_datacache_sqlite.c:69 +#: src/datacache/plugin_datacache_sqlite.c:72 +#: src/datastore/plugin_datastore_mysql.c:803 +#: src/datastore/plugin_datastore_mysql.c:817 +#: src/datastore/plugin_datastore_sqlite.c:57 src/mysql/mysql.c:41 +#: src/mysql/mysql.c:48 src/mysql/mysql.c:522 src/mysql/mysql.c:531 +#: src/mysql/mysql.c:591 src/mysql/mysql.c:607 +#: src/namestore/plugin_namestore_sqlite.c:51 src/util/crypto_ksk.c:49 +#: src/util/crypto_rsa.c:67 src/include/gnunet_common.h:525 +#: src/include/gnunet_common.h:532 #, c-format msgid "`%s' failed at %s:%d with error: %s\n" msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#: src/datacache/plugin_datacache_mysql.c:224 -#: src/datastore/plugin_datastore_mysql.c:316 -#, c-format -msgid "Trying to use file `%s' for MySQL configuration.\n" -msgstr "Versuche, Datei `%s' fĂźr MySQL Konfiguration zu verwenden.\n" - -#: src/datacache/plugin_datacache_mysql.c:230 -#: src/datastore/plugin_datastore_mysql.c:322 -#, fuzzy, c-format -msgid "Could not access file `%s': %s\n" -msgstr "`%s' konnte nicht aufgelĂśst werden: %s\n" - -#: src/datacache/plugin_datacache_mysql.c:979 +#: src/datacache/plugin_datacache_mysql.c:450 msgid "MySQL datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_postgres.c:79 -#: src/datastore/plugin_datastore_postgres.c:93 -#, fuzzy, c-format -msgid "`%s:%s' failed at %s:%d with error: %s" -msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" - -#: src/datacache/plugin_datacache_postgres.c:149 -#, fuzzy, c-format -msgid "Unable to initialize Postgres: %s" -msgstr "SQLite Datenbank konnte nicht initialisiert werden: %s.\n" - -#: src/datacache/plugin_datacache_postgres.c:499 +#: src/datacache/plugin_datacache_postgres.c:367 msgid "Postgres datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:424 +#: src/datacache/plugin_datacache_sqlite.c:410 msgid "Sqlite datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:457 -#: src/datastore/plugin_datastore_sqlite.c:414 -#: src/namestore/plugin_namestore_sqlite.c:381 +#: src/datacache/plugin_datacache_sqlite.c:443 +#: src/datastore/plugin_datastore_sqlite.c:408 +#: src/namestore/plugin_namestore_sqlite.c:370 msgid "Tried to close sqlite without finalizing all prepared statements.\n" msgstr "" +#: src/datacache/plugin_datacache_sqlite.c:450 +#, fuzzy, c-format +msgid "Failed to close statement %p: %d\n" +msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" + #: src/datacache/plugin_datacache_template.c:121 msgid "Template datacache running\n" msgstr "" -#: src/datastore/datastore_api.c:289 +#: src/datastore/datastore_api.c:305 #, fuzzy msgid "Failed to transmit request to drop database.\n" msgstr "Fehler beim Senden einer `%s' Anfrage an den SMTP Server.\n" -#: src/datastore/datastore_api.c:372 +#: src/datastore/datastore_api.c:388 msgid "# queue entry timeouts" msgstr "" -#: src/datastore/datastore_api.c:418 +#: src/datastore/datastore_api.c:432 msgid "# queue overflows" msgstr "" -#: src/datastore/datastore_api.c:445 +#: src/datastore/datastore_api.c:459 #, fuzzy msgid "# queue entries created" msgstr "# dht Anfragen weitergeleitet" -#: src/datastore/datastore_api.c:465 +#: src/datastore/datastore_api.c:477 #, fuzzy msgid "# Requests dropped from datastore queue" msgstr "# gap Anfragen verworfen: Kollision in RT" -#: src/datastore/datastore_api.c:513 +#: src/datastore/datastore_api.c:525 msgid "# datastore connections (re)created" msgstr "" -#: src/datastore/datastore_api.c:540 +#: src/datastore/datastore_api.c:548 msgid "# reconnected to DATASTORE" msgstr "" -#: src/datastore/datastore_api.c:608 +#: src/datastore/datastore_api.c:612 #, fuzzy msgid "# transmission request failures" msgstr "# Klartext PONG Nachrichten empfangen" -#: src/datastore/datastore_api.c:631 +#: src/datastore/datastore_api.c:633 #, fuzzy msgid "# bytes sent to datastore" msgstr "# bytes in der Datenbank" -#: src/datastore/datastore_api.c:772 +#: src/datastore/datastore_api.c:764 #, fuzzy msgid "Failed to receive status response from database." msgstr "" "\n" "Fehler beim Empfangen der Antwort von gnunetd.\n" -#: src/datastore/datastore_api.c:786 +#: src/datastore/datastore_api.c:778 msgid "Error reading response from datastore service" msgstr "" -#: src/datastore/datastore_api.c:798 src/datastore/datastore_api.c:804 +#: src/datastore/datastore_api.c:790 src/datastore/datastore_api.c:796 #, fuzzy msgid "Invalid error message received from datastore service" msgstr "UngĂźltige `%s' Nachricht von Knoten `%s' empfangen.\n" -#: src/datastore/datastore_api.c:810 +#: src/datastore/datastore_api.c:800 #, fuzzy msgid "# status messages received" msgstr "# verschlĂźsselter PING Nachrichten empfangen" -#: src/datastore/datastore_api.c:883 +#: src/datastore/datastore_api.c:869 #, fuzzy msgid "# PUT requests executed" msgstr "# dht Anfragen weitergeleitet" -#: src/datastore/datastore_api.c:954 +#: src/datastore/datastore_api.c:936 #, fuzzy msgid "# RESERVE requests executed" msgstr "# dht Anfragen weitergeleitet" -#: src/datastore/datastore_api.c:1019 +#: src/datastore/datastore_api.c:997 msgid "# RELEASE RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1080 +#: src/datastore/datastore_api.c:1054 #, fuzzy msgid "# UPDATE requests executed" msgstr "# dht Anfragen weitergeleitet" -#: src/datastore/datastore_api.c:1148 +#: src/datastore/datastore_api.c:1118 #, fuzzy msgid "# REMOVE requests executed" msgstr "# dht Anfragen weitergeleitet" -#: src/datastore/datastore_api.c:1193 +#: src/datastore/datastore_api.c:1163 #, fuzzy msgid "Failed to receive response from database.\n" msgstr "" "\n" "Fehler beim Empfangen der Antwort von gnunetd.\n" -#: src/datastore/datastore_api.c:1253 +#: src/datastore/datastore_api.c:1221 #, fuzzy msgid "# Results received" msgstr "# Bytes empfangen Ăźber TCP" -#: src/datastore/datastore_api.c:1324 +#: src/datastore/datastore_api.c:1286 msgid "# GET REPLICATION requests executed" msgstr "" -#: src/datastore/datastore_api.c:1391 +#: src/datastore/datastore_api.c:1349 msgid "# GET ZERO ANONYMITY requests executed" msgstr "" -#: src/datastore/datastore_api.c:1455 +#: src/datastore/datastore_api.c:1409 #, fuzzy msgid "# GET requests executed" msgstr "# dht Anfragen weitergeleitet" -#: src/datastore/gnunet-service-datastore.c:351 +#: src/datastore/gnunet-service-datastore.c:349 #, fuzzy msgid "# bytes expired" msgstr "# Bytes empfangen Ăźber TCP" -#: src/datastore/gnunet-service-datastore.c:426 +#: src/datastore/gnunet-service-datastore.c:422 msgid "# bytes purged (low-priority)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:486 +#: src/datastore/gnunet-service-datastore.c:480 msgid "Transmission to client failed!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:640 +#: src/datastore/gnunet-service-datastore.c:511 +msgid "Shutdown in progress, aborting transmission.\n" +msgstr "" + +#: src/datastore/gnunet-service-datastore.c:626 msgid "# results found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:685 +#: src/datastore/gnunet-service-datastore.c:669 #, c-format msgid "" "Insufficient space (%llu bytes are available) to satisfy `%s' request for " "%llu bytes\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:696 +#: src/datastore/gnunet-service-datastore.c:680 #, c-format msgid "" "The requested amount (%llu bytes) is larger than the cache size (%llu " "bytes)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:700 +#: src/datastore/gnunet-service-datastore.c:684 msgid "" "Insufficient space to satisfy request and requested amount is larger than " "cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:706 +#: src/datastore/gnunet-service-datastore.c:690 msgid "Insufficient space to satisfy request" msgstr "" -#: src/datastore/gnunet-service-datastore.c:711 -#: src/datastore/gnunet-service-datastore.c:765 -#: src/datastore/gnunet-service-datastore.c:986 -#: src/datastore/gnunet-service-datastore.c:1465 +#: src/datastore/gnunet-service-datastore.c:695 +#: src/datastore/gnunet-service-datastore.c:747 +#: src/datastore/gnunet-service-datastore.c:960 +#: src/datastore/gnunet-service-datastore.c:1417 msgid "# reserved" msgstr "" -#: src/datastore/gnunet-service-datastore.c:780 +#: src/datastore/gnunet-service-datastore.c:760 msgid "Could not find matching reservation" msgstr "" -#: src/datastore/gnunet-service-datastore.c:868 +#: src/datastore/gnunet-service-datastore.c:846 #, c-format msgid "Need %llu bytes more space (%llu allowed, using %llu)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1034 +#: src/datastore/gnunet-service-datastore.c:1006 #, fuzzy msgid "# GET requests received" msgstr "# Client Trace-Anfragen empfangen" -#: src/datastore/gnunet-service-datastore.c:1048 +#: src/datastore/gnunet-service-datastore.c:1018 msgid "# requests filtered by bloomfilter" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1076 +#: src/datastore/gnunet-service-datastore.c:1046 #, fuzzy msgid "# UPDATE requests received" msgstr "# Client Trace-Anfragen empfangen" -#: src/datastore/gnunet-service-datastore.c:1110 +#: src/datastore/gnunet-service-datastore.c:1076 #, fuzzy msgid "# GET REPLICATION requests received" msgstr "# Client Trace-Anfragen empfangen" -#: src/datastore/gnunet-service-datastore.c:1145 +#: src/datastore/gnunet-service-datastore.c:1109 #, fuzzy msgid "# GET ZERO ANONYMITY requests received" msgstr "# Client Trace-Anfragen empfangen" -#: src/datastore/gnunet-service-datastore.c:1172 +#: src/datastore/gnunet-service-datastore.c:1134 #, fuzzy msgid "Content not found" msgstr "Kommando `%s' wurde nicht gefunden!\n" -#: src/datastore/gnunet-service-datastore.c:1182 +#: src/datastore/gnunet-service-datastore.c:1142 msgid "# bytes removed (explicit request)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1216 +#: src/datastore/gnunet-service-datastore.c:1174 #, fuzzy msgid "# REMOVE requests received" msgstr "# Client Trace-Anfragen empfangen" -#: src/datastore/gnunet-service-datastore.c:1260 +#: src/datastore/gnunet-service-datastore.c:1216 #, c-format msgid "Datastore payload inaccurate (%lld < %lld). Trying to fix.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1323 +#: src/datastore/gnunet-service-datastore.c:1277 #, c-format msgid "Loading `%s' datastore plugin\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1332 +#: src/datastore/gnunet-service-datastore.c:1286 #, fuzzy, c-format msgid "Failed to load datastore plugin for `%s'\n" msgstr "Anwendung `%s' konnte nicht initialisiert werden.\n" -#: src/datastore/gnunet-service-datastore.c:1536 +#: src/datastore/gnunet-service-datastore.c:1488 #, fuzzy, c-format msgid "# bytes used in file-sharing datastore `%s'" msgstr "# bytes erlaubt in der Datenbank" -#: src/datastore/gnunet-service-datastore.c:1547 +#: src/datastore/gnunet-service-datastore.c:1499 msgid "# quota" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1549 +#: src/datastore/gnunet-service-datastore.c:1501 msgid "# cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1562 +#: src/datastore/gnunet-service-datastore.c:1514 #, c-format msgid "Could not use specified filename `%s' for bloomfilter.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1580 -#: src/datastore/gnunet-service-datastore.c:1596 +#: src/datastore/gnunet-service-datastore.c:1532 +#: src/datastore/gnunet-service-datastore.c:1548 #, fuzzy, c-format msgid "Failed to remove bogus bloomfilter file `%s'\n" msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':" -#: src/datastore/gnunet-service-datastore.c:1626 +#: src/datastore/gnunet-service-datastore.c:1578 #, fuzzy msgid "Failed to initialize bloomfilter.\n" msgstr "SQLite Datenbank konnte nicht initialisiert werden.\n" -#: src/datastore/gnunet-service-datastore.c:1655 +#: src/datastore/gnunet-service-datastore.c:1607 msgid "Rebuilding bloomfilter. Please be patient.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1660 +#: src/datastore/gnunet-service-datastore.c:1612 msgid "Plugin does not support get_keys function. Please fix!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1663 +#: src/datastore/gnunet-service-datastore.c:1615 msgid "Bloomfilter construction complete.\n" msgstr "" -#: src/datastore/plugin_datastore_mysql.c:529 -#: src/datastore/plugin_datastore_mysql.c:1336 +#: src/datastore/plugin_datastore_mysql.c:780 #, fuzzy, c-format msgid "Failed to prepare statement `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/datastore/plugin_datastore_mysql.c:622 -#: src/datastore/plugin_datastore_mysql.c:1346 +#: src/datastore/plugin_datastore_mysql.c:788 #, fuzzy, c-format msgid "`%s' for `%s' failed at %s:%d with error: %s\n" msgstr "`%s' an `%s' schlug fehl bei %s:%d mit dem Fehler: %s\n" -#: src/datastore/plugin_datastore_mysql.c:1581 +#: src/datastore/plugin_datastore_mysql.c:1019 msgid "Mysql database running\n" msgstr "" -#: src/datastore/plugin_datastore_postgres.c:173 -#, fuzzy, c-format -msgid "Unable to initialize Postgres with configuration `%s': %s" -msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':" +#: src/datastore/plugin_datastore_postgres.c:824 +#, fuzzy +msgid "Failed to drop table from database.\n" +msgstr "" +"\n" +"Fehler beim Empfangen der Antwort von gnunetd.\n" -#: src/datastore/plugin_datastore_postgres.c:1017 +#: src/datastore/plugin_datastore_postgres.c:860 msgid "Postgres database running\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:61 +#: src/datastore/plugin_datastore_sqlite.c:57 #, fuzzy, c-format msgid "`%s' failed at %s:%u with error: %s" msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#: src/datastore/plugin_datastore_sqlite.c:239 -#: src/namestore/plugin_namestore_sqlite.c:223 +#: src/datastore/plugin_datastore_sqlite.c:233 +#: src/namestore/plugin_namestore_sqlite.c:204 #, fuzzy, c-format msgid "Option `%s' in section `%s' missing in configuration!\n" msgstr "In der Konfigurationsdatei wurden keine Anwendungen definiert!\n" -#: src/datastore/plugin_datastore_sqlite.c:266 -#: src/namestore/plugin_namestore_sqlite.c:248 +#: src/datastore/plugin_datastore_sqlite.c:260 +#: src/namestore/plugin_namestore_sqlite.c:229 #, c-format msgid "Unable to initialize SQLite: %s.\n" msgstr "SQLite Datenbank konnte nicht initialisiert werden: %s.\n" -#: src/datastore/plugin_datastore_sqlite.c:669 +#: src/datastore/plugin_datastore_sqlite.c:655 #, fuzzy msgid "Invalid data in database. Trying to fix (by deletion).\n" msgstr "UngĂźltige Daten in %s. Korrektur wird versucht (durch LĂśschung).\n" -#: src/datastore/plugin_datastore_sqlite.c:1159 +#: src/datastore/plugin_datastore_sqlite.c:1139 msgid "sqlite version to old to determine size, assuming zero\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1178 +#: src/datastore/plugin_datastore_sqlite.c:1158 #, c-format msgid "" "Using sqlite page utilization to estimate payload (%llu pages of size %llu " "bytes)\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1218 -#: src/namestore/plugin_namestore_sqlite.c:779 +#: src/datastore/plugin_datastore_sqlite.c:1198 +#: src/namestore/plugin_namestore_sqlite.c:829 #, fuzzy msgid "Sqlite database running\n" msgstr "sqlite Datenspeicher" @@ -1201,33 +1211,32 @@ msgstr "sqlite Datenspeicher" msgid "Template database running\n" msgstr "" -#: src/dht/dht_api.c:280 +#: src/dht/dht_api.c:348 #, fuzzy msgid "Failed to connect to the DHT service!\n" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-put.c:172 -#: src/gns/gnunet-gns-lookup.c:179 +#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-monitor.c:293 +#: src/dht/gnunet-dht-put.c:192 msgid "the query key" msgstr "" -#: src/dht/gnunet-dht-get.c:204 src/gns/gnunet-gns-lookup.c:182 +#: src/dht/gnunet-dht-get.c:204 msgid "how many parallel requests (replicas) to create" msgstr "" -#: src/dht/gnunet-dht-get.c:207 src/gns/gnunet-gns-lookup.c:185 +#: src/dht/gnunet-dht-get.c:207 src/dht/gnunet-dht-monitor.c:296 msgid "the type of data to look for" msgstr "" -#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:181 -#: src/gns/gnunet-gns-lookup.c:188 +#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:201 msgid "how long to execute this query before giving up?" msgstr "" -#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-put.c:184 -#: src/fs/gnunet-download.c:270 src/fs/gnunet-publish.c:725 -#: src/fs/gnunet-search.c:297 src/fs/gnunet-unindex.c:169 -#: src/gns/gnunet-gns-lookup.c:191 src/nse/gnunet-nse-profiler.c:908 +#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-monitor.c:302 +#: src/dht/gnunet-dht-put.c:204 src/fs/gnunet-download.c:271 +#: src/fs/gnunet-publish.c:731 src/fs/gnunet-search.c:297 +#: src/fs/gnunet-unindex.c:169 src/nse/gnunet-nse-profiler.c:910 msgid "be verbose (print progress information)" msgstr "" @@ -1235,100 +1244,117 @@ msgstr "" msgid "Issue a GET request to the GNUnet DHT, prints results." msgstr "" -#: src/dht/gnunet-dht-put.c:100 +#: src/dht/gnunet-dht-monitor.c:299 +msgid "how long to execute? 0 = forever" +msgstr "" + +#: src/dht/gnunet-dht-monitor.c:321 +msgid "Prints all packets that go through the DHT." +msgstr "" + +#: src/dht/gnunet-dht-put.c:108 #, fuzzy msgid "PUT request sent!\n" msgstr "# gap Anfragen insgesamt empfangen" -#: src/dht/gnunet-dht-put.c:124 +#: src/dht/gnunet-dht-put.c:111 +msgid "Timeout sending PUT request!\n" +msgstr "" + +#: src/dht/gnunet-dht-put.c:114 +#, fuzzy +msgid "PUT request not confirmed!\n" +msgstr "# gap Anfragen insgesamt empfangen" + +#: src/dht/gnunet-dht-put.c:144 msgid "Must provide KEY and DATA for DHT put!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:132 +#: src/dht/gnunet-dht-put.c:152 #, fuzzy, c-format msgid "Could not connect to %s service!\n" msgstr "Verbindung zu gnunetd konnte nicht hergestellt werden.\n" -#: src/dht/gnunet-dht-put.c:137 +#: src/dht/gnunet-dht-put.c:157 #, fuzzy, c-format msgid "Connected to %s service!\n" msgstr "`%s' hat sich mit `%s' verbunden.\n" -#: src/dht/gnunet-dht-put.c:152 +#: src/dht/gnunet-dht-put.c:172 #, c-format msgid "Issuing put request for `%s' with data `%s'!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:166 +#: src/dht/gnunet-dht-put.c:186 msgid "the data to insert under the key" msgstr "" -#: src/dht/gnunet-dht-put.c:169 +#: src/dht/gnunet-dht-put.c:189 msgid "how long to store this entry in the dht (in seconds)" msgstr "" -#: src/dht/gnunet-dht-put.c:175 +#: src/dht/gnunet-dht-put.c:195 msgid "how many replicas to create" msgstr "" -#: src/dht/gnunet-dht-put.c:178 +#: src/dht/gnunet-dht-put.c:198 msgid "the type to insert data as" msgstr "" -#: src/dht/gnunet-dht-put.c:203 +#: src/dht/gnunet-dht-put.c:223 msgid "Issue a PUT request to the GNUnet DHT insert DATA under KEY." msgstr "" -#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:556 -#: src/testing/testing.c:1979 src/testing/testing.c:2009 +#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:544 +#: src/testing/testing.c:1968 src/testing/testing.c:1998 #, fuzzy msgid "Failed to connect to transport service!\n" msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n" -#: src/dht/gnunet-service-dht_clients.c:371 +#: src/dht/gnunet-service-dht_clients.c:407 #, fuzzy msgid "# GET requests from clients injected" msgstr "# Client Trace-Anfragen empfangen" -#: src/dht/gnunet-service-dht_clients.c:462 +#: src/dht/gnunet-service-dht_clients.c:500 #, fuzzy msgid "# PUT requests received from clients" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/dht/gnunet-service-dht_clients.c:529 +#: src/dht/gnunet-service-dht_clients.c:584 #, fuzzy msgid "# GET requests received from clients" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/dht/gnunet-service-dht_clients.c:624 +#: src/dht/gnunet-service-dht_clients.c:682 #, fuzzy msgid "# GET STOP requests received from clients" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/dht/gnunet-service-dht_clients.c:854 +#: src/dht/gnunet-service-dht_clients.c:919 msgid "# Key match, type mismatches in REPLY to CLIENT" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:869 +#: src/dht/gnunet-service-dht_clients.c:932 msgid "# Duplicate REPLIES to CLIENT request dropped" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:906 +#: src/dht/gnunet-service-dht_clients.c:967 #, fuzzy, c-format msgid "Unsupported block type (%u) in request!\n" msgstr "UngĂźltige Nachricht des Typs %u empfangen. Nachricht wird verworfen.\n" -#: src/dht/gnunet-service-dht_clients.c:928 +#: src/dht/gnunet-service-dht_clients.c:989 #, fuzzy msgid "# RESULTS queued for clients" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/dht/gnunet-service-dht_clients.c:979 -#: src/dht/gnunet-service-dht_clients.c:1022 +#: src/dht/gnunet-service-dht_clients.c:1038 +#: src/dht/gnunet-service-dht_clients.c:1081 msgid "# REPLIES ignored for CLIENTS (no match)" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:989 +#: src/dht/gnunet-service-dht_clients.c:1048 #, fuzzy msgid "Could not pass reply to client, message too big!\n" msgstr "'join' Nachricht konnte nicht an gnunetd gesendet werden.\n" @@ -1342,28 +1368,28 @@ msgstr "# Bytes empfangen Ăźber TCP" msgid "# ITEMS stored in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:209 +#: src/dht/gnunet-service-dht_datacache.c:207 msgid "# Good RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:220 +#: src/dht/gnunet-service-dht_datacache.c:218 msgid "# Duplicate RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:226 +#: src/dht/gnunet-service-dht_datacache.c:224 msgid "# Invalid RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:238 +#: src/dht/gnunet-service-dht_datacache.c:236 msgid "# Unsupported RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:241 +#: src/dht/gnunet-service-dht_datacache.c:239 #, c-format msgid "Unsupported block type (%u) in local response!\n" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:271 +#: src/dht/gnunet-service-dht_datacache.c:269 #, fuzzy msgid "# GET requests given to datacache" msgstr "# Client Trace-Anfragen empfangen" @@ -1377,97 +1403,91 @@ msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" msgid "# Preference updates given to core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:573 +#: src/dht/gnunet-service-dht_neighbours.c:571 #, fuzzy msgid "# FIND PEER messages initiated" msgstr "# PING Nachrichten erstellt" -#: src/dht/gnunet-service-dht_neighbours.c:629 -#: src/dht/gnunet-service-dht_neighbours.c:689 -#, fuzzy -msgid "# Peers connected" -msgstr "# verbundener Knoten" - -#: src/dht/gnunet-service-dht_neighbours.c:723 +#: src/dht/gnunet-service-dht_neighbours.c:717 #, fuzzy msgid "# Queued messages discarded (peer disconnected)" msgstr "# defragmentierter Nachrichten" -#: src/dht/gnunet-service-dht_neighbours.c:778 +#: src/dht/gnunet-service-dht_neighbours.c:772 #, fuzzy msgid "# Bytes transmitted to other peers" msgstr "# Bytes des Typs %d Ăźbertragen" -#: src/dht/gnunet-service-dht_neighbours.c:816 +#: src/dht/gnunet-service-dht_neighbours.c:810 #, fuzzy msgid "# Bytes of bandwdith requested from core" msgstr "# Client Trace-Anfragen empfangen" -#: src/dht/gnunet-service-dht_neighbours.c:1040 -#: src/dht/gnunet-service-dht_neighbours.c:1068 +#: src/dht/gnunet-service-dht_neighbours.c:1032 +#: src/dht/gnunet-service-dht_neighbours.c:1060 msgid "# Peers excluded from routing due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1049 -#: src/dht/gnunet-service-dht_neighbours.c:1085 +#: src/dht/gnunet-service-dht_neighbours.c:1041 +#: src/dht/gnunet-service-dht_neighbours.c:1075 #, fuzzy msgid "# Peer selection failed" msgstr " Verbindung fehlgeschlagen\n" -#: src/dht/gnunet-service-dht_neighbours.c:1221 +#: src/dht/gnunet-service-dht_neighbours.c:1207 #, fuzzy msgid "# PUT requests routed" msgstr "# dht Anfragen weitergeleitet" -#: src/dht/gnunet-service-dht_neighbours.c:1252 +#: src/dht/gnunet-service-dht_neighbours.c:1236 #, fuzzy msgid "# PUT messages queued for transmission" msgstr "# PING Nachrichten erstellt" -#: src/dht/gnunet-service-dht_neighbours.c:1333 +#: src/dht/gnunet-service-dht_neighbours.c:1315 #, fuzzy msgid "# GET requests routed" msgstr "# dht Anfragen weitergeleitet" -#: src/dht/gnunet-service-dht_neighbours.c:1364 +#: src/dht/gnunet-service-dht_neighbours.c:1342 #, fuzzy msgid "# GET messages queued for transmission" msgstr "# PING Nachrichten erstellt" -#: src/dht/gnunet-service-dht_neighbours.c:1467 +#: src/dht/gnunet-service-dht_neighbours.c:1443 #, fuzzy msgid "# RESULT messages queued for transmission" msgstr "# PING Nachrichten erstellt" -#: src/dht/gnunet-service-dht_neighbours.c:1555 +#: src/dht/gnunet-service-dht_neighbours.c:1531 #, fuzzy msgid "# P2P PUT requests received" msgstr "# Client Trace-Anfragen empfangen" -#: src/dht/gnunet-service-dht_neighbours.c:1668 +#: src/dht/gnunet-service-dht_neighbours.c:1647 msgid "# FIND PEER requests ignored due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1676 +#: src/dht/gnunet-service-dht_neighbours.c:1655 msgid "# FIND PEER requests ignored due to lack of HELLO" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1767 +#: src/dht/gnunet-service-dht_neighbours.c:1746 #, fuzzy msgid "# P2P GET requests received" msgstr "# Client Trace-Anfragen empfangen" -#: src/dht/gnunet-service-dht_neighbours.c:1811 +#: src/dht/gnunet-service-dht_neighbours.c:1788 #, fuzzy msgid "# P2P FIND PEER requests processed" msgstr "# Client Trace-Anfragen empfangen" -#: src/dht/gnunet-service-dht_neighbours.c:1825 +#: src/dht/gnunet-service-dht_neighbours.c:1802 #, fuzzy msgid "# P2P GET requests ONLY routed" msgstr "# dht Anfragen weitergeleitet" -#: src/dht/gnunet-service-dht_neighbours.c:1895 +#: src/dht/gnunet-service-dht_neighbours.c:1876 #, fuzzy msgid "# P2P RESULTS received" msgstr "# Bytes empfangen Ăźber TCP" @@ -1489,29 +1509,28 @@ msgstr "" msgid "# Invalid REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:236 +#: src/dht/gnunet-service-dht_routing.c:238 msgid "# Unsupported REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:314 -#: src/dht/gnunet-service-dht_routing.c:368 +#: src/dht/gnunet-service-dht_routing.c:311 msgid "# Entries removed from routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:324 +#: src/dht/gnunet-service-dht_routing.c:352 msgid "# Entries added to routing table" msgstr "" -#: src/dht/plugin_block_dht.c:124 +#: src/dht/plugin_block_dht.c:136 #, fuzzy, c-format msgid "Block not of type %u\n" msgstr "Kein Transport des Typs %d bekannt.\n" -#: src/dht/plugin_block_dht.c:131 +#: src/dht/plugin_block_dht.c:143 msgid "Size mismatch for block\n" msgstr "" -#: src/dht/plugin_block_dht.c:140 +#: src/dht/plugin_block_dht.c:152 #, c-format msgid "Block of type %u is malformed\n" msgstr "" @@ -1540,68 +1559,69 @@ msgstr "" msgid "Change DNS replies to point elsewhere." msgstr "" -#: src/dns/gnunet-service-dns.c:480 +#: src/dns/gnunet-service-dns.c:485 #, fuzzy, c-format msgid "Could not bind to any port: %s\n" msgstr "IP des Hosts `%s' konnte nicht ermittelt werden: %s\n" -#: src/dns/gnunet-service-dns.c:634 +#: src/dns/gnunet-service-dns.c:639 msgid "# DNS requests answered via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:818 +#: src/dns/gnunet-service-dns.c:822 msgid "# DNS exit failed (failed to open socket)" msgstr "" -#: src/dns/gnunet-service-dns.c:1001 +#: src/dns/gnunet-service-dns.c:1005 #, c-format msgid "Received DNS response that is too small (%u bytes)" msgstr "" -#: src/dns/gnunet-service-dns.c:1046 +#: src/dns/gnunet-service-dns.c:1050 msgid "# External DNS response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1165 +#: src/dns/gnunet-service-dns.c:1168 msgid "# Client response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1198 -msgid "Changing DNS reply according to client specifications\n" -msgstr "" - -#: src/dns/gnunet-service-dns.c:1279 +#: src/dns/gnunet-service-dns.c:1281 msgid "Received malformed IPv4-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1294 +#: src/dns/gnunet-service-dns.c:1297 msgid "Received malformed IPv6-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1303 +#: src/dns/gnunet-service-dns.c:1306 #, c-format msgid "Got non-IP packet with %u bytes and protocol %u from TUN\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1312 +#: src/dns/gnunet-service-dns.c:1315 msgid "# Non-DNS UDP packet received via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:1377 +#: src/dns/gnunet-service-dns.c:1380 #, fuzzy msgid "# DNS requests received via TUN interface" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/dns/gnunet-service-dns.c:1461 +#: src/dns/gnunet-service-dns.c:1465 #, c-format msgid "Configured DNS exit `%s' is not working / valid.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1493 src/exit/gnunet-daemon-exit.c:2673 +#: src/dns/gnunet-service-dns.c:1497 src/exit/gnunet-daemon-exit.c:2674 msgid "# Inbound MESH tunnels created" msgstr "" -#: src/dns/gnunet-service-dns.c:1567 +#: src/dns/gnunet-service-dns.c:1561 src/exit/gnunet-daemon-exit.c:3032 +#, c-format +msgid "`%s' must be installed SUID, refusing to run\n" +msgstr "" + +#: src/dns/gnunet-service-dns.c:1581 msgid "Configured to provide DNS exit, but no valid DNS server configured!\n" msgstr "" @@ -1625,15 +1645,15 @@ msgstr "" msgid "# Bytes transmitted via mesh tunnels" msgstr "# Bytes des Typs %d Ăźbertragen" -#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2068 -#: src/exit/gnunet-daemon-exit.c:2318 src/vpn/gnunet-service-vpn.c:1388 -#: src/vpn/gnunet-service-vpn.c:1788 src/vpn/gnunet-service-vpn.c:1951 +#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2069 +#: src/exit/gnunet-daemon-exit.c:2319 src/vpn/gnunet-service-vpn.c:1394 +#: src/vpn/gnunet-service-vpn.c:1795 src/vpn/gnunet-service-vpn.c:1958 msgid "# ICMPv4 packets dropped (type not allowed)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2127 -#: src/exit/gnunet-daemon-exit.c:2377 src/vpn/gnunet-service-vpn.c:1444 -#: src/vpn/gnunet-service-vpn.c:1847 src/vpn/gnunet-service-vpn.c:1984 +#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2128 +#: src/exit/gnunet-daemon-exit.c:2378 src/vpn/gnunet-service-vpn.c:1450 +#: src/vpn/gnunet-service-vpn.c:1854 src/vpn/gnunet-service-vpn.c:1991 msgid "# ICMPv6 packets dropped (type not allowed)" msgstr "" @@ -1682,138 +1702,138 @@ msgstr "" msgid "Packet from unknown protocol %u received. Ignored.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1470 +#: src/exit/gnunet-daemon-exit.c:1471 #, fuzzy msgid "# TCP packets sent via TUN" msgstr "# Bytes gesendet Ăźber UDP" -#: src/exit/gnunet-daemon-exit.c:1570 +#: src/exit/gnunet-daemon-exit.c:1571 #, fuzzy msgid "# TCP service creation requests received via mesh" msgstr "# Client Trace-Anfragen empfangen" -#: src/exit/gnunet-daemon-exit.c:1573 src/exit/gnunet-daemon-exit.c:1652 -#: src/exit/gnunet-daemon-exit.c:1762 src/exit/gnunet-daemon-exit.c:1992 -#: src/exit/gnunet-daemon-exit.c:2234 src/exit/gnunet-daemon-exit.c:2515 -#: src/exit/gnunet-daemon-exit.c:2615 +#: src/exit/gnunet-daemon-exit.c:1574 src/exit/gnunet-daemon-exit.c:1653 +#: src/exit/gnunet-daemon-exit.c:1763 src/exit/gnunet-daemon-exit.c:1993 +#: src/exit/gnunet-daemon-exit.c:2235 src/exit/gnunet-daemon-exit.c:2516 +#: src/exit/gnunet-daemon-exit.c:2616 #, fuzzy msgid "# Bytes received from MESH" msgstr "# Bytes empfangen Ăźber HTTP" -#: src/exit/gnunet-daemon-exit.c:1606 src/exit/gnunet-daemon-exit.c:2637 +#: src/exit/gnunet-daemon-exit.c:1607 src/exit/gnunet-daemon-exit.c:2638 #, c-format msgid "No service found for %s on port %d!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1610 +#: src/exit/gnunet-daemon-exit.c:1611 #, fuzzy msgid "# TCP requests dropped (no such service)" msgstr "# gap Anfragen verworfen: Kollision in RT" -#: src/exit/gnunet-daemon-exit.c:1655 +#: src/exit/gnunet-daemon-exit.c:1656 #, fuzzy msgid "# TCP IP-exit creation requests received via mesh" msgstr "# Client Trace-Anfragen empfangen" -#: src/exit/gnunet-daemon-exit.c:1765 +#: src/exit/gnunet-daemon-exit.c:1766 #, fuzzy msgid "# TCP data requests received via mesh" msgstr "# Client Trace-Anfragen empfangen" -#: src/exit/gnunet-daemon-exit.c:1779 +#: src/exit/gnunet-daemon-exit.c:1780 #, fuzzy msgid "# TCP DATA requests dropped (no session)" msgstr "# gap Anfragen verworfen: Kollision in RT" -#: src/exit/gnunet-daemon-exit.c:1829 +#: src/exit/gnunet-daemon-exit.c:1830 #, fuzzy msgid "# ICMP packets sent via TUN" msgstr "# Bytes gesendet Ăźber UDP" -#: src/exit/gnunet-daemon-exit.c:1995 +#: src/exit/gnunet-daemon-exit.c:1996 #, fuzzy msgid "# ICMP IP-exit requests received via mesh" msgstr "# Client Trace-Anfragen empfangen" -#: src/exit/gnunet-daemon-exit.c:2237 +#: src/exit/gnunet-daemon-exit.c:2238 #, fuzzy msgid "# ICMP service requests received via mesh" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/exit/gnunet-daemon-exit.c:2303 src/vpn/gnunet-service-vpn.c:1378 -#: src/vpn/gnunet-service-vpn.c:1945 +#: src/exit/gnunet-daemon-exit.c:2304 src/vpn/gnunet-service-vpn.c:1384 +#: src/vpn/gnunet-service-vpn.c:1952 msgid "# ICMPv4 packets dropped (impossible PT to v6)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2362 src/vpn/gnunet-service-vpn.c:1414 -#: src/vpn/gnunet-service-vpn.c:1426 src/vpn/gnunet-service-vpn.c:1835 +#: src/exit/gnunet-daemon-exit.c:2363 src/vpn/gnunet-service-vpn.c:1420 +#: src/vpn/gnunet-service-vpn.c:1432 src/vpn/gnunet-service-vpn.c:1842 msgid "# ICMPv6 packets dropped (impossible PT to v4)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2412 +#: src/exit/gnunet-daemon-exit.c:2413 #, fuzzy msgid "# UDP packets sent via TUN" msgstr "# Bytes gesendet Ăźber UDP" -#: src/exit/gnunet-daemon-exit.c:2518 +#: src/exit/gnunet-daemon-exit.c:2519 #, fuzzy msgid "# UDP IP-exit requests received via mesh" msgstr "# Client Trace-Anfragen empfangen" -#: src/exit/gnunet-daemon-exit.c:2618 +#: src/exit/gnunet-daemon-exit.c:2619 #, fuzzy msgid "# UDP service requests received via mesh" msgstr "# Client Trace-Anfragen empfangen" -#: src/exit/gnunet-daemon-exit.c:2641 +#: src/exit/gnunet-daemon-exit.c:2642 #, fuzzy msgid "# UDP requests dropped (no such service)" msgstr "# gap Anfragen verworfen: Kollision in RT" -#: src/exit/gnunet-daemon-exit.c:2881 +#: src/exit/gnunet-daemon-exit.c:2882 #, c-format msgid "No addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2895 src/exit/gnunet-daemon-exit.c:2907 +#: src/exit/gnunet-daemon-exit.c:2896 src/exit/gnunet-daemon-exit.c:2908 #, c-format msgid "Service `%s' configured for IPv4, but IPv4 is disabled!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2918 +#: src/exit/gnunet-daemon-exit.c:2919 #, c-format msgid "No IP addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3047 +#: src/exit/gnunet-daemon-exit.c:3048 msgid "" "This system does not support IPv4, will disable IPv4 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3055 +#: src/exit/gnunet-daemon-exit.c:3056 msgid "" "This system does not support IPv6, will disable IPv6 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3062 +#: src/exit/gnunet-daemon-exit.c:3063 msgid "" "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use " "ENABLE_IPv4=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3068 +#: src/exit/gnunet-daemon-exit.c:3069 msgid "" "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use " "ENABLE_IPv6=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3074 src/pt/gnunet-daemon-pt.c:884 +#: src/exit/gnunet-daemon-exit.c:3075 src/pt/gnunet-daemon-pt.c:884 msgid "No useful service enabled. Exiting.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3235 +#: src/exit/gnunet-daemon-exit.c:3236 msgid "Daemon to run to provide an IP exit node for the VPN" msgstr "" @@ -1821,122 +1841,127 @@ msgstr "" msgid "# acknowledgements sent for fragment" msgstr "" -#: src/fragmentation/defragmentation.c:454 +#: src/fragmentation/defragmentation.c:456 #, fuzzy msgid "# fragments received" msgstr "# verworfener Nachrichten" -#: src/fragmentation/defragmentation.c:513 +#: src/fragmentation/defragmentation.c:521 #, fuzzy msgid "# duplicate fragments received" msgstr "# Bytes empfangen Ăźber TCP" -#: src/fragmentation/defragmentation.c:526 +#: src/fragmentation/defragmentation.c:534 msgid "# messages defragmented" msgstr "# defragmentierter Nachrichten" -#: src/fragmentation/fragmentation.c:188 +#: src/fragmentation/fragmentation.c:203 #, fuzzy msgid "# fragments transmitted" msgstr "# Selbstbekanntmachungen Ăźbertragen" -#: src/fragmentation/fragmentation.c:191 +#: src/fragmentation/fragmentation.c:206 #, fuzzy msgid "# fragments retransmitted" msgstr "# Selbstbekanntmachungen Ăźbertragen" -#: src/fragmentation/fragmentation.c:255 +#: src/fragmentation/fragmentation.c:232 +#, fuzzy +msgid "# fragments wrap arounds" +msgstr "# Selbstbekanntmachungen Ăźbertragen" + +#: src/fragmentation/fragmentation.c:273 msgid "# messages fragmented" msgstr "# fragmentierter Nachrichten" -#: src/fragmentation/fragmentation.c:258 +#: src/fragmentation/fragmentation.c:276 msgid "# total size of fragmented messages" msgstr "" -#: src/fragmentation/fragmentation.c:343 +#: src/fragmentation/fragmentation.c:363 #, fuzzy msgid "# fragment acknowledgements received" msgstr "# KnotenankĂźndigungen empfangen" -#: src/fragmentation/fragmentation.c:349 +#: src/fragmentation/fragmentation.c:369 msgid "# bits removed from fragmentation ACKs" msgstr "" -#: src/fragmentation/fragmentation.c:373 +#: src/fragmentation/fragmentation.c:393 #, fuzzy msgid "# fragmentation transmissions completed" msgstr "# Klartext PONG Nachrichten empfangen" -#: src/fs/fs_api.c:284 +#: src/fs/fs_api.c:339 #, fuzzy, c-format msgid "Could not open file `%s': %s" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_api.c:293 +#: src/fs/fs_api.c:348 #, fuzzy, c-format msgid "Could not read file `%s': %s" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_api.c:299 +#: src/fs/fs_api.c:354 #, c-format msgid "Short read reading from file `%s'!" msgstr "" -#: src/fs/fs_api.c:877 +#: src/fs/fs_api.c:938 #, fuzzy, c-format msgid "Failed to resume publishing information `%s': %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_api.c:1334 +#: src/fs/fs_api.c:1395 #, c-format msgid "Failed to recover namespace `%s', cannot resume publishing operation.\n" msgstr "" -#: src/fs/fs_api.c:1376 +#: src/fs/fs_api.c:1437 #, c-format msgid "Failure while resuming publishing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:1392 +#: src/fs/fs_api.c:1453 #, fuzzy, c-format msgid "Failed to resume publishing operation `%s': %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_api.c:2004 +#: src/fs/fs_api.c:2106 #, c-format msgid "Failure while resuming unindexing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2014 +#: src/fs/fs_api.c:2116 #, fuzzy, c-format msgid "Failed to resume unindexing operation `%s': %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_api.c:2139 src/fs/fs_api.c:2378 +#: src/fs/fs_api.c:2241 src/fs/fs_api.c:2480 #, fuzzy, c-format msgid "Failed to resume sub-download `%s': %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_api.c:2156 +#: src/fs/fs_api.c:2258 #, fuzzy, c-format msgid "Failed to resume sub-search `%s': %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_api.c:2168 src/fs/fs_api.c:2187 src/fs/fs_api.c:2671 +#: src/fs/fs_api.c:2270 src/fs/fs_api.c:2289 src/fs/fs_api.c:2773 #, c-format msgid "Failure while resuming search operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2369 +#: src/fs/fs_api.c:2471 #, c-format msgid "Failed to resume sub-download `%s': could not open file `%s'\n" msgstr "" -#: src/fs/fs_api.c:2615 +#: src/fs/fs_api.c:2717 msgid "Could not resume running search, will resume as paused search\n" msgstr "" -#: src/fs/fs_api.c:2709 +#: src/fs/fs_api.c:2811 #, c-format msgid "Failure while resuming download operation `%s': %s\n" msgstr "" @@ -1946,54 +1971,59 @@ msgstr "" msgid "MAGIC mismatch. This is not a GNUnet directory.\n" msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" -#: src/fs/fs_download.c:310 +#: src/fs/fs_download.c:311 #, fuzzy msgid "" "Recursive downloads of directories larger than 4 GB are not supported on 32-" "bit systems\n" msgstr "Rekursiver Download des Verzeichnisses `%s' bei %llu von %llu Bytes.\n" -#: src/fs/fs_download.c:330 +#: src/fs/fs_download.c:331 msgid "Directory too large for system address space\n" msgstr "" -#: src/fs/fs_download.c:488 src/fs/fs_download.c:500 +#: src/fs/fs_download.c:497 src/fs/fs_download.c:509 #, fuzzy, c-format msgid "Failed to open file `%s' for writing" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_download.c:870 +#: src/fs/fs_download.c:878 #, fuzzy, c-format msgid "Failed to create directory for recursive download of `%s'\n" msgstr "Fehler beim Aktualisieren der Daten des Moduls `%s'\n" -#: src/fs/fs_download.c:951 +#: src/fs/fs_download.c:960 #, c-format msgid "" "Internal error or bogus download URI (expected %u bytes at depth %u and " -"offset %llu/%llu, got %u bytes)\n" +"offset %llu/%llu, got %u bytes)" msgstr "" -#: src/fs/fs_download.c:977 +#: src/fs/fs_download.c:986 msgid "internal error decrypting content" msgstr "" -#: src/fs/fs_download.c:1000 +#: src/fs/fs_download.c:1009 #, fuzzy, c-format -msgid "Download failed: could not open file `%s': %s\n" +msgid "Download failed: could not open file `%s': %s" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_download.c:1010 +#: src/fs/fs_download.c:1019 #, fuzzy, c-format -msgid "Failed to seek to offset %llu in file `%s': %s\n" +msgid "Failed to seek to offset %llu in file `%s': %s" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/fs_download.c:1019 -#, c-format -msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s\n" -msgstr "" +#: src/fs/fs_download.c:1028 +#, fuzzy, c-format +msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s" +msgstr "Datei wurde als `%s' gespeichert.\n" + +#: src/fs/fs_download.c:1125 +#, fuzzy +msgid "internal error decoding tree" +msgstr "=\tFehler beim Lesen des Verzeichnisses.\n" -#: src/fs/fs_download.c:1835 +#: src/fs/fs_download.c:1888 #, fuzzy msgid "Invalid URI" msgstr "UngĂźltiger Parameter: `%s'\n" @@ -2079,69 +2109,69 @@ msgstr "Unbekannter Fehler.\n" msgid "Failed to connect to datastore." msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden." -#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:395 +#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:397 #, fuzzy, c-format msgid "Publishing failed: %s" msgstr "" "\n" "Fehler beim Uploaden der Datei: %s\n" -#: src/fs/fs_publish.c:616 src/fs/fs_publish.c:633 src/fs/fs_publish.c:672 -#: src/fs/fs_publish.c:692 src/fs/fs_publish.c:717 src/fs/fs_publish.c:857 +#: src/fs/fs_publish.c:621 src/fs/fs_publish.c:638 src/fs/fs_publish.c:677 +#: src/fs/fs_publish.c:697 src/fs/fs_publish.c:722 src/fs/fs_publish.c:862 #, fuzzy, c-format msgid "Can not index file `%s': %s. Will try to insert instead.\n" msgstr "Indizieren der Datei `%s' schlug fehl. Versuch Datei einzufĂźgen...\n" -#: src/fs/fs_publish.c:618 +#: src/fs/fs_publish.c:623 msgid "timeout on index-start request to `fs' service" msgstr "" -#: src/fs/fs_publish.c:630 +#: src/fs/fs_publish.c:635 #, fuzzy msgid "unknown error" msgstr "Unbekannter Fehler" -#: src/fs/fs_publish.c:673 +#: src/fs/fs_publish.c:678 msgid "failed to compute hash" msgstr "" -#: src/fs/fs_publish.c:693 +#: src/fs/fs_publish.c:698 msgid "filename too long" msgstr "" -#: src/fs/fs_publish.c:718 +#: src/fs/fs_publish.c:723 #, fuzzy msgid "could not connect to `fs' service" msgstr "Verbindung zu gnunetd konnte nicht hergestellt werden.\n" -#: src/fs/fs_publish.c:741 +#: src/fs/fs_publish.c:746 #, fuzzy, c-format msgid "Failed to get file identifiers for `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/fs/fs_publish.c:806 +#: src/fs/fs_publish.c:811 #, fuzzy, c-format msgid "Recursive upload failed at `%s': %s" msgstr "`%s' schlug fehl bei %s:%d mit dem Fehler: `%s'.\n" -#: src/fs/fs_publish.c:812 +#: src/fs/fs_publish.c:817 #, fuzzy, c-format msgid "Recursive upload failed: %s" msgstr "" "\n" "Fehler beim Uploaden der Datei: %s\n" -#: src/fs/fs_publish.c:858 +#: src/fs/fs_publish.c:863 #, fuzzy msgid "needs to be an actual file" msgstr "`%s' ist keine normale Datei.\n" -#: src/fs/fs_publish.c:1067 +#: src/fs/fs_publish.c:1071 #, c-format msgid "Insufficient space for publishing: %s" msgstr "" -#: src/fs/fs_publish.c:1138 +#: src/fs/fs_publish.c:1142 #, c-format msgid "Reserving space for %u entries and %llu bytes for publication\n" msgstr "" @@ -2151,7 +2181,7 @@ msgstr "" msgid "Could not connect to datastore." msgstr "Verbindung zu gnunetd konnte nicht hergestellt werden.\n" -#: src/fs/fs_search.c:810 +#: src/fs/fs_search.c:829 #, c-format msgid "Got result with unknown block type `%d', ignoring" msgstr "" @@ -2161,44 +2191,64 @@ msgstr "" msgid "Failed to start daemon: %s\n" msgstr "Fehler beim Starten der Collection.\n" -#: src/fs/fs_unindex.c:57 +#: src/fs/fs_unindex.c:58 msgid "Failed to find given position in file" msgstr "" -#: src/fs/fs_unindex.c:62 +#: src/fs/fs_unindex.c:63 #, fuzzy msgid "Failed to read file" msgstr "Zustellung der Nachricht `%s' fehlgeschlagen.\n" -#: src/fs/fs_unindex.c:231 +#: src/fs/fs_unindex.c:233 msgid "Unexpected time for a response from `fs' service." msgstr "" -#: src/fs/fs_unindex.c:239 +#: src/fs/fs_unindex.c:241 msgid "Timeout waiting for `fs' service." msgstr "" -#: src/fs/fs_unindex.c:247 +#: src/fs/fs_unindex.c:249 #, fuzzy msgid "Invalid response from `fs' service." msgstr "UngĂźltige Antwort auf `%s'.\n" -#: src/fs/fs_unindex.c:292 +#: src/fs/fs_unindex.c:293 #, fuzzy msgid "Failed to connect to FS service for unindexing." msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden." -#: src/fs/fs_unindex.c:325 +#: src/fs/fs_unindex.c:344 +#, fuzzy +msgid "Failed to get KSKs from directory scan." +msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" + +#: src/fs/fs_unindex.c:356 +#, fuzzy, c-format +msgid "Internal error scanning `%s'.\n" +msgstr "=\tFehler beim Lesen des Verzeichnisses.\n" + +#: src/fs/fs_unindex.c:411 +#, fuzzy, c-format +msgid "Failed to remove KBlock: %s\n" +msgstr "Datei wurde als `%s' gespeichert.\n" + +#: src/fs/fs_unindex.c:501 +#, fuzzy, c-format +msgid "Failed to parse URI `%s' from KBlock!\n" +msgstr "Datei `%s' hat URI: %s\n" + +#: src/fs/fs_unindex.c:553 src/fs/fs_unindex.c:618 #, fuzzy msgid "Failed to connect to `datastore' service." msgstr "`%s' Dienst konnte nicht initialisiert werden.\n" -#: src/fs/fs_unindex.c:338 +#: src/fs/fs_unindex.c:631 #, fuzzy msgid "Failed to open file for unindexing." msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden." -#: src/fs/fs_unindex.c:372 +#: src/fs/fs_unindex.c:665 #, fuzzy msgid "Failed to compute hash of file." msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden." @@ -2311,92 +2361,92 @@ msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" msgid "Display contents of a GNUnet directory" msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" -#: src/fs/gnunet-download.c:100 +#: src/fs/gnunet-download.c:101 #, fuzzy, c-format msgid "Starting download `%s'.\n" msgstr "Collection `%s' begonnen.\n" -#: src/fs/gnunet-download.c:109 +#: src/fs/gnunet-download.c:110 #, fuzzy msgid "" msgstr "Unbekannter Fehler" -#: src/fs/gnunet-download.c:118 +#: src/fs/gnunet-download.c:119 #, c-format msgid "" "Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to " "download\n" msgstr "" -#: src/fs/gnunet-download.c:128 +#: src/fs/gnunet-download.c:129 #, fuzzy, c-format msgid "Error downloading: %s.\n" msgstr "Fehler beim Download: %s\n" -#: src/fs/gnunet-download.c:136 +#: src/fs/gnunet-download.c:137 #, fuzzy, c-format msgid "Downloading `%s' done (%s/s).\n" msgstr "Upload abgewiesen!" -#: src/fs/gnunet-download.c:151 src/fs/gnunet-publish.c:190 +#: src/fs/gnunet-download.c:152 src/fs/gnunet-publish.c:190 #: src/fs/gnunet-search.c:190 src/fs/gnunet-unindex.c:109 #, c-format msgid "Unexpected status: %d\n" msgstr "" -#: src/fs/gnunet-download.c:176 +#: src/fs/gnunet-download.c:177 #, fuzzy msgid "You need to specify a URI argument.\n" msgstr "Sie mĂźssen einen Empfänger angeben!\n" -#: src/fs/gnunet-download.c:182 src/fs/gnunet-publish.c:618 +#: src/fs/gnunet-download.c:183 src/fs/gnunet-publish.c:624 #, fuzzy, c-format msgid "Failed to parse URI: %s\n" msgstr "Datei `%s' hat URI: %s\n" -#: src/fs/gnunet-download.c:189 +#: src/fs/gnunet-download.c:190 msgid "Only CHK or LOC URIs supported.\n" msgstr "" -#: src/fs/gnunet-download.c:196 +#: src/fs/gnunet-download.c:197 msgid "Target filename must be specified.\n" msgstr "" -#: src/fs/gnunet-download.c:210 src/fs/gnunet-publish.c:596 +#: src/fs/gnunet-download.c:211 src/fs/gnunet-publish.c:602 #: src/fs/gnunet-search.c:241 src/fs/gnunet-unindex.c:141 #, fuzzy, c-format msgid "Could not initialize `%s' subsystem.\n" msgstr "`%s' Dienst konnte nicht initialisiert werden.\n" -#: src/fs/gnunet-download.c:247 src/fs/gnunet-search.c:285 +#: src/fs/gnunet-download.c:248 src/fs/gnunet-search.c:285 msgid "set the desired LEVEL of receiver-anonymity" msgstr "Den Grad LEVEL der gewĂźnschten Empfänger-Anonymität setzen" -#: src/fs/gnunet-download.c:250 +#: src/fs/gnunet-download.c:251 msgid "delete incomplete downloads (when aborted with CTRL-C)" msgstr "" -#: src/fs/gnunet-download.c:253 src/fs/gnunet-search.c:288 +#: src/fs/gnunet-download.c:254 src/fs/gnunet-search.c:288 msgid "only search the local peer (no P2P network search)" msgstr "" -#: src/fs/gnunet-download.c:256 +#: src/fs/gnunet-download.c:257 msgid "write the file to FILENAME" msgstr "Schreibe die Datei in DATEINAME" -#: src/fs/gnunet-download.c:260 +#: src/fs/gnunet-download.c:261 msgid "set the maximum number of parallel downloads that is allowed" msgstr "" -#: src/fs/gnunet-download.c:264 +#: src/fs/gnunet-download.c:265 msgid "set the maximum number of parallel requests for blocks that is allowed" msgstr "" -#: src/fs/gnunet-download.c:267 +#: src/fs/gnunet-download.c:268 msgid "download a GNUnet directory recursively" msgstr "Das GNUnet Verzeichnis rekursiv herunterladen" -#: src/fs/gnunet-download.c:277 +#: src/fs/gnunet-download.c:278 msgid "" "Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/" "chk/...)" @@ -2411,35 +2461,30 @@ msgstr "" msgid "Special file-sharing operations" msgstr "Alle Optionen anzeigen" -#: src/fs/gnunet-pseudonym.c:151 src/statistics/gnunet-statistics.c:126 +#: src/fs/gnunet-pseudonym.c:160 src/statistics/gnunet-statistics.c:167 #, fuzzy, c-format msgid "Invalid argument `%s'\n" msgstr "UngĂźltiger Parameter: `%s'\n" -#: src/fs/gnunet-pseudonym.c:165 -#, fuzzy, c-format -msgid "Namespace `%s' unknown.\n" -msgstr "Namespace `%s' hat das Rating %d.\n" - -#: src/fs/gnunet-pseudonym.c:240 src/fs/gnunet-pseudonym.c:247 -#: src/fs/gnunet-pseudonym.c:249 +#: src/fs/gnunet-pseudonym.c:250 src/fs/gnunet-pseudonym.c:257 +#: src/fs/gnunet-pseudonym.c:259 #, fuzzy, c-format msgid "Option `%s' ignored\n" msgstr "%s: Option `%s' ist mehrdeutig\n" -#: src/fs/gnunet-pseudonym.c:269 src/fs/gnunet-publish.c:672 +#: src/fs/gnunet-pseudonym.c:279 src/fs/gnunet-publish.c:678 msgid "set the desired LEVEL of sender-anonymity" msgstr "GewĂźnschten Grad an Sender-Anonymität festlegen" -#: src/fs/gnunet-pseudonym.c:272 +#: src/fs/gnunet-pseudonym.c:282 msgid "create or advertise namespace NAME" msgstr "" -#: src/fs/gnunet-pseudonym.c:275 +#: src/fs/gnunet-pseudonym.c:285 msgid "delete namespace NAME " msgstr "" -#: src/fs/gnunet-pseudonym.c:278 +#: src/fs/gnunet-pseudonym.c:288 #, fuzzy msgid "" "add an additional keyword for the advertisment (this option can be specified " @@ -2448,40 +2493,40 @@ msgstr "" "Ein zusätzliches SchlĂźsselwort fĂźr alle Dateien und Verzeichnisse hinzufĂźgen " "(diese Option kann mehrmals angegeben werden)" -#: src/fs/gnunet-pseudonym.c:282 src/fs/gnunet-publish.c:691 +#: src/fs/gnunet-pseudonym.c:292 src/fs/gnunet-publish.c:697 msgid "set the meta-data for the given TYPE to the given VALUE" msgstr "" "Die Meta-Daten des angegebenen Typs TYPE auf den angegebenen Wert VALUE " "setzen" -#: src/fs/gnunet-pseudonym.c:285 +#: src/fs/gnunet-pseudonym.c:295 #, fuzzy msgid "print names of local namespaces" msgstr "das Rating eines Namespaces setzen" -#: src/fs/gnunet-pseudonym.c:288 +#: src/fs/gnunet-pseudonym.c:298 msgid "use the given PRIORITY for the advertisments" msgstr "" -#: src/fs/gnunet-pseudonym.c:291 +#: src/fs/gnunet-pseudonym.c:301 msgid "do not print names of remote namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:294 src/fs/gnunet-publish.c:710 +#: src/fs/gnunet-pseudonym.c:304 src/fs/gnunet-publish.c:716 msgid "set the desired replication LEVEL" msgstr "" -#: src/fs/gnunet-pseudonym.c:297 +#: src/fs/gnunet-pseudonym.c:307 #, fuzzy msgid "specify ID of the root of the namespace" msgstr "das Rating eines Namespaces setzen" -#: src/fs/gnunet-pseudonym.c:300 +#: src/fs/gnunet-pseudonym.c:310 #, fuzzy msgid "change rating of namespace ID by VALUE" msgstr "das Rating eines Namespaces setzen" -#: src/fs/gnunet-pseudonym.c:308 +#: src/fs/gnunet-pseudonym.c:318 msgid "Manage GNUnet pseudonyms." msgstr "" @@ -2510,116 +2555,116 @@ msgstr "Ich bin Peer `%s'.\n" msgid "Cleanup after abort complete.\n" msgstr "`%s' Startvorgang abgeschlossen.\n" -#: src/fs/gnunet-publish.c:299 +#: src/fs/gnunet-publish.c:305 #, fuzzy, c-format msgid "Meta data for file `%s' (%s)\n" msgstr "Daten des Moduls `%s' werden aktualisiert\n" -#: src/fs/gnunet-publish.c:301 +#: src/fs/gnunet-publish.c:307 #, fuzzy, c-format msgid "Keywords for file `%s' (%s)\n" msgstr "SchlĂźsselwĂśrter fĂźr Datei `%s':\n" -#: src/fs/gnunet-publish.c:352 +#: src/fs/gnunet-publish.c:358 #, fuzzy, c-format msgid "Failed to create namespace `%s'\n" msgstr "Namespace `%s' konnte nicht erstellt werden (existiert bereits?).\n" -#: src/fs/gnunet-publish.c:427 +#: src/fs/gnunet-publish.c:433 #, fuzzy msgid "Could not publish\n" msgstr "`%s' konnte nicht aufgelĂśst werden: %s\n" -#: src/fs/gnunet-publish.c:454 +#: src/fs/gnunet-publish.c:460 #, fuzzy msgid "Could not start publishing.\n" msgstr "Anwendung `%s' konnte nicht initialisiert werden.\n" -#: src/fs/gnunet-publish.c:485 +#: src/fs/gnunet-publish.c:491 #, fuzzy, c-format msgid "Scanning directory `%s'.\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/fs/gnunet-publish.c:487 +#: src/fs/gnunet-publish.c:493 #, fuzzy, c-format msgid "Scanning file `%s'.\n" msgstr "Collection `%s' begonnen.\n" -#: src/fs/gnunet-publish.c:492 +#: src/fs/gnunet-publish.c:498 #, c-format msgid "There was trouble processing file `%s', skipping it.\n" msgstr "" -#: src/fs/gnunet-publish.c:497 +#: src/fs/gnunet-publish.c:503 #, fuzzy msgid "Preprocessing complete.\n" msgstr "GNUnet wurde erfolgreich heruntergefahren.\n" -#: src/fs/gnunet-publish.c:501 +#: src/fs/gnunet-publish.c:507 #, fuzzy, c-format msgid "Extracting meta data from file `%s' complete.\n" msgstr "Daten des Moduls `%s' werden aktualisiert\n" -#: src/fs/gnunet-publish.c:505 +#: src/fs/gnunet-publish.c:511 msgid "Meta data extraction has finished.\n" msgstr "" -#: src/fs/gnunet-publish.c:512 +#: src/fs/gnunet-publish.c:518 #, fuzzy msgid "Internal error scanning directory.\n" msgstr "=\tFehler beim Lesen des Verzeichnisses.\n" -#: src/fs/gnunet-publish.c:546 +#: src/fs/gnunet-publish.c:552 #, c-format msgid "Cannot extract metadata from a URI!\n" msgstr "" -#: src/fs/gnunet-publish.c:553 +#: src/fs/gnunet-publish.c:559 #, c-format msgid "You must specify one and only one filename for insertion.\n" msgstr "Sie dĂźrfen nur eine Datei zum Deindizieren angeben.\n" -#: src/fs/gnunet-publish.c:559 +#: src/fs/gnunet-publish.c:565 #, fuzzy, c-format msgid "You must NOT specify an URI and a filename.\n" msgstr "Sie mĂźssen einen Empfänger angeben!\n" -#: src/fs/gnunet-publish.c:567 src/vpn/gnunet-vpn.c:214 +#: src/fs/gnunet-publish.c:573 src/vpn/gnunet-vpn.c:214 #, fuzzy, c-format msgid "Option `%s' is required when using option `%s'.\n" msgstr "Option `%s' macht keinen Sinn ohne die Option `%s'.\n" -#: src/fs/gnunet-publish.c:577 src/fs/gnunet-publish.c:584 -#: src/transport/gnunet-transport.c:530 +#: src/fs/gnunet-publish.c:583 src/fs/gnunet-publish.c:590 +#: src/transport/gnunet-transport.c:560 #, c-format msgid "Option `%s' makes no sense without option `%s'.\n" msgstr "Option `%s' macht keinen Sinn ohne die Option `%s'.\n" -#: src/fs/gnunet-publish.c:606 +#: src/fs/gnunet-publish.c:612 #, fuzzy, c-format msgid "Could not create namespace `%s'\n" msgstr "Namespace `%s' konnte nicht erstellt werden (existiert bereits?).\n" -#: src/fs/gnunet-publish.c:639 +#: src/fs/gnunet-publish.c:645 #, fuzzy, c-format msgid "Failed to access `%s': %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/fs/gnunet-publish.c:651 +#: src/fs/gnunet-publish.c:657 msgid "" "Failed to start meta directory scanner. Is gnunet-helper-publish-fs " "installed?\n" msgstr "" -#: src/fs/gnunet-publish.c:676 +#: src/fs/gnunet-publish.c:682 msgid "disable adding the creation time to the metadata of the uploaded file" msgstr "" -#: src/fs/gnunet-publish.c:679 +#: src/fs/gnunet-publish.c:685 msgid "do not use libextractor to add keywords or metadata" msgstr "" -#: src/fs/gnunet-publish.c:683 +#: src/fs/gnunet-publish.c:689 msgid "" "print list of extracted keywords that would be used, but do not perform " "upload" @@ -2627,7 +2672,7 @@ msgstr "" "Liste der extrahierten SchlĂźsselworte, die verwendet werden wĂźrden, " "ausgeben, aber keinen Upload durchfĂźhren" -#: src/fs/gnunet-publish.c:687 +#: src/fs/gnunet-publish.c:693 msgid "" "add an additional keyword for the top-level file or directory (this option " "can be specified multiple times)" @@ -2635,7 +2680,7 @@ msgstr "" "Ein zusätzliches SchlĂźsselwort fĂźr die Datei oder das Verzeichnis auf der " "obersten Ebene hinzufĂźgen (diese Option kann mehrmals angegeben werden)" -#: src/fs/gnunet-publish.c:694 +#: src/fs/gnunet-publish.c:700 msgid "" "do not index, perform full insertion (stores entire file in encrypted form " "in GNUnet database)" @@ -2643,7 +2688,7 @@ msgstr "" "Nicht indizieren, sondern komplett einfĂźgen (speichert die gesamte Datei in " "verschlĂźsselter Form in der GNUnet Datenbank)" -#: src/fs/gnunet-publish.c:699 +#: src/fs/gnunet-publish.c:705 msgid "" "specify ID of an updated version to be published in the future (for " "namespace insertions only)" @@ -2651,36 +2696,36 @@ msgstr "" "ID einer aktualisierten Version angeben, die in der Zukunft verĂśffentlich " "werden soll. (nur fĂźr das EinfĂźgen in Namespaces)" -#: src/fs/gnunet-publish.c:703 +#: src/fs/gnunet-publish.c:709 msgid "specify the priority of the content" msgstr "Die Priorität des Inhalts angeben" -#: src/fs/gnunet-publish.c:707 +#: src/fs/gnunet-publish.c:713 msgid "publish the files under the pseudonym NAME (place file into namespace)" msgstr "" "Die Datei unter dem Pseudonym NAME verĂśffentlichen (platziert die Datei in " "einem Namespace)" -#: src/fs/gnunet-publish.c:713 +#: src/fs/gnunet-publish.c:719 msgid "" "only simulate the process but do not do any actual publishing (useful to " "compute URIs)" msgstr "" -#: src/fs/gnunet-publish.c:717 +#: src/fs/gnunet-publish.c:723 msgid "" "set the ID of this version of the publication (for namespace insertions only)" msgstr "" "die ID dieser Version der VerĂśffentlichung setzen (nur fĂźr das EinfĂźgen in " "Namespaces)" -#: src/fs/gnunet-publish.c:721 +#: src/fs/gnunet-publish.c:727 msgid "" "URI to be published (can be used instead of passing a file to add keywords " "to the file with the respective URI)" msgstr "" -#: src/fs/gnunet-publish.c:736 +#: src/fs/gnunet-publish.c:742 msgid "Publish a file or directory on GNUnet" msgstr "" @@ -2730,24 +2775,12 @@ msgid "# Loopback routes suppressed" msgstr "# gap Routing erfolgreich (insgesamt)" #: src/fs/gnunet-service-fs.c:581 src/hostlist/gnunet-daemon-hostlist.c:297 -#: src/topology/gnunet-daemon-topology.c:1290 -#: src/topology/gnunet-daemon-topology.c:1297 +#: src/topology/gnunet-daemon-topology.c:1330 +#: src/topology/gnunet-daemon-topology.c:1337 #, fuzzy, c-format msgid "Failed to connect to `%s' service.\n" msgstr "`%s' Dienst konnte nicht initialisiert werden.\n" -#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 -#: src/topology/gnunet-daemon-topology.c:654 -#: src/topology/gnunet-daemon-topology.c:756 -#: src/transport/gnunet-service-transport_neighbours.c:960 -#: src/transport/gnunet-service-transport_neighbours.c:1289 -#: src/transport/gnunet-service-transport_neighbours.c:1841 -#: src/transport/gnunet-service-transport_neighbours.c:2499 -#: src/transport/gnunet-service-transport_neighbours.c:2566 -#, fuzzy -msgid "# peers connected" -msgstr "# verbundener Knoten" - #: src/fs/gnunet-service-fs_cp.c:696 #, fuzzy msgid "# migration stop messages received" @@ -3101,15 +3134,134 @@ msgstr "" msgid "Reply mismatched in terms of namespace. Discarded.\n" msgstr "" -#: src/gns/gns_api.c:221 +#: src/gns/gnunet-gns.c:191 #, fuzzy -msgid "Failed to connect to the GNS service!\n" +msgid "Failed to connect to GNS\n" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/gns/gnunet-gns-lookup.c:210 -msgid "Issue a request to the GNUnet Naming System, prints results." +#: src/gns/gnunet-gns.c:232 +msgid "try to shorten a given GNS name" +msgstr "" + +#: src/gns/gnunet-gns.c:235 +msgid "Lookup a record using GNS (NOT IMPLEMENTED)" +msgstr "" + +#: src/gns/gnunet-gns.c:238 +msgid "Get the authority of a particular name" +msgstr "" + +#: src/gns/gnunet-gns.c:241 +#, fuzzy +msgid "Specify the type of the record lookup" +msgstr "Die Priorität des Inhalts angeben" + +#: src/gns/gnunet-gns.c:244 +msgid "No unneeded output" +msgstr "" + +#: src/gns/gnunet-gns.c:255 +msgid "GNUnet GNS access tool" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:280 +#, fuzzy, c-format +msgid "Unsupported form value `%s'\n" +msgstr "Kommando `%s' wird nicht unterstĂźtzt. Vorgang wird abgebrochen.\n" + +#: src/gns/gnunet-gns-fcfsd.c:333 +#, fuzzy, c-format +msgid "Failed to create record for domain `%s': %s\n" +msgstr "Konfigurationsdatei `%s' konnte nicht geparst werden.\n" + +#: src/gns/gnunet-gns-fcfsd.c:377 +#, c-format +msgid "Found existing name `%s' for the given key\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:439 +#, c-format +msgid "Found %u existing records for domain `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:498 +#, fuzzy, c-format +msgid "Failed to create page for `%s'\n" +msgstr "Namespace `%s' konnte nicht erstellt werden (existiert bereits?).\n" + +#: src/gns/gnunet-gns-fcfsd.c:514 +#, fuzzy, c-format +msgid "Failed to setup post processor for `%s'\n" +msgstr "Fehler beim Aktualisieren der Daten des Moduls `%s'\n" + +#: src/gns/gnunet-gns-fcfsd.c:725 src/gns/gnunet-gns-fcfsd.c:737 +#, fuzzy, c-format +msgid "Option `%s' not specified in configuration section `%s'\n" +msgstr "" +"Option `%s' ist in der Konfigurationsdatei in der Sektion `%s' nicht " +"gesetzt, sie wird auf %dm gesetzt.\n" + +#: src/gns/gnunet-gns-fcfsd.c:747 src/namestore/gnunet-namestore.c:299 +#, fuzzy +msgid "Failed to read or create private zone key\n" +msgstr "Fehler beim Aktualisieren der Daten des Moduls `%s'\n" + +#: src/gns/gnunet-gns-fcfsd.c:757 src/namestore/gnunet-namestore.c:310 +#, fuzzy +msgid "Failed to connect to namestore\n" +msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden." + +#: src/gns/gnunet-gns-fcfsd.c:773 src/gns/gnunet-gns-proxy.c:525 +#, fuzzy +msgid "Failed to start HTTP server\n" +msgstr "Fehler beim Starten der Collection.\n" + +#: src/gns/gnunet-gns-fcfsd.c:804 +msgid "GNUnet GNS first come first serve registration service" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:800 +msgid "listen on specified port" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:811 +msgid "GNUnet GNS proxy" +msgstr "" + +#: src/hello/gnunet-hello.c:122 +msgid "Call with name of HELLO file to modify.\n" +msgstr "" + +#: src/hello/gnunet-hello.c:128 +#, fuzzy, c-format +msgid "Error accessing file `%s': %s\n" +msgstr "Fehler beim Anlegen des Benutzers" + +#: src/hello/gnunet-hello.c:136 +#, c-format +msgid "File `%s' is too big to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:143 +#, c-format +msgid "File `%s' is too small to be a HELLO\n" msgstr "" +#: src/hello/gnunet-hello.c:153 src/hello/gnunet-hello.c:181 +#, fuzzy, c-format +msgid "Error opening file `%s': %s\n" +msgstr "Fehler beim Anlegen des Benutzers" + +#: src/hello/gnunet-hello.c:169 +#, fuzzy, c-format +msgid "Did not find well-formed HELLO in file `%s'\n" +msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" + +#: src/hello/gnunet-hello.c:193 +#, fuzzy, c-format +msgid "Error writing HELLO to file `%s': %s\n" +msgstr "Fehler beim Anlegen des Benutzers" + #: src/hostlist/gnunet-daemon-hostlist.c:264 msgid "" "None of the functions for the hostlist daemon were enabled. I have no " @@ -3138,195 +3290,197 @@ msgstr "" msgid "GNUnet hostlist server and client" msgstr "" -#: src/hostlist/hostlist-client.c:286 +#: src/hostlist/hostlist-client.c:289 msgid "# bytes downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:307 src/hostlist/hostlist-client.c:339 +#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:340 #, fuzzy msgid "# invalid HELLOs downloaded from hostlist servers" msgstr "# Hellos per HTTP heruntergeladen" -#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:342 +#: src/hostlist/hostlist-client.c:313 src/hostlist/hostlist-client.c:343 #, fuzzy, c-format msgid "Invalid `%s' message received from hostlist at `%s'\n" msgstr "UngĂźltige `%s' Nachricht von Knoten `%s' empfangen.\n" -#: src/hostlist/hostlist-client.c:330 +#: src/hostlist/hostlist-client.c:331 #, fuzzy msgid "# valid HELLOs downloaded from hostlist servers" msgstr "# Hellos per HTTP heruntergeladen" -#: src/hostlist/hostlist-client.c:374 src/hostlist/hostlist-client.c:395 +#: src/hostlist/hostlist-client.c:375 src/hostlist/hostlist-client.c:396 #, c-format msgid "No `%s' specified in `%s' configuration, will not bootstrap.\n" msgstr "" -#: src/hostlist/hostlist-client.c:472 src/hostlist/hostlist-client.c:682 -#: src/hostlist/hostlist-client.c:688 src/hostlist/hostlist-client.c:740 -#: src/hostlist/hostlist-client.c:749 src/hostlist/hostlist-client.c:877 -#: src/hostlist/hostlist-client.c:967 src/hostlist/hostlist-client.c:972 -#: src/transport/plugin_transport_http_client.c:108 -#: src/transport/plugin_transport_http_client.c:123 +#: src/hostlist/hostlist-client.c:473 src/hostlist/hostlist-client.c:683 +#: src/hostlist/hostlist-client.c:689 src/hostlist/hostlist-client.c:741 +#: src/hostlist/hostlist-client.c:750 src/hostlist/hostlist-client.c:871 +#: src/hostlist/hostlist-client.c:961 src/hostlist/hostlist-client.c:966 +#: src/transport/plugin_transport_http_client.c:110 +#: src/transport/plugin_transport_http_client.c:125 #, c-format msgid "%s failed at %s:%d: `%s'\n" msgstr "`%s' schlug fehl bei %s:%d mit dem Fehler: `%s'.\n" -#: src/hostlist/hostlist-client.c:592 src/hostlist/hostlist-client.c:1342 +#: src/hostlist/hostlist-client.c:593 src/hostlist/hostlist-client.c:1331 msgid "# advertised hostlist URIs" msgstr "" -#: src/hostlist/hostlist-client.c:622 +#: src/hostlist/hostlist-client.c:623 #, c-format msgid "# advertised URI `%s' downloaded" msgstr "" -#: src/hostlist/hostlist-client.c:663 +#: src/hostlist/hostlist-client.c:664 #, c-format msgid "" "Advertised hostlist with URI `%s' could not be downloaded. Advertised URI " "gets dismissed.\n" msgstr "" -#: src/hostlist/hostlist-client.c:805 +#: src/hostlist/hostlist-client.c:802 #, fuzzy, c-format msgid "Timeout trying to download hostlist from `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/hostlist/hostlist-client.c:822 +#: src/hostlist/hostlist-client.c:816 #, c-format msgid "Download limit of %u bytes exceeded, stopping download\n" msgstr "" -#: src/hostlist/hostlist-client.c:842 +#: src/hostlist/hostlist-client.c:836 #, fuzzy, c-format -msgid "%s failed for `%s' at %s:%d: `%s'\n" -msgstr "`%s' schlug fehl bei %s:%d mit dem Fehler: `%s'.\n" +msgid "Download of hostlist from `%s' failed: `%s'\n" +msgstr "" +"Upload von `%s' komplett, derzeitige durchschnittliche Geschwindigkeit " +"beträgt %8.3f KB/s.\n" -#: src/hostlist/hostlist-client.c:848 +#: src/hostlist/hostlist-client.c:842 #, fuzzy, c-format msgid "Download of hostlist `%s' completed.\n" msgstr "" "Upload von `%s' komplett, derzeitige durchschnittliche Geschwindigkeit " "beträgt %8.3f KB/s.\n" -#: src/hostlist/hostlist-client.c:856 +#: src/hostlist/hostlist-client.c:850 #, c-format msgid "Adding successfully tested hostlist `%s' datastore.\n" msgstr "" -#: src/hostlist/hostlist-client.c:909 +#: src/hostlist/hostlist-client.c:903 #, c-format msgid "Bootstrapping using hostlist at `%s'.\n" msgstr "" -#: src/hostlist/hostlist-client.c:917 +#: src/hostlist/hostlist-client.c:911 msgid "# hostlist downloads initiated" msgstr "" -#: src/hostlist/hostlist-client.c:1045 src/hostlist/hostlist-client.c:1515 +#: src/hostlist/hostlist-client.c:1037 src/hostlist/hostlist-client.c:1505 msgid "# milliseconds between hostlist downloads" msgstr "" -#: src/hostlist/hostlist-client.c:1054 +#: src/hostlist/hostlist-client.c:1046 #, c-format msgid "Have %u/%u connections. Will consider downloading hostlist in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1092 +#: src/hostlist/hostlist-client.c:1084 msgid "Scheduled saving of hostlists\n" msgstr "" -#: src/hostlist/hostlist-client.c:1096 +#: src/hostlist/hostlist-client.c:1088 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1119 src/hostlist/hostlist-client.c:1135 +#: src/hostlist/hostlist-client.c:1111 src/hostlist/hostlist-client.c:1127 #, fuzzy msgid "# active connections" msgstr "GNUnet Konfiguration" -#: src/hostlist/hostlist-client.c:1253 +#: src/hostlist/hostlist-client.c:1242 #, c-format msgid "Initial time between hostlist downloads is %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1284 +#: src/hostlist/hostlist-client.c:1273 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot load hostlists from file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1290 +#: src/hostlist/hostlist-client.c:1279 #, fuzzy, c-format msgid "Loading saved hostlist entries from file `%s' \n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/hostlist/hostlist-client.c:1294 +#: src/hostlist/hostlist-client.c:1283 #, c-format msgid "Hostlist file `%s' is not existing\n" msgstr "" -#: src/hostlist/hostlist-client.c:1305 +#: src/hostlist/hostlist-client.c:1294 #, fuzzy, c-format msgid "Could not open file `%s' for reading to load hostlists: %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/hostlist/hostlist-client.c:1338 +#: src/hostlist/hostlist-client.c:1327 #, c-format msgid "%u hostlist URIs loaded from file\n" msgstr "" -#: src/hostlist/hostlist-client.c:1340 +#: src/hostlist/hostlist-client.c:1329 msgid "# hostlist URIs read from file" msgstr "" -#: src/hostlist/hostlist-client.c:1373 +#: src/hostlist/hostlist-client.c:1362 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot save hostlists to file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1387 +#: src/hostlist/hostlist-client.c:1376 #, fuzzy, c-format msgid "Could not open file `%s' for writing to save hostlists: %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/hostlist/hostlist-client.c:1392 +#: src/hostlist/hostlist-client.c:1381 #, fuzzy, c-format msgid "Writing %u hostlist URIs to `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/hostlist/hostlist-client.c:1416 src/hostlist/hostlist-client.c:1433 +#: src/hostlist/hostlist-client.c:1405 src/hostlist/hostlist-client.c:1422 #, c-format msgid "Error writing hostlist URIs to file `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:1428 +#: src/hostlist/hostlist-client.c:1417 msgid "# hostlist URIs written to file" msgstr "" -#: src/hostlist/hostlist-client.c:1480 +#: src/hostlist/hostlist-client.c:1470 msgid "Learning is enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1483 +#: src/hostlist/hostlist-client.c:1473 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1492 +#: src/hostlist/hostlist-client.c:1482 msgid "Learning is not enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1504 +#: src/hostlist/hostlist-client.c:1494 #, c-format msgid "" "Since learning is not enabled on this peer, hostlist file `%s' was removed\n" msgstr "" -#: src/hostlist/hostlist-client.c:1508 +#: src/hostlist/hostlist-client.c:1498 #, fuzzy, c-format msgid "Hostlist file `%s' could not be removed\n" msgstr "SitzungsschlĂźssel von Knoten `%s' konnte nicht ĂźberprĂźft werden.\n" @@ -3340,8 +3494,10 @@ msgstr "# bytes in der Datenbank" msgid "expired addresses encountered" msgstr "" -#: src/hostlist/hostlist-server.c:184 -#: src/topology/gnunet-daemon-topology.c:875 +#: src/hostlist/hostlist-server.c:184 src/hostlist/hostlist-server.c:425 +#: src/peerinfo-tool/gnunet-peerinfo.c:403 +#: src/peerinfo-tool/gnunet-peerinfo.c:519 +#: src/topology/gnunet-daemon-topology.c:927 #, fuzzy, c-format msgid "Error in communication with PEERINFO service: %s\n" msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." @@ -3350,188 +3506,405 @@ msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." msgid "HELLOs without addresses encountered (ignored)" msgstr "" -#: src/hostlist/hostlist-server.c:221 +#: src/hostlist/hostlist-server.c:219 msgid "bytes not included in hostlist (size limit)" msgstr "" -#: src/hostlist/hostlist-server.c:269 +#: src/hostlist/hostlist-server.c:263 #, fuzzy, c-format msgid "Refusing `%s' request to hostlist server\n" msgstr "Fehler beim Senden einer `%s' Anfrage an den SMTP Server.\n" -#: src/hostlist/hostlist-server.c:272 +#: src/hostlist/hostlist-server.c:266 #, fuzzy msgid "hostlist requests refused (not HTTP GET)" msgstr "# Client Trace-Anfragen empfangen" -#: src/hostlist/hostlist-server.c:280 +#: src/hostlist/hostlist-server.c:273 msgid "Sending 100 CONTINUE reply\n" msgstr "" -#: src/hostlist/hostlist-server.c:287 +#: src/hostlist/hostlist-server.c:279 #, c-format msgid "Refusing `%s' request with %llu bytes of upload data\n" msgstr "" -#: src/hostlist/hostlist-server.c:291 +#: src/hostlist/hostlist-server.c:283 #, fuzzy msgid "hostlist requests refused (upload data)" msgstr "# Client Trace-Anfragen empfangen" -#: src/hostlist/hostlist-server.c:299 +#: src/hostlist/hostlist-server.c:291 msgid "Could not handle hostlist request since I do not have a response yet\n" msgstr "" -#: src/hostlist/hostlist-server.c:302 +#: src/hostlist/hostlist-server.c:294 #, fuzzy msgid "hostlist requests refused (not ready)" msgstr "# Client Trace-Anfragen empfangen" -#: src/hostlist/hostlist-server.c:306 +#: src/hostlist/hostlist-server.c:298 msgid "Received request for our hostlist\n" msgstr "" -#: src/hostlist/hostlist-server.c:307 +#: src/hostlist/hostlist-server.c:299 #, fuzzy msgid "hostlist requests processed" msgstr "# Client Trace-Anfragen empfangen" -#: src/hostlist/hostlist-server.c:350 +#: src/hostlist/hostlist-server.c:341 #, fuzzy msgid "# hostlist advertisements send" msgstr "# Bekanntmachungen von anderen Ăźbertragen" -#: src/hostlist/hostlist-server.c:397 +#: src/hostlist/hostlist-server.c:388 msgid "Advertisement message could not be queued by core\n" msgstr "" -#: src/hostlist/hostlist-server.c:565 +#: src/hostlist/hostlist-server.c:561 #, fuzzy, c-format msgid "Invalid port number %llu. Exiting.\n" msgstr "UngĂźltige Parameter. Abbruch.\n" -#: src/hostlist/hostlist-server.c:574 +#: src/hostlist/hostlist-server.c:570 #, c-format msgid "Hostlist service starts on %s:%llu\n" msgstr "" -#: src/hostlist/hostlist-server.c:588 +#: src/hostlist/hostlist-server.c:584 #, fuzzy, c-format msgid "Address to obtain hostlist: `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/hostlist/hostlist-server.c:626 +#: src/hostlist/hostlist-server.c:624 +#, fuzzy, c-format +msgid "`%s' is not a valid IP address! Ignoring BINDTOIP.\n" +msgstr "`%s' ist nicht verfĂźgbar." + +#: src/hostlist/hostlist-server.c:666 #, fuzzy, c-format msgid "Could not start hostlist HTTP server on port %u\n" msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n" -#: src/mesh/gnunet-service-mesh.c:4595 +#: src/integration-tests/connection_watchdog.c:997 +#, fuzzy, c-format +msgid "Transport plugin: `%s' port %llu\n" +msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n" + +#: src/integration-tests/connection_watchdog.c:1030 +#, fuzzy, c-format +msgid "Found %u transport plugins: `%s'\n" +msgstr "Teste Transport(e) %s\n" + +#: src/integration-tests/connection_watchdog.c:1089 +msgid "Send ping messages to test connectivity (default == NO)" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1095 +#: src/template/gnunet-template.c:68 +#, fuzzy +msgid "help text" +msgstr "Hilfetext fĂźr -t" + +#: src/mesh/gnunet-service-mesh.c:4590 msgid "Wrong CORE service\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4789 +#: src/mesh/gnunet-service-mesh.c:4784 #, fuzzy msgid "Mesh service is lacking key configuration settings. Exiting.\n" msgstr "GNUnet Konfiguration" -#: src/mesh/gnunet-service-mesh.c:4798 +#: src/mesh/gnunet-service-mesh.c:4793 #, fuzzy msgid "Mesh service could not access hostkey. Exiting.\n" msgstr "Auf die Namespace Informationen konnte nicht zugegriffen werden.\n" -#: src/namestore/namestore_api.c:272 src/namestore/namestore_api.c:313 -msgid "Namestore added record successfully" +#: src/mysql/mysql.c:174 +#, c-format +msgid "Trying to use file `%s' for MySQL configuration.\n" +msgstr "Versuche, Datei `%s' fĂźr MySQL Konfiguration zu verwenden.\n" + +#: src/mysql/mysql.c:181 +#, fuzzy, c-format +msgid "Could not access file `%s': %s\n" +msgstr "`%s' konnte nicht aufgelĂśst werden: %s\n" + +#: src/namestore/gnunet-namestore.c:157 +#, fuzzy, c-format +msgid "Adding record failed: %s\n" msgstr "" +"\n" +"Fehler beim Uploaden der Datei: %s\n" -#: src/namestore/namestore_api.c:281 src/namestore/namestore_api.c:322 -msgid "Namestore failed to add record" +#: src/namestore/gnunet-namestore.c:183 +#, fuzzy, c-format +msgid "Deleting record failed: %s\n" msgstr "" +"\n" +"Fehler beim Uploaden der Datei: %s\n" -#: src/nat/gnunet-nat-server.c:289 +#: src/namestore/gnunet-namestore.c:239 #, c-format -msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgid "\tCorrupt or unsupported record of type %u\n" msgstr "" -#: src/nat/gnunet-nat-server.c:328 -msgid "GNUnet NAT traversal test helper daemon" +#: src/namestore/gnunet-namestore.c:276 +#, c-format +msgid "Option `%s' not given, but I need a zone key file!\n" msgstr "" -#: src/nat/nat.c:803 +#: src/namestore/gnunet-namestore.c:281 +#, fuzzy, c-format +msgid "Using default zone file `%s'\n" +msgstr "Collection `%s' begonnen.\n" + +#: src/namestore/gnunet-namestore.c:291 #, c-format -msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgid "No options given\n" msgstr "" -#: src/nat/nat.c:852 +#: src/namestore/gnunet-namestore.c:321 #, fuzzy, c-format -msgid "Failed to start %s\n" +msgid "Unsupported type `%s'\n" +msgstr "UngĂźltige Nachricht des Typs %u empfangen. Nachricht wird verworfen.\n" + +#: src/namestore/gnunet-namestore.c:328 src/namestore/gnunet-namestore.c:350 +#: src/namestore/gnunet-namestore.c:374 src/namestore/gnunet-namestore.c:384 +#: src/namestore/gnunet-namestore.c:409 +#, fuzzy, c-format +msgid "Missing option `%s' for operation `%s'\n" +msgstr "Konfigurationsdatei `%s' wurde erzeugt.\n" + +#: src/namestore/gnunet-namestore.c:329 src/namestore/gnunet-namestore.c:351 +msgid "add/del" +msgstr "" + +#: src/namestore/gnunet-namestore.c:341 +#, fuzzy, c-format +msgid "Value `%s' invalid for record type `%s'\n" +msgstr "%s: Symbolwert `%s' ist ungĂźltig fĂźr %s\n" + +#: src/namestore/gnunet-namestore.c:366 +#, fuzzy, c-format +msgid "Invalid time format `%s'\n" +msgstr "UngĂźltiger Parameter: `%s'\n" + +#: src/namestore/gnunet-namestore.c:375 src/namestore/gnunet-namestore.c:385 +msgid "add" +msgstr "" + +#: src/namestore/gnunet-namestore.c:410 +msgid "del" +msgstr "" + +#: src/namestore/gnunet-namestore.c:462 +msgid "add record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:465 +msgid "delete record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:468 +msgid "display records" +msgstr "" + +#: src/namestore/gnunet-namestore.c:471 +msgid "" +"expiration time for record to use (for adding only), \"never\" is possible" +msgstr "" + +#: src/namestore/gnunet-namestore.c:474 +msgid "name of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:477 +msgid "type of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:480 +msgid "value of the record to add/delete" +msgstr "" + +#: src/namestore/gnunet-namestore.c:483 +msgid "create or list public record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:486 +msgid "create or list non-authority record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:489 +msgid "filename with the zone key" +msgstr "" + +#: src/namestore/gnunet-namestore.c:500 +#, fuzzy +msgid "GNUnet zone manipulation tool" +msgstr "GNUnet Konfiguration" + +#: src/namestore/gnunet-service-namestore.c:143 +#, c-format +msgid "File zone `%s' but corrupt content already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:154 +#, c-format +msgid "File zone `%s' containing this key already exists\n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:160 +#, c-format +msgid "" +"File zone `%s' but different zone key already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:198 +#, fuzzy, c-format +msgid "Stored zonekey for zone `%s' in file `%s'\n" +msgstr "Datei wurde als `%s' gespeichert.\n" + +#: src/namestore/gnunet-service-namestore.c:1909 +#, fuzzy +msgid "No directory to load zonefiles specified in configuration\n" +msgstr "In der Konfigurationsdatei wurden keine Anwendungen definiert!\n" + +#: src/namestore/gnunet-service-namestore.c:1918 +#, c-format +msgid "Creating directory `%s' for zone files failed!\n" +msgstr "" + +#: src/namestore/namestore_api.c:315 src/namestore/namestore_api.c:353 +msgid "Namestore added record successfully" +msgstr "" + +#: src/namestore/namestore_api.c:323 +msgid "Namestore failed to add record" +msgstr "" + +#: src/namestore/namestore_api.c:361 +msgid "Namestore record already existed" +msgstr "" + +#: src/namestore/namestore_api.c:368 +msgid "Namestore failed to add record\n" +msgstr "" + +#: src/namestore/namestore_api.c:401 +#, fuzzy +msgid "Namestore removed record successfully" +msgstr "Der GNUnet Dienst wurde erfolgreich installiert.\n" + +#: src/namestore/namestore_api.c:408 +msgid "No records for entry" +msgstr "" + +#: src/namestore/namestore_api.c:415 +#, fuzzy +msgid "Could not find record to remove" +msgstr "Verbindung zu gnunetd konnte nicht hergestellt werden.\n" + +#: src/namestore/namestore_api.c:422 +#, fuzzy +msgid "Failed to create new signature" +msgstr "Namespace `%s' konnte nicht erstellt werden (existiert bereits?).\n" + +#: src/namestore/namestore_api.c:429 +#, fuzzy +msgid "Failed to put new set of records in database" +msgstr "Fehler beim Senden einer `%s' Anfrage an den SMTP Server.\n" + +#: src/nat/gnunet-nat-server.c:279 +#, c-format +msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgstr "" + +#: src/nat/gnunet-nat-server.c:318 +msgid "GNUnet NAT traversal test helper daemon" +msgstr "" + +#: src/nat/nat.c:799 +#, c-format +msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgstr "" + +#: src/nat/nat.c:844 +#, fuzzy, c-format +msgid "Failed to start %s\n" msgstr "Fehler beim Starten der Collection.\n" -#: src/nat/nat.c:1121 +#: src/nat/nat.c:1111 #, fuzzy, c-format msgid "Malformed %s `%s' given in configuration!\n" msgstr "Fehler beim Speichern der Konfiguration!" -#: src/nat/nat.c:1187 src/nat/nat.c:1197 +#: src/nat/nat.c:1177 src/nat/nat.c:1187 #, c-format msgid "" "Configuration requires `%s', but binary is not installed properly (SUID bit " "not set). Option disabled.\n" msgstr "" -#: src/nat/nat.c:1329 +#: src/nat/nat.c:1321 msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" msgstr "" -#: src/nat/nat.c:1341 +#: src/nat/nat.c:1332 #, c-format msgid "Running gnunet-helper-nat-client %s %s %u\n" msgstr "" -#: src/nat/nat_test.c:348 +#: src/nat/nat_test.c:341 #, fuzzy msgid "Failed to connect to `gnunet-nat-server'\n" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/nat/nat_test.c:418 +#: src/nat/nat_test.c:411 #, c-format msgid "Failed to create listen socket bound to `%s' for NAT test: %s\n" msgstr "" -#: src/nse/gnunet-nse-profiler.c:926 +#: src/nse/gnunet-nse-profiler.c:928 #, fuzzy msgid "Measure quality and performance of the NSE service." msgstr "Auf den Dienst konnte nicht zugegriffen werden" -#: src/nse/gnunet-service-nse.c:936 +#: src/nse/gnunet-service-nse.c:925 #, c-format msgid "Proof of work invalid: %llu!\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1391 src/nse/gnunet-service-nse.c:1410 -#: src/nse/gnunet-service-nse.c:1431 +#: src/nse/gnunet-service-nse.c:1381 src/nse/gnunet-service-nse.c:1400 +#: src/nse/gnunet-service-nse.c:1421 msgid "NSE service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1398 +#: src/nse/gnunet-service-nse.c:1388 #, fuzzy msgid "Invalid work requirement for NSE service. Exiting.\n" msgstr "UngĂźltige Parameter. Abbruch.\n" -#: src/nse/gnunet-service-nse.c:1419 +#: src/nse/gnunet-service-nse.c:1409 #, fuzzy msgid "NSE service could not access hostkey. Exiting.\n" msgstr "Auf die Namespace Informationen konnte nicht zugegriffen werden.\n" -#: src/peerinfo/gnunet-service-peerinfo.c:133 +#: src/peerinfo/gnunet-service-peerinfo.c:134 #, fuzzy, c-format msgid "Removing expired address of transport `%s'\n" msgstr "VerfĂźgbare(r) Transport(e): %s\n" -#: src/peerinfo/gnunet-service-peerinfo.c:195 +#: src/peerinfo/gnunet-service-peerinfo.c:203 +#, fuzzy, c-format +msgid "Failed to parse HELLO in file `%s'\n" +msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" + +#: src/peerinfo/gnunet-service-peerinfo.c:229 msgid "# peers known" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:239 +#: src/peerinfo/gnunet-service-peerinfo.c:254 #, c-format msgid "" "File `%s' in directory `%s' does not match naming convention. Removed.\n" @@ -3539,68 +3912,164 @@ msgstr "" "Die Datei `%s' im Verzeichnis `%s' entspricht nicht der Namenskonvention. " "Datei wurde entfernt.\n" -#: src/peerinfo/gnunet-service-peerinfo.c:305 +#: src/peerinfo/gnunet-service-peerinfo.c:353 #, fuzzy, c-format msgid "Still no peers found in `%s'!\n" msgstr "Dienst `%s' konnte nicht ordentlich entladen werden!\n" -#: src/peerinfo/peerinfo_api.c:279 -#, fuzzy, c-format -msgid "Failed to transmit message to `%s' service.\n" -msgstr "`%s' Dienst konnte nicht initialisiert werden.\n" +#: src/peerinfo/gnunet-service-peerinfo.c:710 +#, c-format +msgid "Importing HELLOs from `%s'\n" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:238 +msgid "aborted due to explicit disconnect request" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:358 +#, fuzzy +msgid "failed to transmit request (service down?)" +msgstr "Fehler beim Senden einer `%s' Anfrage an den SMTP Server.\n" -#: src/peerinfo/peerinfo_api.c:435 +#: src/peerinfo/peerinfo_api.c:505 #, fuzzy msgid "Failed to receive response from `PEERINFO' service." msgstr "Fehler beim Empfangen der Antwort von gnunetd auf die `%s' Nachricht\n" -#: src/peerinfo/peerinfo_api.c:463 src/peerinfo/peerinfo_api.c:481 +#: src/peerinfo/peerinfo_api.c:531 src/peerinfo/peerinfo_api.c:550 +#: src/peerinfo/peerinfo_api.c:565 src/peerinfo/peerinfo_api.c:576 +#: src/peerinfo/peerinfo_api.c:587 #, fuzzy -msgid "Received invalid message from `PEERINFO' service.\n" +msgid "Received invalid message from `PEERINFO' service." msgstr "UngĂźltige `%s' Anfrage von `%s' empfangen.\n" -#: src/peerinfo/peerinfo_api.c:523 +#: src/peerinfo/peerinfo_api.c:663 #, fuzzy -msgid "Failed to transmit iteration request to `PEERINFO' service\n" +msgid "Timeout transmitting iteration request to `PEERINFO' service." msgstr "Fehler beim Senden einer `%s' Anfrage an den SMTP Server.\n" -#: src/peerinfo/peerinfo_api.c:557 -msgid "Timeout transmitting iteration request to `PEERINFO' service.\n" -msgstr "" - -#: src/peerinfo/peerinfo_api_notify.c:258 +#: src/peerinfo/peerinfo_api_notify.c:256 #, fuzzy, c-format msgid "Could not connect to `%s' service.\n" msgstr "Verbindung zu gnunetd konnte nicht hergestellt werden.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:216 +#: src/peerinfo-tool/gnunet-peerinfo.c:581 +#, fuzzy +msgid "Failed to parse HELLO message: missing expiration time\n" +msgstr "Fehler beim Speichern der Konfiguration!" + +#: src/peerinfo-tool/gnunet-peerinfo.c:589 +#, fuzzy +msgid "Failed to parse HELLO message: invalid expiration time\n" +msgstr "Fehler beim Speichern der Konfiguration!" + +#: src/peerinfo-tool/gnunet-peerinfo.c:598 +#, fuzzy +msgid "Failed to parse HELLO message: malformed\n" +msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:608 +#, fuzzy +msgid "Failed to parse HELLO message: missing transport plugin\n" +msgstr "Anwendung `%s' konnte nicht initialisiert werden.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:625 +#, c-format +msgid "Plugin `%s' not found\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:634 +#, c-format +msgid "Plugin `%s' does not support URIs yet\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:653 +#, fuzzy, c-format +msgid "Failed to parse `%s' as an address for plugin `%s'\n" +msgstr "Fehler beim Binden an UDP Port %d.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:685 +#, fuzzy, c-format +msgid "Failure adding HELLO: %s\n" +msgstr "Fehler bei %s:%d.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:833 #, fuzzy, c-format msgid "Could not find option `%s:%s' in configuration.\n" msgstr "Knoten `%s' konnte nicht in der Routing Tabelle gefunden werden!\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:223 +#: src/peerinfo-tool/gnunet-peerinfo.c:840 #, fuzzy, c-format msgid "Loading hostkey from `%s' failed.\n" msgstr "Das Parsen des Hello von `%s' schlug fehl.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:235 +#: src/peerinfo-tool/gnunet-peerinfo.c:875 +#, fuzzy, c-format +msgid "Invalid URI `%s'\n" +msgstr "UngĂźltiger Parameter: `%s'\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:899 #, c-format msgid "I am peer `%s'.\n" msgstr "Ich bin Peer `%s'.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:255 +#: src/peerinfo-tool/gnunet-peerinfo.c:936 +msgid "don't resolve host names" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:939 msgid "output only the identity strings" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:258 +#: src/peerinfo-tool/gnunet-peerinfo.c:942 msgid "output our own identity only" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:264 +#: src/peerinfo-tool/gnunet-peerinfo.c:945 +msgid "list all known peers" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:948 +msgid "also output HELLO uri(s)" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:951 +msgid "add given HELLO uri to the database" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:957 #, fuzzy msgid "Print information about peers." msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:105 +#: src/transport/gnunet-service-transport_plugins.c:118 +#, fuzzy, c-format +msgid "Starting transport plugins `%s'\n" +msgstr "Teste Transport(e) %s\n" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:109 +#: src/transport/gnunet-service-transport_plugins.c:122 +#, fuzzy, c-format +msgid "Loading `%s' transport plugin\n" +msgstr "Teste Transport(e) %s\n" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:129 +#: src/transport/gnunet-service-transport_plugins.c:150 +#, fuzzy, c-format +msgid "Failed to load transport plugin for `%s'\n" +msgstr "Anwendung `%s' konnte nicht initialisiert werden.\n" + +#: src/postgres/postgres.c:59 +#, fuzzy, c-format +msgid "`%s:%s' failed at %s:%d with error: %s" +msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" + +#: src/postgres/postgres.c:148 +#, fuzzy, c-format +msgid "Unable to initialize Postgres: %s" +msgstr "SQLite Datenbank konnte nicht initialisiert werden: %s.\n" + #: src/pt/gnunet-daemon-pt.c:264 #, fuzzy msgid "Failed to pack DNS request. Dropping.\n" @@ -3668,50 +4137,67 @@ msgstr "`%s' Dienst konnte nicht initialisiert werden.\n" msgid "Daemon to run to perform IP protocol translation to GNUnet" msgstr "" -#: src/statistics/gnunet-service-statistics.c:209 +#: src/statistics/gnunet-service-statistics.c:271 #, fuzzy, c-format msgid "Loading %llu bytes of statistics from `%s'\n" msgstr "Dateien aus dem GNUnet herunterladen." -#: src/statistics/gnunet-service-statistics.c:267 +#: src/statistics/gnunet-service-statistics.c:330 #, fuzzy, c-format msgid "Wrote %llu bytes of statistics to `%s'\n" msgstr "Dateien aus dem GNUnet herunterladen." -#: src/statistics/gnunet-statistics.c:98 +#: src/statistics/gnunet-statistics.c:122 #, fuzzy msgid "Failed to obtain statistics.\n" msgstr "Statistiken Ăźber den Netzwerkverkehr konnten nicht ermittelt werden.\n" -#: src/statistics/gnunet-statistics.c:164 +#: src/statistics/gnunet-statistics.c:199 +#, c-format +msgid "No subsystem or name given\n" +msgstr "" + +#: src/statistics/gnunet-statistics.c:207 +#, fuzzy, c-format +msgid "Failed to initialize watch routine\n" +msgstr "SQLite Datenbank konnte nicht initialisiert werden.\n" + +#: src/statistics/gnunet-statistics.c:227 msgid "limit output to statistics for the given NAME" msgstr "" -#: src/statistics/gnunet-statistics.c:167 +#: src/statistics/gnunet-statistics.c:230 msgid "make the value being set persistent" msgstr "" -#: src/statistics/gnunet-statistics.c:170 +#: src/statistics/gnunet-statistics.c:233 msgid "limit output to the given SUBSYSTEM" msgstr "" -#: src/statistics/gnunet-statistics.c:173 +#: src/statistics/gnunet-statistics.c:236 msgid "just print the statistics value" msgstr "" -#: src/statistics/gnunet-statistics.c:180 +#: src/statistics/gnunet-statistics.c:239 +msgid "watch value continously" +msgstr "" + +#: src/statistics/gnunet-statistics.c:246 msgid "Print statistics about GNUnet operations." msgstr "Statistiken der GNUnet Aktivitäten ausgeben." -#: src/statistics/statistics_api.c:390 +#: src/statistics/statistics_api.c:456 #, fuzzy -msgid "Failed to connect to statistics service!\n" -msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" +msgid "Could not save some persistent statistics\n" +msgstr "" +"IP(v4) dieses Hosts konnte nicht ermittelt werden. Bitte geben Sie die IP in " +"der Konfigurationsdatei an.\n" -#: src/template/gnunet-template.c:68 -#, fuzzy -msgid "help text" -msgstr "Hilfetext fĂźr -t" +#: src/statistics/statistics_api.c:999 +msgid "" +"Failed to receive acknowledgement from statistics service, some statistics " +"might have been lost!\n" +msgstr "" #: src/testing/gnunet-testing.c:157 #, fuzzy @@ -3762,208 +4248,178 @@ msgstr "GNUnet Konfiguration" msgid "Could not access hostkey.\n" msgstr "Konfigurationsdatei `%s' konnte nicht geparst werden.\n" -#: src/testing/testing.c:204 +#: src/testing/testing.c:200 msgid "`scp' does not seem to terminate (timeout copying config).\n" msgstr "" -#: src/testing/testing.c:218 src/testing/testing.c:808 +#: src/testing/testing.c:214 src/testing/testing.c:798 #, fuzzy msgid "`scp' did not complete cleanly.\n" msgstr "`%s' ist zu keinem Knoten verbunden.\n" -#: src/testing/testing.c:239 +#: src/testing/testing.c:237 #, fuzzy msgid "Failed to create pipe for `gnunet-peerinfo' process.\n" msgstr "Fehler beim Starten der Collection.\n" -#: src/testing/testing.c:240 +#: src/testing/testing.c:238 #, fuzzy msgid "Failed to create pipe for `ssh' process.\n" msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" -#: src/testing/testing.c:292 +#: src/testing/testing.c:286 #, fuzzy, c-format msgid "Could not start `%s' process to create hostkey.\n" msgstr "" "IP(v4) dieses Hosts konnte nicht ermittelt werden. Bitte geben Sie die IP in " "der Konfigurationsdatei an.\n" -#: src/testing/testing.c:299 +#: src/testing/testing.c:293 #, fuzzy msgid "Failed to start `gnunet-peerinfo' process.\n" msgstr "Fehler beim Starten der Collection.\n" -#: src/testing/testing.c:300 src/testing/testing.c:488 +#: src/testing/testing.c:294 src/testing/testing.c:471 #, fuzzy msgid "Failed to start `ssh' process.\n" msgstr "Fehler beim Starten der Collection.\n" -#: src/testing/testing.c:360 +#: src/testing/testing.c:354 #, fuzzy, c-format msgid "Error reading from gnunet-peerinfo: %s\n" msgstr "Fehler beim Lesen von Informationen von gnunetd.\n" -#: src/testing/testing.c:364 +#: src/testing/testing.c:358 #, fuzzy msgid "Malformed output from gnunet-peerinfo!\n" msgstr "Fehler beim Lesen von Informationen von gnunetd.\n" -#: src/testing/testing.c:374 +#: src/testing/testing.c:368 #, fuzzy msgid "Failed to get hostkey!\n" msgstr "Statistiken Ăźber den Netzwerkverkehr konnten nicht ermittelt werden.\n" -#: src/testing/testing.c:406 +#: src/testing/testing.c:400 msgid "`Failed while waiting for topology setup!\n" msgstr "" -#: src/testing/testing.c:480 +#: src/testing/testing.c:463 #, fuzzy, c-format msgid "Could not start `%s' process to start GNUnet.\n" msgstr "" "IP(v4) dieses Hosts konnte nicht ermittelt werden. Bitte geben Sie die IP in " "der Konfigurationsdatei an.\n" -#: src/testing/testing.c:487 +#: src/testing/testing.c:470 #, fuzzy msgid "Failed to start `gnunet-arm' process.\n" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/testing/testing.c:509 src/testing/testing.c:612 +#: src/testing/testing.c:493 src/testing/testing.c:600 msgid "`gnunet-arm' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:510 src/testing/testing.c:613 -#: src/testing/testing.c:633 +#: src/testing/testing.c:494 src/testing/testing.c:601 +#: src/testing/testing.c:621 msgid "`ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:582 +#: src/testing/testing.c:570 msgid "Unable to get HELLO for peer!\n" msgstr "" -#: src/testing/testing.c:632 +#: src/testing/testing.c:620 msgid "`gnunet-arm' terminated with non-zero exit status (or timed out)!\n" msgstr "" -#: src/testing/testing.c:653 src/testing/testing.c:685 +#: src/testing/testing.c:643 src/testing/testing.c:675 msgid "either `gnunet-arm' or `ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:668 src/testing/testing.c:723 +#: src/testing/testing.c:658 src/testing/testing.c:713 #, fuzzy msgid "shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n" msgstr "`%s' ist zu keinem Knoten verbunden.\n" -#: src/testing/testing.c:796 +#: src/testing/testing.c:786 msgid "`scp' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:966 +#: src/testing/testing.c:948 #, fuzzy, c-format msgid "Starting service %s for peer `%4s'\n" msgstr "Collection `%s' begonnen.\n" -#: src/testing/testing.c:1237 src/testing/testing_group.c:6278 +#: src/testing/testing.c:1207 src/testing/testing_group.c:6154 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration directory.\n" msgstr "" "IP(v4) dieses Hosts konnte nicht ermittelt werden. Bitte geben Sie die IP in " "der Konfigurationsdatei an.\n" -#: src/testing/testing.c:1322 src/testing/testing.c:1397 +#: src/testing/testing.c:1292 src/testing/testing.c:1359 #, fuzzy, c-format msgid "Terminating peer `%4s'\n" msgstr "Zugriff verweigert fĂźr `%s' bei %s:%d.\n" -#: src/testing/testing.c:1480 +#: src/testing/testing.c:1448 #, fuzzy, c-format msgid "Setting d->dead on peer `%4s'\n" msgstr "Collection `%s' begonnen.\n" -#: src/testing/testing.c:1610 +#: src/testing/testing.c:1601 msgid "Peer not yet running, can not change configuration at this point." msgstr "" -#: src/testing/testing.c:1618 +#: src/testing/testing.c:1609 #, fuzzy msgid "Failed to write new configuration to disk." msgstr "Fehler beim Speichern der Konfiguration!" -#: src/testing/testing.c:1647 +#: src/testing/testing.c:1636 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration file.\n" msgstr "" "IP(v4) dieses Hosts konnte nicht ermittelt werden. Bitte geben Sie die IP in " "der Konfigurationsdatei an.\n" -#: src/testing/testing.c:1650 +#: src/testing/testing.c:1639 #, fuzzy msgid "Failed to copy new configuration to remote machine." msgstr "Fehler beim Speichern der Konfiguration!" -#: src/testing/testing.c:1805 +#: src/testing/testing.c:1794 #, fuzzy msgid "Peers failed to connect" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden." -#: src/testing/testing.c:1933 +#: src/testing/testing.c:1922 #, fuzzy msgid "Failed to connect to core service of first peer!\n" msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n" -#: src/testing/testing.c:2156 +#: src/testing/testing.c:2145 msgid "Peers are not fully running yet, can not connect!\n" msgstr "" -#: src/testing/testing_group.c:1910 src/testing/testing_group.c:1922 -#: src/testing/testing_group.c:2023 src/testing/testing_group.c:2082 -#: src/testing/testing_group.c:2171 src/testing/testing_group.c:2191 -#: src/testing/testing_group.c:2328 src/testing/testing_peergroup.c:940 +#: src/testing/testing_group.c:1895 src/testing/testing_group.c:1907 +#: src/testing/testing_group.c:2008 src/testing/testing_group.c:2065 +#: src/testing/testing_group.c:2152 src/testing/testing_group.c:2172 +#: src/testing/testing_group.c:2302 src/testing/testing_peergroup.c:950 #, fuzzy, c-format msgid "Invalid value `%s' for option `%s' in section `%s': expected float\n" msgstr "" "Die Konfigurationsdatei muss in der Sektion `%s' unter `%s' ein Verzeichnis " "angeben, in dem FS Daten gespeichert werden.\n" -#: src/testing/testing_group.c:1932 -#, fuzzy, c-format -msgid "Target is %d connections per peer." -msgstr "Fehler beim Aufbauen einer Verbindung mit gnunetd.\n" - -#: src/testing/testing_group.c:2179 +#: src/testing/testing_group.c:2160 #, c-format msgid "" "Invalid value `%s' for option `%s' in section `%s': got %f, needed value " "greater than 0\n" msgstr "" -#: src/testing/testing_group.c:2209 src/testing/testing_group.c:2402 -#, c-format -msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n" -msgstr "" - -#: src/testing/testing_group.c:2246 -#, c-format -msgid "natural log of %d is %d, will run %d iterations\n" -msgstr "" - -#: src/testing/testing_group.c:2249 -#, c-format -msgid "Total connections added thus far: %u!\n" -msgstr "" - -#: src/testing/testing_group.c:2290 -#, c-format -msgid "Total connections added for small world: %d!\n" -msgstr "" - -#: src/testing/testing_group.c:2342 -#, c-format -msgid "rand is %f probability is %f\n" -msgstr "" - -#: src/testing/testing_group.c:2919 src/testing/testing_group.c:3118 +#: src/testing/testing_group.c:2877 src/testing/testing_group.c:3063 #, fuzzy, c-format msgid "" "No `%s' specified in peer configuration in section `%s', cannot copy friends " @@ -3972,404 +4428,272 @@ msgstr "" "Option `%s' ist in der Konfigurationsdatei in der Sektion `%s' nicht " "gesetzt, sie wird auf %dm gesetzt.\n" -#: src/testing/testing_group.c:3020 -msgid "Finished copying all friend files!\n" -msgstr "" - -#: src/testing/testing_group.c:3133 -#, fuzzy, c-format -msgid "Copying file with command cp %s %s\n" -msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" - -#: src/testing/testing_group.c:3156 -#, fuzzy, c-format -msgid "Copying file with command scp %s %s\n" -msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" - -#: src/testing/testing_group.c:3173 -#, c-format -msgid "Checking copy status of file %d\n" +#: src/testing/testing_group.c:3957 +msgid "Creating no allowed topology (all peers can connect at core level)\n" msgstr "" -#: src/testing/testing_group.c:3191 -#, c-format -msgid "File %d copied\n" -msgstr "" +#: src/testing/testing_group.c:5226 +#, fuzzy +msgid "Unknown topology specification, can't connect peers!\n" +msgstr "Syntaxfehler in Topolgieangabe, Bytes werden Ăźbersprungen.\n" -#: src/testing/testing_group.c:3206 +#: src/testing/testing_group.c:5944 src/transport/transport-testing.c:636 #, fuzzy -msgid "Finished copying all blacklist files!\n" +msgid "Could not read hostkeys file!\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/testing/testing_group.c:3586 src/testing/testing_group.c:3723 -#: src/testing/testing_group.c:4884 src/testing/testing_group.c:5025 -msgid "Delaying connect, we have too many outstanding connections!\n" -msgstr "" - -#: src/testing/testing_group.c:3596 src/testing/testing_group.c:4894 -#: src/testing/testing_group.c:5035 -#, c-format -msgid "Creating connection, outstanding_connections is %d\n" -msgstr "" - -#: src/testing/testing_group.c:3608 +#: src/testing/testing_group.c:6011 #, fuzzy, c-format -msgid "Offering HELLO of peer %s to peer %s\n" -msgstr "Verbindung zu %u.%u.%u.%u:%u fehlgeschlagen: %s\n" - -#: src/testing/testing_group.c:3734 -#, c-format -msgid "Creating connection, outstanding_connections is %d (max %d)\n" -msgstr "" - -#: src/testing/testing_group.c:3988 -msgid "Creating clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:3993 -msgid "Creating small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:3998 -msgid "Creating small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4002 -msgid "Creating ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4006 -msgid "Creating 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4010 -msgid "Creating Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4014 -msgid "Creating InterNAT topology\n" -msgstr "" - -#: src/testing/testing_group.c:4018 -msgid "Creating Scale Free topology\n" -msgstr "" - -#: src/testing/testing_group.c:4023 -msgid "Creating straight line topology\n" -msgstr "" - -#: src/testing/testing_group.c:4027 -msgid "Creating topology from file!\n" -msgstr "" - -#: src/testing/testing_group.c:4043 -msgid "Creating no allowed topology (all peers can connect at core level)\n" -msgstr "" - -#: src/testing/testing_group.c:4058 -msgid "Failed during friend file copying!\n" -msgstr "" - -#: src/testing/testing_group.c:4064 -msgid "Friend files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:4081 -msgid "Blacklisting all but clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:4087 -msgid "Blacklisting all but small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4093 -msgid "Blacklisting all but small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4099 -msgid "Blacklisting all but ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4105 -msgid "Blacklisting all but 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4111 -msgid "Blacklisting all but Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4117 -msgid "Blacklisting all but InterNAT topology\n" -msgstr "" +msgid "Could not create configuration for peer number %u on `%s'!\n" +msgstr "Auf die Namespace Informationen konnte nicht zugegriffen werden.\n" -#: src/testing/testing_group.c:4152 -msgid "Blacklisting all but Scale Free topology\n" +#: src/testing/testing_new.c:169 +msgid "tmppath cannot be NULL\n" msgstr "" -#: src/testing/testing_group.c:4158 -msgid "Blacklisting all but straight line topology\n" +#: src/testing/testing_new.c:356 +#, c-format +msgid "Hostkeys file not found: %s\n" msgstr "" -#: src/testing/testing_group.c:4173 -#, fuzzy -msgid "Failed during blacklist file copying!\n" +#: src/testing/testing_new.c:365 +#, fuzzy, c-format +msgid "Could not open hostkeys file: %s\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/testing/testing_group.c:4179 -msgid "Blacklist files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:5263 -msgid "Creating clique CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5270 -msgid "Creating small world (ring) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5277 -msgid "Creating small world (2d-torus) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5283 -msgid "Creating ring CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5290 -msgid "Creating 2d torus CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5297 -msgid "Creating Erdos-Renyi CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5304 -msgid "Creating InterNAT CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5311 -msgid "Creating Scale Free CONNECT topology\n" +#: src/testing/testing_new.c:380 +#, c-format +msgid "Incorrect hostkey file format: %s\n" msgstr "" -#: src/testing/testing_group.c:5318 -msgid "Creating straight line CONNECT topology\n" -msgstr "" +#: src/testing/testing_new.c:437 +#, fuzzy, c-format +msgid "Key number %u does not exist\n" +msgstr "Anzahl an Nachrichten, die pro Durchlauf verwendet wird" -#: src/testing/testing_group.c:5324 -msgid "Creating no CONNECT topology\n" -msgstr "" +#: src/testing/testing_new.c:446 +#, fuzzy, c-format +msgid "Error while decoding key %u\n" +msgstr "Fehler beim Download: %s\n" -#: src/testing/testing_group.c:5330 +#: src/testing/testing_new.c:680 #, fuzzy -msgid "Unknown topology specification, can't connect peers!\n" -msgstr "Syntaxfehler in Topolgieangabe, Bytes werden Ăźbersprungen.\n" +msgid "Failed to create configuration for peer (not enough free ports?)\n" +msgstr "Auf die Namespace Informationen konnte nicht zugegriffen werden.\n" -#: src/testing/testing_group.c:5340 +#: src/testing/testing_new.c:691 #, c-format -msgid "Connecting random subset (%'.2f percent) of possible peers\n" +msgid "" +"You attempted to create a testbed with more than %u hosts. Please " +"precompute more hostkeys first.\n" msgstr "" -#: src/testing/testing_group.c:5348 -#, c-format -msgid "Connecting a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:704 +#, fuzzy, c-format +msgid "Failed to initialize hostkey for peer %u\n" +msgstr "SQLite Datenbank konnte nicht initialisiert werden.\n" -#: src/testing/testing_group.c:5357 -#, c-format -msgid "Using DFS to connect a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:734 +#, fuzzy, c-format +msgid "Failed to write hostkey file for peer %u: %s\n" +msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" -#: src/testing/testing_group.c:5367 -#, c-format -msgid "Finding additional %u closest peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:751 +#, fuzzy, c-format +msgid "Failed to write configuration file `%s' for peer %u: %s\n" +msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':" -#: src/testing/testing_group.c:6062 src/transport/transport-testing.c:650 -#, fuzzy -msgid "Could not read hostkeys file!\n" -msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" +#: src/testing/testing_new.c:791 +#, fuzzy, c-format +msgid "Failed to start `%s': %s\n" +msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/testing/testing_group.c:6131 +#: src/testing/testing_new.c:959 #, fuzzy, c-format -msgid "Could not create configuration for peer number %u on `%s'!\n" -msgstr "Auf die Namespace Informationen konnte nicht zugegriffen werden.\n" +msgid "Failed to load configuration from %s\n" +msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':" -#: src/topology/gnunet-daemon-topology.c:244 +#: src/topology/gnunet-daemon-topology.c:259 msgid "# peers blacklisted" msgstr "" -#: src/topology/gnunet-daemon-topology.c:380 +#: src/topology/gnunet-daemon-topology.c:392 #, fuzzy msgid "# connect requests issued to transport" msgstr "# Client Trace-Anfragen empfangen" -#: src/topology/gnunet-daemon-topology.c:675 -#: src/topology/gnunet-daemon-topology.c:761 +#: src/topology/gnunet-daemon-topology.c:730 +#: src/topology/gnunet-daemon-topology.c:815 #, fuzzy msgid "# friends connected" msgstr "# verbundener Knoten" -#: src/topology/gnunet-daemon-topology.c:950 +#: src/topology/gnunet-daemon-topology.c:996 msgid "Failed to connect to core service, can not manage topology!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:982 +#: src/topology/gnunet-daemon-topology.c:1026 #, c-format msgid "Option `%s' in section `%s' not specified!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:994 +#: src/topology/gnunet-daemon-topology.c:1039 #, fuzzy, c-format msgid "Could not read friends list `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/topology/gnunet-daemon-topology.c:1000 +#: src/topology/gnunet-daemon-topology.c:1045 #, c-format msgid "Friends file `%s' is empty.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1009 +#: src/topology/gnunet-daemon-topology.c:1054 #, fuzzy, c-format msgid "Failed to read friends list from `%s': out of memory\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/topology/gnunet-daemon-topology.c:1017 +#: src/topology/gnunet-daemon-topology.c:1062 #, c-format msgid "Failed to read friends list from `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/topology/gnunet-daemon-topology.c:1037 +#: src/topology/gnunet-daemon-topology.c:1082 #, fuzzy, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes.\n" msgstr "Syntaxfehler in Topolgieangabe, Bytes werden Ăźbersprungen.\n" -#: src/topology/gnunet-daemon-topology.c:1050 +#: src/topology/gnunet-daemon-topology.c:1095 #, fuzzy, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n" msgstr "Syntaxfehler in Topologieangabe, Ăźberspringe Bytes `%s'.\n" -#: src/topology/gnunet-daemon-topology.c:1060 +#: src/topology/gnunet-daemon-topology.c:1105 #, fuzzy, c-format msgid "Found friend `%s' in configuration\n" msgstr " gconfig\tGTK Konfiguration\n" -#: src/topology/gnunet-daemon-topology.c:1066 +#: src/topology/gnunet-daemon-topology.c:1111 #, c-format msgid "Found myself `%s' in friend list (useless, ignored)\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1076 +#: src/topology/gnunet-daemon-topology.c:1121 #, fuzzy msgid "# friends in configuration" msgstr " gconfig\tGTK Konfiguration\n" -#: src/topology/gnunet-daemon-topology.c:1082 +#: src/topology/gnunet-daemon-topology.c:1127 msgid "" "Fewer friends specified than required by minimum friend count. Will only " "connect to friends.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1089 +#: src/topology/gnunet-daemon-topology.c:1134 msgid "" "More friendly connections required than target total number of connections.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1126 +#: src/topology/gnunet-daemon-topology.c:1169 #, fuzzy msgid "# HELLO messages received" msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/topology/gnunet-daemon-topology.c:1183 +#: src/topology/gnunet-daemon-topology.c:1224 #, fuzzy msgid "# HELLO messages gossipped" msgstr "# ausgehender Nachrichten verworfen" -#: src/topology/gnunet-daemon-topology.c:1323 +#: src/topology/gnunet-daemon-topology.c:1363 msgid "GNUnet topology control (maintaining P2P mesh and F2F constraints)" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:247 +#: src/transport/gnunet-service-transport_blacklist.c:246 #, fuzzy, c-format msgid "Could not read blacklist file `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/transport/gnunet-service-transport_blacklist.c:254 +#: src/transport/gnunet-service-transport_blacklist.c:252 #, c-format msgid "Blacklist file `%s' is empty.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:266 +#: src/transport/gnunet-service-transport_blacklist.c:263 #, fuzzy, c-format msgid "Failed to read blacklist from `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/transport/gnunet-service-transport_blacklist.c:287 -#: src/transport/gnunet-service-transport_blacklist.c:311 +#: src/transport/gnunet-service-transport_blacklist.c:284 +#: src/transport/gnunet-service-transport_blacklist.c:308 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, giving up!\n" msgstr "Syntaxfehler in Konfigurationsdatei `%s' in Zeile %d.\n" -#: src/transport/gnunet-service-transport_blacklist.c:298 -#: src/transport/gnunet-service-transport_blacklist.c:336 +#: src/transport/gnunet-service-transport_blacklist.c:295 +#: src/transport/gnunet-service-transport_blacklist.c:331 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes.\n" msgstr "Syntaxfehler in Topolgieangabe, Bytes werden Ăźbersprungen.\n" -#: src/transport/gnunet-service-transport_blacklist.c:350 +#: src/transport/gnunet-service-transport_blacklist.c:345 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n" msgstr "Syntaxfehler in Topologieangabe, Ăźberspringe Bytes `%s'.\n" -#: src/transport/gnunet-service-transport_blacklist.c:364 +#: src/transport/gnunet-service-transport_blacklist.c:359 #, c-format msgid "Found myself `%s' in blacklist (useless, ignored)\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:523 -#: src/transport/gnunet-service-transport_blacklist.c:764 +#: src/transport/gnunet-service-transport_blacklist.c:514 +#: src/transport/gnunet-service-transport_blacklist.c:747 msgid "# disconnects due to blacklist" msgstr "" -#: src/transport/gnunet-service-transport.c:158 +#: src/transport/gnunet-service-transport.c:163 #, fuzzy msgid "# bytes payload discarded due to not connected peer " msgstr "# KnotenankĂźndigungen empfangen" -#: src/transport/gnunet-service-transport.c:572 +#: src/transport/gnunet-service-transport.c:237 +#, fuzzy +msgid "# bytes total received" +msgstr "# gap Anfragen insgesamt empfangen" + +#: src/transport/gnunet-service-transport.c:284 +#, fuzzy +msgid "# bytes payload received" +msgstr "# Bytes entschlĂźsselt" + +#: src/transport/gnunet-service-transport.c:582 msgid "Transport service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport.c:581 +#: src/transport/gnunet-service-transport.c:591 msgid "Transport service could not access hostkey. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:353 +#: src/transport/gnunet-service-transport_clients.c:352 #, c-format msgid "Dropping message of type %u and size %u, have %u/%u messages pending\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:358 +#: src/transport/gnunet-service-transport_clients.c:357 #, fuzzy msgid "# messages dropped due to slow client" msgstr "# gap Anfragen verworfen: Kollision in RT" -#: src/transport/gnunet-service-transport_clients.c:510 +#: src/transport/gnunet-service-transport_clients.c:503 #, c-format msgid "Rejecting control connection from peer `%s', which is not me!\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:628 -#, fuzzy -msgid "# bytes payload received for other peers" -msgstr "# Bytes des Typs %d empfangen" - -#: src/transport/gnunet-service-transport_clients.c:645 +#: src/transport/gnunet-service-transport_clients.c:631 msgid "# bytes payload dropped (other peer was not connected)" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:696 +#: src/transport/gnunet-service-transport_clients.c:682 #, fuzzy msgid "# REQUEST CONNECT messages received" msgstr "# verschlĂźsselter PONG Nachrichten empfangen" @@ -4378,623 +4702,564 @@ msgstr "# verschlĂźsselter PONG Nachrichten empfangen" msgid "# refreshed my HELLO" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:482 -msgid "# failed connection attempts due to timeout" -msgstr "" +#: src/transport/gnunet-service-transport_neighbours.c:1032 +#, fuzzy +msgid "# DISCONNECT messages sent" +msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/transport/gnunet-service-transport_neighbours.c:883 +#: src/transport/gnunet-service-transport_neighbours.c:1148 +#: src/transport/gnunet-service-transport_neighbours.c:1482 #, fuzzy -msgid "# peers disconnected due to external request" -msgstr "# gap Anfragen verworfen: Kollision in RT" +msgid "# bytes in message queue for other peers" +msgstr "# Bytes ausgehender Nachrichten verworfen" -#: src/transport/gnunet-service-transport_neighbours.c:966 +#: src/transport/gnunet-service-transport_neighbours.c:1153 #, fuzzy -msgid "# fast reconnects failed" -msgstr "# verbundener Knoten" +msgid "# messages transmitted to other peers" +msgstr "# Bytes des Typs %d Ăźbertragen" -#: src/transport/gnunet-service-transport_neighbours.c:1022 +#: src/transport/gnunet-service-transport_neighbours.c:1158 #, fuzzy -msgid "# peers disconnected due to timeout" -msgstr "# geschlossener Verbindungen (HANGUP gesendet)" +msgid "# transmission failures for messages to other peers" +msgstr "# Bytes ausgehender Nachrichten verworfen" -#: src/transport/gnunet-service-transport_neighbours.c:1047 +#: src/transport/gnunet-service-transport_neighbours.c:1215 +msgid "# messages timed out while in transport queue" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:1254 #, fuzzy msgid "# keepalives sent" msgstr "# p2p Trace-Antworten gesendet" -#: src/transport/gnunet-service-transport_neighbours.c:1088 +#: src/transport/gnunet-service-transport_neighbours.c:1278 #, fuzzy -msgid "# peers disconnected due to global disconnect" -msgstr "# KnotenankĂźndigungen empfangen" +msgid "# KEEPALIVE messages discarded (peer unknown)" +msgstr "# defragmentierter Nachrichten" -#: src/transport/gnunet-service-transport_neighbours.c:1888 -#: src/transport/gnunet-service-transport_neighbours.c:1909 +#: src/transport/gnunet-service-transport_neighbours.c:1286 #, fuzzy -msgid "# messages not sent (no such peer or not connected)" +msgid "# KEEPALIVE messages discarded (no session)" msgstr "# defragmentierter Nachrichten" -#: src/transport/gnunet-service-transport_neighbours.c:1925 +#: src/transport/gnunet-service-transport_neighbours.c:1323 #, fuzzy -msgid "# bytes in message queue for other peers" -msgstr "# Bytes ausgehender Nachrichten verworfen" +msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" +msgstr "# defragmentierter Nachrichten" + +#: src/transport/gnunet-service-transport_neighbours.c:1332 +#, fuzzy +msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" +msgstr "# defragmentierter Nachrichten" -#: src/transport/gnunet-service-transport_neighbours.c:1977 +#: src/transport/gnunet-service-transport_neighbours.c:1388 #, fuzzy msgid "# messages discarded due to lack of neighbour record" msgstr "# defragmentierter Nachrichten" -#: src/transport/gnunet-service-transport_neighbours.c:2013 +#: src/transport/gnunet-service-transport_neighbours.c:1422 #, fuzzy msgid "# bandwidth quota violations by other peers" msgstr "Verfolgt die Bandbreitennutzung von gnunetd" -#: src/transport/gnunet-service-transport_neighbours.c:2031 +#: src/transport/gnunet-service-transport_neighbours.c:1438 msgid "# ms throttling suggested" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2060 +#: src/transport/gnunet-service-transport_neighbours.c:2544 #, fuzzy -msgid "# KEEPALIVE messages discarded (not connected)" -msgstr "# defragmentierter Nachrichten" +msgid "# unexpected CONNECT_ACK messages (no peer)" +msgstr "COUNT Nachrichten versenden" -#: src/transport/gnunet-service-transport_neighbours.c:2113 +#: src/transport/gnunet-service-transport_neighbours.c:2559 +#: src/transport/gnunet-service-transport_neighbours.c:2585 #, fuzzy -msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" -msgstr "# defragmentierter Nachrichten" +msgid "# unexpected CONNECT_ACK messages (not ready)" +msgstr "COUNT Nachrichten versenden" -#: src/transport/gnunet-service-transport_neighbours.c:2121 +#: src/transport/gnunet-service-transport_neighbours.c:2598 #, fuzzy -msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" -msgstr "# defragmentierter Nachrichten" +msgid "# unexpected CONNECT_ACK messages (waiting on ATS)" +msgstr "COUNT Nachrichten versenden" -#: src/transport/gnunet-service-transport_neighbours.c:2187 +#: src/transport/gnunet-service-transport_neighbours.c:2627 +#, fuzzy +msgid "# unexpected CONNECT_ACK messages (disconnecting)" +msgstr "COUNT Nachrichten versenden" + +#: src/transport/gnunet-service-transport_neighbours.c:2807 +#, fuzzy +msgid "# unexpected SESSION ACK messages" +msgstr "# verschlĂźsselter PONG Nachrichten gesendet" + +#: src/transport/gnunet-service-transport_neighbours.c:2856 msgid "# SET QUOTA messages ignored (no such peer)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2205 +#: src/transport/gnunet-service-transport_neighbours.c:2870 msgid "# disconnects due to quota of 0" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2323 +#: src/transport/gnunet-service-transport_neighbours.c:2901 msgid "# disconnect messages ignored (old format)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2336 +#: src/transport/gnunet-service-transport_neighbours.c:2912 msgid "# disconnect messages ignored (timestamp)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2411 -#, fuzzy -msgid "# unexpected CONNECT_ACK messages (no peer)" -msgstr "COUNT Nachrichten versenden" - -#: src/transport/gnunet-service-transport_neighbours.c:2453 -#, fuzzy -msgid "# unexpected CONNECT_ACK messages" -msgstr "COUNT Nachrichten versenden" +#: src/transport/gnunet-service-transport_neighbours.c:2943 +msgid "# other peer asked to disconnect from us" +msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2544 +#: src/transport/gnunet-service-transport_neighbours.c:3020 #, fuzzy -msgid "# unexpected ACK messages" -msgstr "# verschlĂźsselter PONG Nachrichten gesendet" +msgid "# disconnected from peer upon explicit request" +msgstr "# gap Anfragen verworfen: Kollision in RT" #: src/transport/gnunet-service-transport_plugins.c:111 msgid "Transport service is lacking NEIGHBOUR_LIMIT option.\n" msgstr "" -#: src/transport/gnunet-service-transport_plugins.c:118 -#, fuzzy, c-format -msgid "Starting transport plugins `%s'\n" -msgstr "Teste Transport(e) %s\n" - -#: src/transport/gnunet-service-transport_plugins.c:122 -#, fuzzy, c-format -msgid "Loading `%s' transport plugin\n" -msgstr "Teste Transport(e) %s\n" - -#: src/transport/gnunet-service-transport_plugins.c:150 -#, fuzzy, c-format -msgid "Failed to load transport plugin for `%s'\n" -msgstr "Anwendung `%s' konnte nicht initialisiert werden.\n" - -#: src/transport/gnunet-service-transport_validation.c:410 +#: src/transport/gnunet-service-transport_validation.c:414 msgid "# address records discarded" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:459 +#: src/transport/gnunet-service-transport_validation.c:463 #, c-format msgid "" "Not transmitting `%s' with `%s', message too big (%u bytes!). This should " "not happen.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:508 +#: src/transport/gnunet-service-transport_validation.c:512 #, fuzzy msgid "# PING without HELLO messages sent" msgstr "# Klartext PING Nachrichten gesendet" -#: src/transport/gnunet-service-transport_validation.c:566 +#: src/transport/gnunet-service-transport_validation.c:570 msgid "# address revalidations started" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:798 +#: src/transport/gnunet-service-transport_validation.c:805 #, fuzzy msgid "# PING message for different peer received" msgstr "# PING Nachrichten erstellt" -#: src/transport/gnunet-service-transport_validation.c:833 +#: src/transport/gnunet-service-transport_validation.c:840 #, c-format msgid "" "Not confirming PING with address `%s' since I cannot confirm having this " "address.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:919 +#: src/transport/gnunet-service-transport_validation.c:924 msgid "# PONGs unicast via reliable transport" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:928 +#: src/transport/gnunet-service-transport_validation.c:933 msgid "# PONGs multicast to all available addresses" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1050 +#: src/transport/gnunet-service-transport_validation.c:1055 msgid "# PONGs dropped, no matching pending validation" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1075 +#: src/transport/gnunet-service-transport_validation.c:1080 msgid "# PONGs dropped, signature expired" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1134 +#: src/transport/gnunet-service-transport_validation.c:1136 #, fuzzy, c-format msgid "Adding `%s' without addresses for peer `%s'\n" msgstr "Adresse des Knotens `%s' konnte nicht ermittelt werden.\n" -#: src/transport/gnunet-transport.c:256 +#: src/transport/gnunet-transport.c:260 msgid "No transport plugins configured, peer will never communicate\n" msgstr "" -#: src/transport/gnunet-transport.c:269 +#: src/transport/gnunet-transport.c:273 #, c-format msgid "No port configured for plugin `%s', cannot test it\n" msgstr "" -#: src/transport/gnunet-transport.c:319 +#: src/transport/gnunet-transport.c:323 #, c-format msgid "Received %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:326 +#: src/transport/gnunet-transport.c:330 #, c-format msgid "Transmitted %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:359 +#: src/transport/gnunet-transport.c:363 #, fuzzy, c-format msgid "Transmitting %u bytes to %s\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/transport/gnunet-transport.c:379 +#: src/transport/gnunet-transport.c:383 #, fuzzy, c-format msgid "Connected to %s\n" msgstr "`%s' hat sich mit `%s' verbunden.\n" -#: src/transport/gnunet-transport.c:410 +#: src/transport/gnunet-transport.c:414 #, fuzzy, c-format msgid "Disconnected from %s\n" msgstr "`%s' hat sich mit `%s' verbunden.\n" -#: src/transport/gnunet-transport.c:439 +#: src/transport/gnunet-transport.c:443 #, fuzzy, c-format msgid "Received %u bytes from %s\n" msgstr "GAP hat ungĂźltige Inhalte von `%s' empfangen.\n" -#: src/transport/gnunet-transport.c:453 +#: src/transport/gnunet-transport.c:466 #, fuzzy, c-format msgid "Peer `%s': %s %s\n" msgstr "Ich bin Peer `%s'.\n" -#: src/transport/gnunet-transport.c:483 +#: src/transport/gnunet-transport.c:473 +#, c-format +msgid "Peer `%s': %s \n" +msgstr "" + +#: src/transport/gnunet-transport.c:501 #, fuzzy, c-format msgid "Peer `%s' disconnected\n" msgstr "# verbundener Knoten" -#: src/transport/gnunet-transport.c:539 +#: src/transport/gnunet-transport.c:569 #, fuzzy, c-format msgid "Failed to parse peer identity `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/transport/gnunet-transport.c:587 +#: src/transport/gnunet-transport.c:618 msgid "measure how fast we are receiving data (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:590 +#: src/transport/gnunet-transport.c:621 #, fuzzy msgid "try to connect to the given peer" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/transport/gnunet-transport.c:593 +#: src/transport/gnunet-transport.c:624 #, fuzzy msgid "provide information about all current connections (once)" msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." -#: src/transport/gnunet-transport.c:596 +#: src/transport/gnunet-transport.c:627 #, fuzzy msgid "provide information about all current connections (continuously)" msgstr "Informationen Ăźber andere GNUnet Knoten ausgeben." -#: src/transport/gnunet-transport.c:599 +#: src/transport/gnunet-transport.c:630 #, fuzzy msgid "do not resolve hostnames" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/transport/gnunet-transport.c:603 +#: src/transport/gnunet-transport.c:634 msgid "send data for benchmarking to the other peer (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:606 +#: src/transport/gnunet-transport.c:637 msgid "test transport configuration (involves external server)" msgstr "" -#: src/transport/gnunet-transport.c:614 +#: src/transport/gnunet-transport.c:645 #, fuzzy msgid "Direct access to transport service." msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n" -#: src/transport/plugin_transport_http.c:981 +#: src/transport/plugin_transport_http.c:1100 msgid "Disabling IPv6 since it is not supported on this system!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1029 +#: src/transport/plugin_transport_http.c:1149 #, fuzzy msgid "Require valid port number for service in configuration!\n" msgstr "In der Konfigurationsdatei wurden keine Anwendungen definiert!\n" -#: src/transport/plugin_transport_http.c:1054 src/util/service.c:986 +#: src/transport/plugin_transport_http.c:1174 src/util/service.c:1036 #, fuzzy, c-format msgid "Failed to resolve `%s': %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/transport/plugin_transport_http.c:1071 src/util/service.c:1003 +#: src/transport/plugin_transport_http.c:1191 src/util/service.c:1053 #, fuzzy, c-format msgid "Failed to find %saddress for `%s'.\n" msgstr "Fehler beim Binden an UDP Port %d.\n" -#: src/transport/plugin_transport_http.c:1176 +#: src/transport/plugin_transport_http.c:1296 #, c-format msgid "Found %u addresses to report to NAT service\n" msgstr "" -#: src/transport/plugin_transport_http.c:1189 +#: src/transport/plugin_transport_http.c:1309 #, c-format msgid "FREEING %s\n" msgstr "" -#: src/transport/plugin_transport_http.c:1264 +#: src/transport/plugin_transport_http.c:1386 #, fuzzy msgid "Neither IPv4 nor IPv6 are enabled! Fix in configuration\n" msgstr "Netzwerkbekanntmachungen wurden per Konfiguration deaktiviert!\n" -#: src/transport/plugin_transport_http.c:1277 +#: src/transport/plugin_transport_http.c:1399 #, fuzzy msgid "Port is required! Fix in configuration\n" msgstr " gconfig\tGTK Konfiguration\n" -#: src/transport/plugin_transport_http.c:1288 +#: src/transport/plugin_transport_http.c:1410 msgid "Port 0, client only mode\n" msgstr "" -#: src/transport/plugin_transport_http.c:1308 +#: src/transport/plugin_transport_http.c:1430 #, c-format msgid "" "Specific IPv4 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1338 +#: src/transport/plugin_transport_http.c:1460 #, c-format msgid "" "Specific IPv6 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http_client.c:621 -#, c-format -msgid "Could not initialize curl multi handle, failed to start %s plugin!\n" -msgstr "" - -#: src/transport/plugin_transport_http_server.c:189 -msgid "" -"Could not create a new TLS certificate, program `gnunet-transport-" -"certificate-creation' could not be started!\n" -msgstr "" - -#: src/transport/plugin_transport_http_server.c:213 -msgid "No usable TLS certificate found and creating one failed!\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:370 -#, fuzzy, c-format -msgid "Received malformed message via %s. Ignored.\n" -msgstr "" -"Es wurde eine ungĂźltige Nachricht per SMTP empfangen (ungĂźltige Größe).\n" - -#: src/transport/plugin_transport_smtp.c:457 -#, fuzzy -msgid "SMTP filter string to invalid, lacks ': '\n" -msgstr "SMTP Filterstring zu lang, wurde auf `%s' abgeschnitten\n" - -#: src/transport/plugin_transport_smtp.c:466 +#: src/transport/plugin_transport_http_client.c:624 #, c-format -msgid "SMTP filter string to long, capped to `%s'\n" -msgstr "SMTP Filterstring zu lang, wurde auf `%s' abgeschnitten\n" - -#: src/transport/plugin_transport_smtp.c:561 -#: src/transport/plugin_transport_smtp.c:571 -#: src/transport/plugin_transport_smtp.c:584 -#: src/transport/plugin_transport_smtp.c:603 -#: src/transport/plugin_transport_smtp.c:626 -#: src/transport/plugin_transport_smtp.c:634 -#: src/transport/plugin_transport_smtp.c:647 -#: src/transport/plugin_transport_smtp.c:658 -#, fuzzy, c-format -msgid "SMTP: `%s' failed: %s.\n" -msgstr "`%s' schlug fehl: %s\n" - -#: src/transport/plugin_transport_smtp.c:801 -#, fuzzy -msgid "No email-address specified, can not start SMTP transport.\n" +msgid "Could not initialize curl multi handle, failed to start %s plugin!\n" msgstr "" -"Kein Filter fĂźr E-Mail angegeben, es kann keine Bekanntmachung erstellt " -"werden.\n" - -#: src/transport/plugin_transport_smtp.c:813 -#, fuzzy -msgid "# bytes received via SMTP" -msgstr "# Bytes empfangen Ăźber TCP" -#: src/transport/plugin_transport_smtp.c:814 -#, fuzzy -msgid "# bytes sent via SMTP" -msgstr "# Bytes gesendet Ăźber TCP" +#: src/transport/plugin_transport_http_server.c:178 +msgid "" +"Could not create a new TLS certificate, program `gnunet-transport-" +"certificate-creation' could not be started!\n" +msgstr "" -#: src/transport/plugin_transport_smtp.c:816 -#, fuzzy -msgid "# bytes dropped by SMTP (outgoing)" -msgstr "# Bytes verworfen von TCP (ausgehend)" +#: src/transport/plugin_transport_http_server.c:202 +msgid "No usable TLS certificate found and creating one failed!\n" +msgstr "" -#: src/transport/plugin_transport_tcp.c:512 +#: src/transport/plugin_transport_tcp.c:591 #, c-format msgid "Unexpected address length: %u bytes\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:616 -#: src/transport/plugin_transport_tcp.c:705 -#: src/transport/plugin_transport_tcp.c:757 -#: src/transport/plugin_transport_tcp.c:830 -#: src/transport/plugin_transport_tcp.c:909 +#: src/transport/plugin_transport_tcp.c:767 +#: src/transport/plugin_transport_tcp.c:856 +#: src/transport/plugin_transport_tcp.c:906 +#: src/transport/plugin_transport_tcp.c:992 +#: src/transport/plugin_transport_tcp.c:1086 +#: src/transport/plugin_transport_tcp.c:1103 #, fuzzy msgid "# bytes currently in TCP buffers" msgstr "# Bytes gesendet Ăźber TCP" -#: src/transport/plugin_transport_tcp.c:622 -#: src/transport/plugin_transport_tcp.c:856 -#: src/transport/plugin_transport_tcp.c:1561 +#: src/transport/plugin_transport_tcp.c:774 +#: src/transport/plugin_transport_tcp.c:963 +#: src/transport/plugin_transport_tcp.c:1761 +#: src/transport/plugin_transport_tcp.c:2390 #, fuzzy msgid "# TCP sessions active" msgstr "# SitzungsschlĂźssel akzeptiert" -#: src/transport/plugin_transport_tcp.c:709 +#: src/transport/plugin_transport_tcp.c:860 #, fuzzy msgid "# bytes discarded by TCP (timeout)" msgstr "# Bytes verworfen von TCP (ausgehend)" -#: src/transport/plugin_transport_tcp.c:760 +#: src/transport/plugin_transport_tcp.c:909 #, fuzzy msgid "# bytes transmitted via TCP" msgstr "# Bytes des Typs %d Ăźbertragen" -#: src/transport/plugin_transport_tcp.c:834 +#: src/transport/plugin_transport_tcp.c:996 #, fuzzy msgid "# bytes discarded by TCP (disconnect)" msgstr "# Bytes verworfen von TCP (ausgehend)" -#: src/transport/plugin_transport_tcp.c:1081 +#: src/transport/plugin_transport_tcp.c:1290 #, c-format msgid "Address of unexpected length: %u\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1116 -msgid "Found valid IPv4 NAT address (creating session)!\n" -msgstr "" - -#: src/transport/plugin_transport_tcp.c:1186 +#: src/transport/plugin_transport_tcp.c:1401 msgid "# transport-service disconnect requests for TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:1603 +#: src/transport/plugin_transport_tcp.c:1802 #, fuzzy msgid "# TCP WELCOME messages received" msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/transport/plugin_transport_tcp.c:1756 +#: src/transport/plugin_transport_tcp.c:1973 msgid "# bytes received via TCP" msgstr "# Bytes empfangen Ăźber TCP" -#: src/transport/plugin_transport_tcp.c:1823 +#: src/transport/plugin_transport_tcp.c:2043 msgid "# network-level TCP disconnect events" msgstr "" -#: src/transport/plugin_transport_tcp.c:1962 src/util/service.c:889 +#: src/transport/plugin_transport_tcp.c:2279 src/util/service.c:940 #, c-format msgid "Require valid port number for service `%s' in configuration!\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1976 +#: src/transport/plugin_transport_tcp.c:2293 #, fuzzy msgid "Failed to start service.\n" msgstr "Fehler beim Starten der Collection.\n" -#: src/transport/plugin_transport_tcp.c:2039 +#: src/transport/plugin_transport_tcp.c:2355 #, fuzzy, c-format msgid "Failed to find option %s in section %s!\n" msgstr "Fehler beim Binden an UDP Port %d.\n" -#: src/transport/plugin_transport_tcp.c:2062 +#: src/transport/plugin_transport_tcp.c:2378 #, fuzzy, c-format msgid "TCP transport listening on port %llu\n" msgstr "Der Transportdienst auf Port %d konnte nicht gestartet werden.\n" -#: src/transport/plugin_transport_tcp.c:2066 +#: src/transport/plugin_transport_tcp.c:2382 msgid "TCP transport not listening on any port (client only)\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2070 +#: src/transport/plugin_transport_tcp.c:2386 #, c-format msgid "TCP transport advertises itself as being on port %llu\n" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:130 +#: src/transport/plugin_transport_udp_broadcasting.c:128 #, fuzzy msgid "# IPv6 multicast HELLO beacons received via udp" msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/transport/plugin_transport_udp_broadcasting.c:172 +#: src/transport/plugin_transport_udp_broadcasting.c:169 #, fuzzy msgid "# IPv4 broadcast HELLO beacons received via udp" msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/transport/plugin_transport_udp_broadcasting.c:393 +#: src/transport/plugin_transport_udp_broadcasting.c:367 #, c-format msgid "Failed to set IPv4 broadcast option for broadcast socket on port %d\n" msgstr "" -#: src/transport/plugin_transport_udp.c:1985 +#: src/transport/plugin_transport_udp.c:1894 +#, c-format +msgid "" +"UDP could not message to `%s': `%s'. Please check your network configuration " +"and disable IPv6 if your connection does not have a global IPv6 address\n" +msgstr "" + +#: src/transport/plugin_transport_udp.c:2138 #, fuzzy msgid "Failed to open UDP sockets\n" msgstr "Fehler beim Binden an UDP6 Port %d.\n" -#: src/transport/plugin_transport_udp.c:2068 +#: src/transport/plugin_transport_udp.c:2306 #, c-format msgid "Given `%s' option is out of range: %llu > %u\n" msgstr "" -#: src/transport/plugin_transport_udp.c:2112 +#: src/transport/plugin_transport_udp.c:2349 #, fuzzy, c-format msgid "Invalid IPv6 address: `%s'\n" msgstr "UngĂźltiger Parameter: `%s'\n" -#: src/transport/plugin_transport_unix.c:1051 +#: src/transport/plugin_transport_unix.c:1356 #, fuzzy msgid "Failed to open UNIX sockets\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/transport/plugin_transport_wlan.c:875 +#: src/transport/plugin_transport_wlan.c:561 +msgid "# WLAN ACKs sent" +msgstr "" + +#: src/transport/plugin_transport_wlan.c:580 #, fuzzy -msgid "# wlan session timeouts" -msgstr "# SitzungsschlĂźssel akzeptiert" +msgid "# WLAN messages defragmented" +msgstr "# defragmentierter Nachrichten" -#: src/transport/plugin_transport_wlan.c:899 +#: src/transport/plugin_transport_wlan.c:626 +#: src/transport/plugin_transport_wlan.c:676 +#: src/transport/plugin_transport_wlan.c:1696 #, fuzzy -msgid "# wlan session created" +msgid "# WLAN sessions allocated" msgstr "# SitzungsschlĂźssel akzeptiert" -#: src/transport/plugin_transport_wlan.c:980 -#: src/transport/plugin_transport_wlan.c:1138 -#: src/transport/plugin_transport_wlan.c:1159 -#: src/transport/plugin_transport_wlan.c:1190 -#: src/transport/plugin_transport_wlan.c:2334 -#: src/transport/plugin_transport_wlan.c:3142 -msgid "# wlan pending sessions" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:1233 -#: src/transport/plugin_transport_wlan.c:1888 +#: src/transport/plugin_transport_wlan.c:749 #, fuzzy -msgid "# wlan pending fragments" -msgstr "# verworfener Nachrichten" - -#: src/transport/plugin_transport_wlan.c:1388 -#, c-format -msgid "" -"Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n" -msgstr "" +msgid "# WLAN message fragments sent" +msgstr "# fragmentierter Nachrichten" -#: src/transport/plugin_transport_wlan.c:1732 -msgid "# wlan hello beacons send" +#: src/transport/plugin_transport_wlan.c:767 +msgid "# WLAN messages pending (with fragmentation)" msgstr "" -#: src/transport/plugin_transport_wlan.c:1765 -#: src/transport/plugin_transport_wlan.c:1968 -#: src/transport/plugin_transport_wlan.c:2059 -#, c-format -msgid "Error writing to wlan helper. errno == %d, ERROR: %s\n" -msgstr "" +#: src/transport/plugin_transport_wlan.c:867 +#: src/transport/plugin_transport_wlan.c:948 +#: src/transport/plugin_transport_wlan.c:1698 +#, fuzzy +msgid "# WLAN MAC endpoints allocated" +msgstr "# Client Trace-Anfragen empfangen" -#: src/transport/plugin_transport_wlan.c:1954 -msgid "# wlan acks send" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1119 +#, fuzzy +msgid "# HELLO messages received via WLAN" +msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/transport/plugin_transport_wlan.c:2025 +#: src/transport/plugin_transport_wlan.c:1140 #, fuzzy -msgid "# wlan fragments send" +msgid "# fragments received via WLAN" msgstr "# verworfener Nachrichten" -#: src/transport/plugin_transport_wlan.c:2161 -#, c-format -msgid "Wlan Address len %d is wrong\n" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:2295 -#: src/transport/plugin_transport_wlan.c:2919 -#: src/transport/plugin_transport_wlan.c:3145 -msgid "# wlan mac endpoints" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1150 +#, fuzzy +msgid "# ACKs received via WLAN" +msgstr "# Bytes empfangen Ăźber TCP" -#: src/transport/plugin_transport_wlan.c:2517 +#: src/transport/plugin_transport_wlan.c:1207 #, fuzzy -msgid "# wlan whole messages received" -msgstr "# verschlĂźsselter PING Nachrichten empfangen" +msgid "# WLAN DATA messages discarded due to CRC32 error" +msgstr "# defragmentierter Nachrichten" -#: src/transport/plugin_transport_wlan.c:2708 +#: src/transport/plugin_transport_wlan.c:1306 #, fuzzy -msgid "# wlan hello messages received" -msgstr "# verschlĂźsselter PING Nachrichten empfangen" +msgid "# DATA messages received via WLAN" +msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/transport/plugin_transport_wlan.c:2742 +#: src/transport/plugin_transport_wlan.c:1341 #, fuzzy -msgid "# wlan fragments received" -msgstr "# verworfener Nachrichten" +msgid "# WLAN DATA messages processed" +msgstr "# verschlĂźsselter PONG Nachrichten empfangen" -#: src/transport/plugin_transport_wlan.c:2790 +#: src/transport/plugin_transport_wlan.c:1402 #, fuzzy -msgid "# wlan acks received" -msgstr "# gap Anfragen insgesamt empfangen" +msgid "# HELLO beacons sent via WLAN" +msgstr "# Bytes gesendet Ăźber UDP" -#: src/transport/plugin_transport_wlan.c:2879 -msgid "# wlan mac endpoints timeouts" +#: src/transport/plugin_transport_wlan.c:1511 +msgid "WLAN address with invalid size encountered\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:2903 -#, fuzzy -msgid "# wlan mac endpoints created" -msgstr "# Client Trace-Anfragen empfangen" +#: src/transport/plugin_transport_wlan.c:1668 +#, fuzzy, c-format +msgid "Invalid configuration option `%s' in section `%s'\n" +msgstr "Konfigurationsdatei `%s' wurde erzeugt.\n" -#: src/transport/plugin_transport_wlan.c:2956 -msgid "# wlan WLAN_HELPER_DATA received" +#: src/transport/plugin_transport_wlan.c:1677 +#, c-format +msgid "Helper binary `%s' not SUID, cannot run WLAN transport\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:3010 -#, fuzzy -msgid "# wlan messages for this client received" -msgstr "# verschlĂźsselter PING Nachrichten empfangen" - -#: src/transport/plugin_transport_wlan.c:3021 -#, fuzzy -msgid "# wlan messages inside WLAN_HELPER_DATA received" -msgstr "# verschlĂźsselter PING Nachrichten empfangen" +#: src/transport/plugin_transport_wlan.c:1687 +#, fuzzy, c-format +msgid "Missing configuration option `%s' in section `%s'\n" +msgstr "Konfigurationsdatei `%s' wurde erzeugt.\n" -#: src/transport/transport_api.c:588 +#: src/transport/transport_api.c:570 #, fuzzy, c-format msgid "Received unexpected message of type %u in %s:%u\n" msgstr "Es wurde eine unbekannte Testbed Nachricht des Typs %u empfangen.\n" @@ -5029,136 +5294,129 @@ msgstr "" msgid "Metadata `%s' failed to deserialize" msgstr "" -#: src/util/client.c:304 +#: src/util/client.c:359 #, c-format msgid "" "Could not determine valid hostname and port for service `%s' from " "configuration.\n" msgstr "" -#: src/util/client.c:312 +#: src/util/client.c:367 #, c-format msgid "Need a non-empty hostname for service `%s'.\n" msgstr "" -#: src/util/client.c:657 +#: src/util/client.c:685 msgid "Failure to transmit TEST request.\n" msgstr "" -#: src/util/client.c:717 src/util/service.c:919 +#: src/util/client.c:740 src/util/service.c:970 #, c-format msgid "UNIXPATH `%s' too long, maximum length is %llu\n" msgstr "" -#: src/util/client.c:859 +#: src/util/client.c:882 #, fuzzy, c-format msgid "Could not connect to service `%s', must not be running.\n" msgstr "Verbindung zu gnunetd konnte nicht hergestellt werden.\n" -#: src/util/client.c:875 +#: src/util/client.c:896 #, fuzzy, c-format msgid "Failure to transmit request to service `%s'\n" msgstr "Fehler beim Senden einer `%s' Anfrage an den SMTP Server.\n" -#: src/util/client.c:1143 +#: src/util/client.c:1149 msgid "Could not submit request, not expecting to receive a response.\n" msgstr "" -#: src/util/common_logging.c:239 src/util/common_logging.c:889 +#: src/util/common_logging.c:239 src/util/common_logging.c:890 msgid "DEBUG" msgstr "DEBUG" -#: src/util/common_logging.c:241 src/util/common_logging.c:887 +#: src/util/common_logging.c:241 src/util/common_logging.c:888 msgid "INFO" msgstr "INFO" -#: src/util/common_logging.c:243 src/util/common_logging.c:885 +#: src/util/common_logging.c:243 src/util/common_logging.c:886 msgid "WARNING" msgstr "WARNUNG" -#: src/util/common_logging.c:245 src/util/common_logging.c:883 +#: src/util/common_logging.c:245 src/util/common_logging.c:884 msgid "ERROR" msgstr "FEHLER" -#: src/util/common_logging.c:247 src/util/common_logging.c:891 +#: src/util/common_logging.c:247 src/util/common_logging.c:892 msgid "NONE" msgstr "" -#: src/util/common_logging.c:609 +#: src/util/common_logging.c:610 #, fuzzy, c-format msgid "Failed to create or access directory for log file `%s'\n" msgstr "Konfigurationsdatei `%s' konnte nicht geparst werden.\n" -#: src/util/common_logging.c:724 +#: src/util/common_logging.c:725 #, c-format msgid "Message `%.*s' repeated %u times in the last %s\n" msgstr "" -#: src/util/common_logging.c:892 +#: src/util/common_logging.c:893 msgid "INVALID" msgstr "" -#: src/util/common_logging.c:991 +#: src/util/common_logging.c:992 #, fuzzy msgid "unknown address" msgstr "Unbekannter Fehler" -#: src/util/common_logging.c:1029 +#: src/util/common_logging.c:1030 #, fuzzy msgid "invalid address" msgstr "UngĂźltige Parameter: " -#: src/util/configuration.c:245 +#: src/util/configuration.c:244 #, fuzzy, c-format msgid "Syntax error in configuration file `%s' at line %u.\n" msgstr "Syntaxfehler in Konfigurationsdatei `%s' in Zeile %d.\n" -#: src/util/configuration.c:817 +#: src/util/configuration.c:816 #, c-format msgid "" "Configuration value '%s' for '%s' in section '%s' is not in set of legal " "choices\n" msgstr "" -#: src/util/connection.c:460 +#: src/util/connection.c:420 #, fuzzy, c-format msgid "Access denied to `%s'\n" msgstr "Zugriff verweigert fĂźr `%s' bei %s:%d.\n" -#: src/util/connection.c:475 +#: src/util/connection.c:435 #, c-format msgid "Accepting connection from `%s': %p\n" msgstr "" -#: src/util/connection.c:629 +#: src/util/connection.c:550 #, fuzzy, c-format msgid "" "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n" msgstr "Fehler beim Aufbauen einer Verbindung mit gnunetd.\n" -#: src/util/connection.c:821 src/util/connection.c:992 +#: src/util/connection.c:739 src/util/connection.c:909 #, fuzzy, c-format msgid "Trying to connect to `%s' (%p)\n" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/util/connection.c:830 +#: src/util/connection.c:748 #, fuzzy, c-format msgid "Failed to connect to `%s' (%p)\n" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/util/connection.c:983 +#: src/util/connection.c:900 #, fuzzy, c-format msgid "Attempt to connect to `%s' failed\n" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/util/connection.c:1465 -#, c-format -msgid "" -"Could not satisfy pending transmission request, socket closed or connect " -"failed (%p).\n" -msgstr "" - -#: src/util/container_bloomfilter.c:507 +#: src/util/container_bloomfilter.c:510 #, c-format msgid "" "Size of file on disk is incorrect for this Bloom filter (want %llu, have " @@ -5176,128 +5434,128 @@ msgid "libgcrypt has not the expected version (version %s is required).\n" msgstr "" "libgcrypt hat nicht die erwartete Version (Version %s wird vorausgesetzt).\n" -#: src/util/crypto_rsa.c:618 src/util/crypto_rsa.c:665 +#: src/util/crypto_rsa.c:661 src/util/crypto_rsa.c:708 #, fuzzy, c-format msgid "Could not aquire lock on file `%s': %s...\n" msgstr "PID konnte nicht in Datei `%s' geschrieben werden: %s.\n" -#: src/util/crypto_rsa.c:623 +#: src/util/crypto_rsa.c:666 #, fuzzy msgid "Creating a new private key. This may take a while.\n" msgstr "Ein neuer Hostkey wird erzeugt (dies kann eine Weile dauern).\n" -#: src/util/crypto_rsa.c:641 +#: src/util/crypto_rsa.c:684 #, c-format msgid "I am host `%s'. Stored new private key in `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:669 src/util/crypto_rsa.c:705 +#: src/util/crypto_rsa.c:712 src/util/crypto_rsa.c:748 msgid "This may be ok if someone is currently generating a hostkey.\n" msgstr "" -#: src/util/crypto_rsa.c:700 +#: src/util/crypto_rsa.c:743 #, c-format msgid "" "When trying to read hostkey file `%s' I found %u bytes but I need at least " "%u.\n" msgstr "" -#: src/util/crypto_rsa.c:720 +#: src/util/crypto_rsa.c:763 #, fuzzy, c-format msgid "File `%s' does not contain a valid private key. Deleting it.\n" msgstr "Die Datei `%s' enthält kein Pseudonym.\n" -#: src/util/crypto_rsa.c:738 +#: src/util/crypto_rsa.c:781 #, fuzzy, c-format msgid "I am host `%s'. Read private key from `%s'.\n" msgstr "Aufruf von `%s' mit SchlĂźssel `%s'.\n" -#: src/util/crypto_rsa.c:959 +#: src/util/crypto_rsa.c:1032 #, c-format msgid "RSA signature verification failed at %s:%d: %s\n" msgstr "RSA SignaturĂźberprĂźfung fehlgeschlagen bei %s:%d: %s\n" -#: src/util/disk.c:479 +#: src/util/disk.c:498 #, fuzzy, c-format msgid "`%s' failed for drive `%S': %u\n" msgstr "`%s' fehlgeschlagen fĂźr Laufwerk %s: %u\n" -#: src/util/disk.c:1087 +#: src/util/disk.c:1062 #, fuzzy, c-format msgid "Expected `%s' to be a directory!\n" msgstr "`%s' erwartet, dass `%s' ein Verzeichnis ist!\n" -#: src/util/disk.c:1441 src/util/service.c:1580 +#: src/util/disk.c:1416 src/util/service.c:1650 #, fuzzy, c-format msgid "Cannot obtain information about user `%s': %s\n" msgstr "Fehler beim Speichern der Konfigurationsdatei: `%s': %s.\n" -#: src/util/disk.c:1759 +#: src/util/disk.c:1734 #, fuzzy, c-format msgid "No `%s' specified for service `%s' in configuration.\n" msgstr "In der Konfigurationsdatei wurden keine Anwendungen definiert!\n" -#: src/util/getopt.c:672 +#: src/util/getopt.c:669 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "%s: Option `%s' ist mehrdeutig\n" -#: src/util/getopt.c:696 +#: src/util/getopt.c:693 #, c-format msgid "%s: option `--%s' does not allow an argument\n" msgstr "%s: Option '--%s' erlaubt keinen Parameter\n" -#: src/util/getopt.c:701 +#: src/util/getopt.c:698 #, c-format msgid "%s: option `%c%s' does not allow an argument\n" msgstr "%s: Option '%c%s' erlaubt keinen Parameter\n" -#: src/util/getopt.c:718 src/util/getopt.c:886 +#: src/util/getopt.c:715 src/util/getopt.c:883 #, c-format msgid "%s: option `%s' requires an argument\n" msgstr "%s: Option `%s' benĂśtigt einen Parameter\n" -#: src/util/getopt.c:747 +#: src/util/getopt.c:744 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "%s: unbekannte Option '--%s'\n" -#: src/util/getopt.c:751 +#: src/util/getopt.c:748 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "%s: unbekannte Option '%c%s'\n" -#: src/util/getopt.c:776 +#: src/util/getopt.c:773 #, c-format msgid "%s: illegal option -- %c\n" msgstr "%s: unerlaubte Option -- %c\n" -#: src/util/getopt.c:778 +#: src/util/getopt.c:775 #, c-format msgid "%s: invalid option -- %c\n" msgstr "%s: ungĂźltige Option -- %c\n" -#: src/util/getopt.c:806 src/util/getopt.c:934 +#: src/util/getopt.c:803 src/util/getopt.c:931 #, c-format msgid "%s: option requires an argument -- %c\n" msgstr "%s: Option benĂśtigt einen Parameter -- %c\n" -#: src/util/getopt.c:854 +#: src/util/getopt.c:851 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "%s: Option '-W %s' ist mehrdeutig\n" -#: src/util/getopt.c:872 +#: src/util/getopt.c:869 #, c-format msgid "%s: option `-W %s' does not allow an argument\n" msgstr "%s: Option '-W %s' erlaubt keinen Parameter\n" -#: src/util/getopt.c:1038 +#: src/util/getopt.c:1035 #, fuzzy, c-format msgid "Use %s to get a list of options.\n" msgstr "Verwenden Sie --help, um eine Liste der Optionen zu erhalten.\n" -#: src/util/getopt_helpers.c:84 +#: src/util/getopt_helpers.c:86 #, c-format msgid "" "Arguments mandatory for long options are also mandatory for short options.\n" @@ -5305,7 +5563,7 @@ msgstr "" "Parameter, die fĂźr lange Optionen zwingend sind, sind auch fĂźr kurze " "Optionen zwingend.\n" -#: src/util/getopt_helpers.c:255 src/util/getopt_helpers.c:283 +#: src/util/getopt_helpers.c:258 src/util/getopt_helpers.c:286 #, c-format msgid "You must pass a number to the `%s' option.\n" msgstr "Sie mĂźssen fĂźr die Option `%s' zusätzlich eine Zahl angeben.\n" @@ -5318,6 +5576,27 @@ msgstr "" msgid "Use build-in GNUnet stub resolver" msgstr "" +#: src/util/gnunet-rsa.c:64 +#, c-format +msgid "No hostkey file specified on command line\n" +msgstr "" + +#: src/util/gnunet-rsa.c:112 +msgid "print the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:115 +msgid "print the hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:118 +msgid "print the short hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:124 +msgid "Manipulate GNUnet private RSA key files" +msgstr "" + #: src/util/gnunet-service-resolver.c:288 #, fuzzy, c-format msgid "Could not resolve `%s' (%s): %s\n" @@ -5329,42 +5608,37 @@ msgstr "`%s' konnte nicht aufgelĂśst werden: %s\n" msgid "Could not find IP of host `%s': %s\n" msgstr "IP des Hosts `%s' konnte nicht ermittelt werden: %s\n" -#: src/util/gnunet-service-resolver.c:494 -#, c-format -msgid "Resolver asked to look up `%s'.\n" -msgstr "" - -#: src/util/gnunet-service-resolver.c:529 -#, c-format -msgid "Resolver asked to look up IP address `%s'.\n" -msgstr "" - -#: src/util/helper.c:239 +#: src/util/helper.c:244 #, fuzzy, c-format msgid "Error reading from `%s': %s\n" msgstr "Fehler beim Anlegen des Benutzers" -#: src/util/helper.c:254 +#: src/util/helper.c:259 #, c-format msgid "Got 0 bytes from helper `%s' (EOF)\n" msgstr "" -#: src/util/helper.c:264 +#: src/util/helper.c:269 #, fuzzy, c-format msgid "Got %u bytes from helper `%s'\n" msgstr "GAP hat ungĂźltige Inhalte von `%s' empfangen.\n" -#: src/util/helper.c:273 +#: src/util/helper.c:278 #, fuzzy, c-format msgid "Failed to parse inbound message from helper `%s'\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/util/helper.c:432 +#: src/util/helper.c:310 +#, fuzzy, c-format +msgid "Starting HELPER process `%s'\n" +msgstr "Collection `%s' begonnen.\n" + +#: src/util/helper.c:440 #, fuzzy, c-format msgid "Error writing to `%s': %s\n" msgstr "Fehler beim Anlegen des Benutzers" -#: src/util/network.c:1196 +#: src/util/network.c:1200 #, c-format msgid "" "Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n" @@ -5392,12 +5666,12 @@ msgstr "`%s' schlug fehl: %s\n" msgid "stat (%s) failed: %s\n" msgstr "`%s' schlug fehl: %s\n" -#: src/util/os_priority.c:304 +#: src/util/os_priority.c:305 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for reading: %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" -#: src/util/os_priority.c:305 +#: src/util/os_priority.c:306 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for writing: %s\n" msgstr "Datei wurde als `%s' gespeichert.\n" @@ -5423,12 +5697,12 @@ msgstr "`%s' fehlgeschlagen fĂźr die Bibliothek `%s'. Ort: %s:%d. Fehler: %s\n" msgid "Could not determine plugin installation path.\n" msgstr "Öffentliche IP-Adresse konnte nicht ermittelt werden.\n" -#: src/util/pseudonym.c:273 +#: src/util/pseudonym.c:276 #, fuzzy, c-format msgid "Failed to parse metadata about pseudonym from file `%s': %s\n" msgstr "Fehler beim Parsen der Gerätedaten von `%s' bei %s:%d.\n" -#: src/util/pseudonym.c:338 +#: src/util/pseudonym.c:407 src/util/pseudonym.c:433 #, fuzzy msgid "no-name" msgstr "Name anzeigen" @@ -5446,187 +5720,167 @@ msgstr "" "Sie mĂźssen fĂźr `%s' in der Sektion `%s' der Konfigurationsdatei eine " "positive Zahl angeben.\n" -#: src/util/resolver_api.c:351 +#: src/util/resolver_api.c:347 #, fuzzy, c-format msgid "Timeout trying to resolve IP address `%s'.\n" msgstr "GNUnet verwendet nun die IP-Adresse %u.%u.%u.%u.\n" -#: src/util/resolver_api.c:355 +#: src/util/resolver_api.c:351 #, fuzzy, c-format msgid "Timeout trying to resolve hostname `%s'.\n" msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#: src/util/resolver_api.c:426 -#, c-format -msgid "Resolver returns `%s' for IP `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:807 -#, c-format -msgid "Resolver returns `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:901 -#, c-format -msgid "Resolving our FQDN `%s'\n" -msgstr "" - -#: src/util/resolver_api.c:906 +#: src/util/resolver_api.c:890 #, fuzzy, c-format msgid "Could not resolve our FQDN : %s\n" msgstr "`%s' konnte nicht aufgelĂśst werden: %s\n" -#: src/util/resolver_api.c:938 -#, c-format -msgid "Resolving our hostname `%s'\n" -msgstr "" - -#: src/util/scheduler.c:866 +#: src/util/scheduler.c:786 msgid "Looks like we're busy waiting...\n" msgstr "" -#: src/util/scheduler.c:996 +#: src/util/scheduler.c:916 #, c-format msgid "Attempt to cancel dead task %llu!\n" msgstr "" -#: src/util/server.c:397 +#: src/util/server.c:483 #, fuzzy, c-format msgid "`%s' failed for port %d (%s).\n" msgstr "`%s' fehlgeschlagen fĂźr Laufwerk %s: %u\n" -#: src/util/server.c:406 +#: src/util/server.c:492 #, fuzzy, c-format msgid "`%s' failed for port %d (%s): address already in use\n" msgstr "`%s' schlug fehl fĂźr Port %d: %s. Läuft gnunetd bereits?\n" -#: src/util/server.c:411 +#: src/util/server.c:497 #, fuzzy, c-format msgid "`%s' failed for `%s': address already in use\n" msgstr "`%s' schlug fehl fĂźr Port %d: %s. Läuft gnunetd bereits?\n" -#: src/util/server.c:640 +#: src/util/server.c:827 #, c-format msgid "" "Processing code for message of type %u did not call " "GNUNET_SERVER_receive_done after %llums\n" msgstr "" -#: src/util/service.c:117 src/util/service.c:143 src/util/service.c:186 -#: src/util/service.c:207 src/util/service.c:214 +#: src/util/service.c:135 src/util/service.c:161 src/util/service.c:204 +#: src/util/service.c:225 src/util/service.c:232 #, c-format msgid "Invalid format for IP: `%s'\n" msgstr "UngĂźltiges Format fĂźr IP: `%s'\n" -#: src/util/service.c:170 +#: src/util/service.c:188 #, c-format msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)." msgstr "UngĂźltige Netzwerk Notation ('/%d ist nicht gĂźltig in IPv4 CIDR)." -#: src/util/service.c:263 +#: src/util/service.c:281 #, c-format msgid "Invalid network notation (does not end with ';': `%s')\n" msgstr "UngĂźltige Netzwerk Notation (endet nicht mit ';': `%s')\n" -#: src/util/service.c:296 +#: src/util/service.c:313 #, fuzzy, c-format msgid "Wrong format `%s' for netmask\n" msgstr "Falsches Format `%s' fĂźr Netzmaske: %s\n" -#: src/util/service.c:326 +#: src/util/service.c:343 #, fuzzy, c-format msgid "Wrong format `%s' for network\n" msgstr "Falsches Format `%s' fĂźr Netzwerk: %s\n" -#: src/util/service.c:668 +#: src/util/service.c:698 #, c-format msgid "Access denied to UID %d / GID %d\n" msgstr "" -#: src/util/service.c:673 +#: src/util/service.c:703 #, fuzzy, c-format msgid "Unknown address family %d\n" msgstr "Unbekannte Operation `%s'\n" -#: src/util/service.c:680 +#: src/util/service.c:710 #, c-format msgid "Access from `%s' denied to service `%s'\n" msgstr "" -#: src/util/service.c:724 +#: src/util/service.c:765 #, c-format msgid "Could not parse IPv4 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:752 +#: src/util/service.c:802 #, c-format msgid "Could not parse IPv6 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:869 +#: src/util/service.c:920 #, c-format msgid "" "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n" msgstr "" -#: src/util/service.c:939 +#: src/util/service.c:990 #, c-format msgid "" "Disabling UNIX domain socket support for service `%s', failed to create UNIX " "domain socket: %s\n" msgstr "" -#: src/util/service.c:956 +#: src/util/service.c:1007 #, c-format msgid "Have neither PORT nor UNIXPATH for service `%s', but one is required\n" msgstr "" -#: src/util/service.c:1191 +#: src/util/service.c:1241 msgid "Could not access a pre-bound socket, will try to bind myself\n" msgstr "" -#: src/util/service.c:1242 src/util/service.c:1260 +#: src/util/service.c:1292 src/util/service.c:1310 #, c-format msgid "Specified value for `%s' of service `%s' is invalid\n" msgstr "" -#: src/util/service.c:1287 +#: src/util/service.c:1337 #, c-format msgid "Could not access pre-bound socket %u, will try to bind myself\n" msgstr "" -#: src/util/service.c:1442 +#: src/util/service.c:1506 #, fuzzy, c-format msgid "Failed to start `%s' at `%s'\n" msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#: src/util/service.c:1475 +#: src/util/service.c:1539 #, fuzzy, c-format msgid "Service `%s' runs at %s\n" msgstr "Knoten `%s' mit Vertrauen %8u und Adresse `%s'\n" -#: src/util/service.c:1521 +#: src/util/service.c:1588 msgid "Service process failed to initialize\n" msgstr "" -#: src/util/service.c:1525 +#: src/util/service.c:1592 msgid "Service process could not initialize server function\n" msgstr "" -#: src/util/service.c:1529 +#: src/util/service.c:1596 msgid "Service process failed to report status\n" msgstr "" -#: src/util/service.c:1581 +#: src/util/service.c:1651 msgid "No such user" msgstr "" -#: src/util/service.c:1594 +#: src/util/service.c:1664 #, c-format msgid "Cannot change user/group to `%s': %s\n" msgstr "Benutzer/Gruppe kann nicht zu `%s' gewechselt werden: %s\n" -#: src/util/service.c:1657 +#: src/util/service.c:1729 msgid "do daemonize (detach from terminal)" msgstr "" @@ -5635,55 +5889,76 @@ msgstr "" msgid "signal (%d, %p) returned %d.\n" msgstr "Aufruf von `%s' gibt %d zurĂźck.\n" -#: src/util/strings.c:143 +#: src/util/strings.c:144 msgid "b" msgstr "b" -#: src/util/strings.c:354 +#: src/util/strings.c:334 #, c-format msgid "Character sets requested were `%s'->`%s'\n" msgstr "" -#: src/util/strings.c:462 +#: src/util/strings.c:481 msgid "Failed to expand `$HOME': environment variable `HOME' not set" msgstr "" -#: src/util/strings.c:554 +#: src/util/strings.c:573 msgid "ms" msgstr "ms" -#: src/util/strings.c:559 +#: src/util/strings.c:578 msgid "eternity" msgstr "" -#: src/util/strings.c:563 +#: src/util/strings.c:582 msgid "s" msgstr "s" -#: src/util/strings.c:567 +#: src/util/strings.c:586 msgid "m" msgstr "m" -#: src/util/strings.c:571 +#: src/util/strings.c:590 msgid "h" msgstr "h" -#: src/util/strings.c:575 +#: src/util/strings.c:594 msgid " days" msgstr " Tage" -#: src/util/strings.c:599 +#: src/util/strings.c:618 msgid "end of time" msgstr "" -#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1065 +#: src/util/strings.c:1012 +msgid "IPv6 address did not start with `['\n" +msgstr "" + +#: src/util/strings.c:1020 +msgid "IPv6 address did contain ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1026 +msgid "IPv6 address did contain ']' before ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1033 +msgid "IPv6 address did contain a valid port number after the last ':'\n" +msgstr "" + +#: src/util/strings.c:1042 +#, fuzzy, c-format +msgid "Invalid IPv6 address `%s': %s\n" +msgstr "UngĂźltiger Parameter: `%s'\n" + +#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1071 #, fuzzy msgid "# Active tunnels" msgstr "GNUnet Konfiguration" #: src/vpn/gnunet-service-vpn.c:608 src/vpn/gnunet-service-vpn.c:645 #, fuzzy -msgid "# Peers connected to mesh tunnels" +msgid "# peers connected to mesh tunnels" msgstr "# verbundener Knoten" #: src/vpn/gnunet-service-vpn.c:699 @@ -5706,76 +5981,76 @@ msgstr "# dht Anfragen weitergeleitet" msgid "Failed to setup mesh tunnel!\n" msgstr "Statistiken Ăźber den Netzwerkverkehr konnten nicht ermittelt werden.\n" -#: src/vpn/gnunet-service-vpn.c:967 +#: src/vpn/gnunet-service-vpn.c:973 #, c-format msgid "Protocol %u not supported, dropping\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1285 +#: src/vpn/gnunet-service-vpn.c:1291 msgid "# ICMPv4 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1306 +#: src/vpn/gnunet-service-vpn.c:1312 msgid "# ICMPv6 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1511 +#: src/vpn/gnunet-service-vpn.c:1517 #, fuzzy msgid "# Packets received from TUN interface" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/vpn/gnunet-service-vpn.c:1549 src/vpn/gnunet-service-vpn.c:1590 +#: src/vpn/gnunet-service-vpn.c:1555 src/vpn/gnunet-service-vpn.c:1596 #, c-format msgid "Packet received for unmapped destination `%s' (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1600 +#: src/vpn/gnunet-service-vpn.c:1606 msgid "Received IPv4 packet with options (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1614 +#: src/vpn/gnunet-service-vpn.c:1620 #, c-format msgid "Received packet of unknown protocol %d from TUN (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1697 +#: src/vpn/gnunet-service-vpn.c:1704 #, fuzzy msgid "# ICMP packets received from mesh" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/vpn/gnunet-service-vpn.c:2038 +#: src/vpn/gnunet-service-vpn.c:2045 #, fuzzy msgid "# UDP packets received from mesh" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/vpn/gnunet-service-vpn.c:2196 +#: src/vpn/gnunet-service-vpn.c:2203 #, fuzzy msgid "# TCP packets received from mesh" msgstr "Empfangene Client-Nachricht ist ungĂźltig.\n" -#: src/vpn/gnunet-service-vpn.c:2347 +#: src/vpn/gnunet-service-vpn.c:2354 msgid "Failed to find unallocated IPv4 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2402 +#: src/vpn/gnunet-service-vpn.c:2409 #, fuzzy msgid "Failed to find unallocated IPv6 address in VPN's range\n" msgstr "Die Ăśffentliche IPv6-Adresse konnte nicht ermittelt werden!\n" -#: src/vpn/gnunet-service-vpn.c:2441 src/vpn/gnunet-service-vpn.c:2624 +#: src/vpn/gnunet-service-vpn.c:2448 src/vpn/gnunet-service-vpn.c:2661 #, fuzzy msgid "# Active destinations" msgstr "GNUnet Konfiguration" -#: src/vpn/gnunet-service-vpn.c:2726 +#: src/vpn/gnunet-service-vpn.c:2734 msgid "Failed to allocate IP address for new destination\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3133 +#: src/vpn/gnunet-service-vpn.c:3141 msgid "IPv6 support disabled as this system does not support IPv6\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3165 +#: src/vpn/gnunet-service-vpn.c:3173 msgid "IPv4 support disabled as this system does not support IPv4\n" msgstr "" @@ -5851,22 +6126,176 @@ msgstr "# Bytes empfangen Ăźber UDP" msgid "Setup tunnels via VPN." msgstr "" -#: src/include/gnunet_common.h:479 src/include/gnunet_common.h:484 -#: src/include/gnunet_common.h:490 +#: src/include/gnunet_common.h:497 src/include/gnunet_common.h:502 +#: src/include/gnunet_common.h:508 #, fuzzy, c-format msgid "Assertion failed at %s:%d.\n" msgstr "Absicherung fehlgeschlagen bei %s:%d.\n" -#: src/include/gnunet_common.h:500 +#: src/include/gnunet_common.h:518 #, fuzzy, c-format msgid "External protocol violation detected at %s:%d.\n" msgstr "Absicherung fehlgeschlagen bei %s:%d.\n" -#: src/include/gnunet_common.h:521 src/include/gnunet_common.h:528 +#: src/include/gnunet_common.h:539 src/include/gnunet_common.h:546 #, fuzzy, c-format msgid "`%s' failed on file `%s' at %s:%d with error: %s\n" msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" +#, fuzzy +#~ msgid "Received malformed message via %s. Ignored.\n" +#~ msgstr "" +#~ "Es wurde eine ungĂźltige Nachricht per SMTP empfangen (ungĂźltige Größe).\n" + +#, fuzzy +#~ msgid "SMTP filter string to invalid, lacks ': '\n" +#~ msgstr "SMTP Filterstring zu lang, wurde auf `%s' abgeschnitten\n" + +#~ msgid "SMTP filter string to long, capped to `%s'\n" +#~ msgstr "SMTP Filterstring zu lang, wurde auf `%s' abgeschnitten\n" + +#, fuzzy +#~ msgid "SMTP: `%s' failed: %s.\n" +#~ msgstr "`%s' schlug fehl: %s\n" + +#, fuzzy +#~ msgid "No email-address specified, can not start SMTP transport.\n" +#~ msgstr "" +#~ "Kein Filter fĂźr E-Mail angegeben, es kann keine Bekanntmachung erstellt " +#~ "werden.\n" + +#, fuzzy +#~ msgid "# bytes received via SMTP" +#~ msgstr "# Bytes empfangen Ăźber TCP" + +#, fuzzy +#~ msgid "# bytes sent via SMTP" +#~ msgstr "# Bytes gesendet Ăźber TCP" + +#, fuzzy +#~ msgid "# bytes dropped by SMTP (outgoing)" +#~ msgstr "# Bytes verworfen von TCP (ausgehend)" + +#, fuzzy +#~ msgid "# Peers connected" +#~ msgstr "# verbundener Knoten" + +#, fuzzy +#~ msgid "%s failed for `%s' at %s:%d: `%s'\n" +#~ msgstr "`%s' schlug fehl bei %s:%d mit dem Fehler: `%s'.\n" + +#, fuzzy +#~ msgid "Failed to transmit shutdown ACK.\n" +#~ msgstr "Fehler beim Starten der Collection.\n" + +#, fuzzy +#~ msgid "Unable to initialize Postgres with configuration `%s': %s" +#~ msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':" + +#, fuzzy +#~ msgid "Failed to transmit message to `%s' service.\n" +#~ msgstr "`%s' Dienst konnte nicht initialisiert werden.\n" + +#, fuzzy +#~ msgid "Target is %d connections per peer." +#~ msgstr "Fehler beim Aufbauen einer Verbindung mit gnunetd.\n" + +#, fuzzy +#~ msgid "Copying file with RENAME (%s,%s)\n" +#~ msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" + +#, fuzzy +#~ msgid "Copying file with command scp %s %s\n" +#~ msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" + +#, fuzzy +#~ msgid "Finished copying all blacklist files!\n" +#~ msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" + +#, fuzzy +#~ msgid "Offering HELLO of peer %s to peer %s\n" +#~ msgstr "Verbindung zu %u.%u.%u.%u:%u fehlgeschlagen: %s\n" + +#, fuzzy +#~ msgid "Failed during blacklist file copying!\n" +#~ msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" + +#, fuzzy +#~ msgid "# bytes payload received for other peers" +#~ msgstr "# Bytes des Typs %d empfangen" + +#, fuzzy +#~ msgid "# fast reconnects failed" +#~ msgstr "# verbundener Knoten" + +#, fuzzy +#~ msgid "# peers disconnected due to timeout" +#~ msgstr "# geschlossener Verbindungen (HANGUP gesendet)" + +#, fuzzy +#~ msgid "# peers disconnected due to global disconnect" +#~ msgstr "# KnotenankĂźndigungen empfangen" + +#, fuzzy +#~ msgid "# messages not sent (no such peer or not connected)" +#~ msgstr "# defragmentierter Nachrichten" + +#, fuzzy +#~ msgid "# unexpected CONNECT_ACK messages" +#~ msgstr "COUNT Nachrichten versenden" + +#, fuzzy +#~ msgid "# wlan session timeouts" +#~ msgstr "# SitzungsschlĂźssel akzeptiert" + +#, fuzzy +#~ msgid "# wlan session created" +#~ msgstr "# SitzungsschlĂźssel akzeptiert" + +#, fuzzy +#~ msgid "# wlan pending fragments" +#~ msgstr "# verworfener Nachrichten" + +#, fuzzy +#~ msgid "# wlan fragments send" +#~ msgstr "# verworfener Nachrichten" + +#, fuzzy +#~ msgid "# wlan whole messages received" +#~ msgstr "# verschlĂźsselter PING Nachrichten empfangen" + +#, fuzzy +#~ msgid "# wlan hello messages received" +#~ msgstr "# verschlĂźsselter PING Nachrichten empfangen" + +#, fuzzy +#~ msgid "# wlan fragments received" +#~ msgstr "# verworfener Nachrichten" + +#, fuzzy +#~ msgid "# wlan acks received" +#~ msgstr "# gap Anfragen insgesamt empfangen" + +#, fuzzy +#~ msgid "# wlan messages for this client received" +#~ msgstr "# verschlĂźsselter PING Nachrichten empfangen" + +#, fuzzy +#~ msgid "# wlan messages inside WLAN_HELPER_DATA received" +#~ msgstr "# verschlĂźsselter PING Nachrichten empfangen" + +#, fuzzy +#~ msgid "Unknown user `%s'\n" +#~ msgstr "Unbekannte Operation `%s'\n" + +#, fuzzy +#~ msgid "Namespace `%s' unknown.\n" +#~ msgstr "Namespace `%s' hat das Rating %d.\n" + +#, fuzzy +#~ msgid "Failed to connect to statistics service!\n" +#~ msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" + #, fuzzy #~ msgid "Failed to send to `%s': %s\n" #~ msgstr "Datei wurde als `%s' gespeichert.\n" @@ -5933,10 +6362,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "Unable to accept connection for service `%s': %s\n" #~ msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':" -#, fuzzy -#~ msgid "Service `%s' started\n" -#~ msgstr "Dienst gelĂśscht.\n" - #, fuzzy #~ msgid "Peer `%s' plugin: `%s' address `%s'\n" #~ msgstr "Knoten `%s' mit Vertrauen %8u und Adresse `%s'\n" @@ -5961,14 +6386,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "Failed to load dhtlog plugin for `%s'\n" #~ msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" -#, fuzzy -#~ msgid "Failed to get full path for `%s'\n" -#~ msgstr "Fehler beim Aktualisieren der Daten des Moduls `%s'\n" - -#, fuzzy -#~ msgid "Failed to create file for dhtlog.\n" -#~ msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" - #, fuzzy #~ msgid "Found peer `%s'\n" #~ msgstr "Ich bin Peer `%s'.\n" @@ -5981,10 +6398,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "Loading udp transport plugin\n" #~ msgstr "Teste Transport(e) %s\n" -#, fuzzy -#~ msgid "Failed to load transport plugin for udp\n" -#~ msgstr "Anwendung `%s' konnte nicht initialisiert werden.\n" - #, fuzzy #~ msgid "# SET QUOTA messages received" #~ msgstr "# verschlĂźsselter PONG Nachrichten empfangen" @@ -6111,9 +6524,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "Ok" #~ msgstr "k" -#~ msgid "GNUnet configuration" -#~ msgstr "GNUnet Konfiguration" - #~ msgid "" #~ "Welcome to GNUnet!\n" #~ "\n" @@ -6369,9 +6779,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ "Your configuration changes were NOT saved.\n" #~ msgstr "Konfigurationsdatei `%s' wurde erzeugt.\n" -#~ msgid "GNUnet service installed successfully.\n" -#~ msgstr "Der GNUnet Dienst wurde erfolgreich installiert.\n" - #~ msgid "This version of Windows doesn't support services.\n" #~ msgstr "Diese Version von Windows unterstĂźtzt keine Dienste.\n" @@ -6596,10 +7003,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "`%s' failed with error code %d: %s\n" #~ msgstr "`%s' schlug bei %s:%d mit dem Fehler %s fehl\n" -#, fuzzy -#~ msgid "Invalid argument for `%s'.\n" -#~ msgstr "UngĂźltiger Parameter: `%s'\n" - #, fuzzy #~ msgid "Deadlock due to `%s'.\n" #~ msgstr "Durch `%s' ist ein Deadlock bei %s:%d entstanden\n" @@ -6876,9 +7279,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "Command `%s' requires two arguments (`%s' and `%s').\n" #~ msgstr "Kommando `%s' benĂśtigt zwei zusätzliche Angaben (`%s' und `%s').\n" -#~ msgid "Unsupported command `%s'. Aborting.\n" -#~ msgstr "Kommando `%s' wird nicht unterstĂźtzt. Vorgang wird abgebrochen.\n" - #, fuzzy #~ msgid "# dht discovery messages sent" #~ msgstr "# verschlĂźsselter PING Nachrichten empfangen" @@ -7223,10 +7623,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "Downloading %d files from directory `%s'.\n" #~ msgstr "Dateien aus dem GNUnet herunterladen." -#, fuzzy -#~ msgid "Did not find any files in directory `%s'\n" -#~ msgstr "Fehler beim Lesen der Freunde-Liste von `%s'\n" - #~ msgid "File stored as `%s'.\n" #~ msgstr "Datei wurde als `%s' gespeichert.\n" @@ -7289,10 +7685,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "# gap requests total received" #~ msgstr "# gap Anfragen insgesamt empfangen" -#, fuzzy -#~ msgid "# gap content total received" -#~ msgstr "# gap Anfragen insgesamt empfangen" - #, fuzzy #~ msgid "" #~ "`%s' registering client handlers %d %d %d %d %d %d %d %d and P2P handlers " @@ -7349,10 +7741,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "Friend list of %s:%d\n" #~ msgstr "Es konnte keine Verbindung mit gnunetd hergestellt werden.\n" -#, fuzzy -#~ msgid "set number of daemons to start" -#~ msgstr "Anzahl an Nachrichten, die pro Durchlauf verwendet wird" - #, fuzzy #~ msgid "Waiting for peers to connect" #~ msgstr "" @@ -9027,9 +9415,6 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ "Der Assistent kann nur zur Einrichtung von gnunetd gestartet werden.\n" #~ "Haben Sie die `%s'-Option vergessen?\n" -#~ msgid "%s: symbol value `%s' invalid for %s\n" -#~ msgstr "%s: Symbolwert `%s' ist ungĂźltig fĂźr %s\n" - #~ msgid "Gtk GNUnet Configurator" #~ msgstr "Gtk GNUnet Konfigurator" @@ -9376,6 +9761,3 @@ msgstr "`%s' schlug bei Datei `%s' fehl. Ort: %s:%d. Fehler: %s\n" #~ msgid "Error: can't create service: %s (#%i)\n" #~ msgstr "Fehler: Dienst konnte nicht erzeugt werden: %s (#%i)\n" - -#~ msgid "Failure at at %s:%d.\n" -#~ msgstr "Fehler bei %s:%d.\n" diff --git a/po/es.gmo b/po/es.gmo index a3b0ad6..07ff667 100644 Binary files a/po/es.gmo and b/po/es.gmo differ diff --git a/po/es.po b/po/es.po index 83d1065..0174aca 100644 --- a/po/es.po +++ b/po/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GNUnet 0.7.0e\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2012-02-28 18:30+0100\n" +"POT-Creation-Date: 2012-06-05 15:47+0200\n" "PO-Revision-Date: 2006-06-29 12:05+0200\n" "Last-Translator: Miguel Angel Arruga \n" "Language-Team: Spanish\n" @@ -17,260 +17,275 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/arm/arm_api.c:187 +#: src/arm/arm_api.c:165 msgid "Failed to transmit shutdown request to client.\n" msgstr "" -#: src/arm/arm_api.c:378 +#: src/arm/arm_api.c:349 #, fuzzy, c-format msgid "Configuration failes to specify option `%s' in section `%s'!\n" msgstr "" "El fichero de configuraciĂłn debe especificar el directorio para almacenar " "los datos FS en la secciĂłn '%s' bajo '%s'.\n" -#: src/arm/arm_api.c:392 +#: src/arm/arm_api.c:363 #, fuzzy, c-format msgid "Configuration fails to specify option `%s' in section `%s'!\n" msgstr "" "El fichero de configuraciĂłn debe especificar el directorio para almacenar " "los datos FS en la secciĂłn '%s' bajo '%s'.\n" -#: src/arm/arm_api.c:467 +#: src/arm/arm_api.c:432 #, fuzzy, c-format msgid "Error receiving response to `%s' request from ARM for service `%s'\n" msgstr "Recibida respuesta anĂłmala a'%s' del par '%s'.\n" -#: src/arm/arm_api.c:523 +#: src/arm/arm_api.c:485 #, c-format msgid "Requesting start of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:524 +#: src/arm/arm_api.c:486 #, c-format msgid "Requesting termination of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:546 +#: src/arm/arm_api.c:507 #, c-format msgid "Error while trying to transmit request to start `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:548 +#: src/arm/arm_api.c:508 #, c-format msgid "Error while trying to transmit request to stop `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:581 +#: src/arm/arm_api.c:540 #, fuzzy, c-format msgid "Asked to start service `%s' within %llu ms\n" msgstr "'%s': No se recibiĂł el mensaje en %llu ms.\n" -#: src/arm/arm_api.c:654 +#: src/arm/arm_api.c:612 #, fuzzy, c-format msgid "Stopping service `%s' within %llu ms\n" msgstr "No se ha recibido una respuesta en %llums.\n" -#: src/arm/gnunet-arm.c:149 +#: src/arm/gnunet-arm.c:159 #, fuzzy, c-format msgid "Service `%s' is unknown to ARM.\n" msgstr "El espacio '%s' ha sido valorado con un %d.\n" -#: src/arm/gnunet-arm.c:154 +#: src/arm/gnunet-arm.c:164 #, fuzzy, c-format msgid "Service `%s' has been stopped.\n" msgstr "Servicio eliminado.\n" -#: src/arm/gnunet-arm.c:157 +#: src/arm/gnunet-arm.c:167 #, fuzzy, c-format msgid "Service `%s' was already running.\n" msgstr "ÂĄEsta bĂşsqueda estĂĄ aĂşn pendiente!\n" -#: src/arm/gnunet-arm.c:162 +#: src/arm/gnunet-arm.c:172 #, fuzzy, c-format msgid "Service `%s' has been started.\n" msgstr "Servicio eliminado.\n" -#: src/arm/gnunet-arm.c:165 +#: src/arm/gnunet-arm.c:175 #, fuzzy, c-format msgid "Service `%s' was already being stopped.\n" msgstr "Servicio eliminado.\n" -#: src/arm/gnunet-arm.c:169 +#: src/arm/gnunet-arm.c:179 #, fuzzy, c-format msgid "Service `%s' was already not running.\n" msgstr "ÂĄEsta bĂşsqueda estĂĄ aĂşn pendiente!\n" -#: src/arm/gnunet-arm.c:173 +#: src/arm/gnunet-arm.c:183 #, fuzzy msgid "Request ignored as ARM is shutting down.\n" msgstr "'%s' se esta cerrando.\n" -#: src/arm/gnunet-arm.c:177 +#: src/arm/gnunet-arm.c:187 #, fuzzy msgid "Error communicating with ARM service.\n" msgstr "Imprime informaciĂłn de los pares de GNUnet." -#: src/arm/gnunet-arm.c:181 +#: src/arm/gnunet-arm.c:191 #, fuzzy msgid "Timeout communicating with ARM service.\n" msgstr "Imprime informaciĂłn de los pares de GNUnet." -#: src/arm/gnunet-arm.c:185 +#: src/arm/gnunet-arm.c:195 #, fuzzy msgid "Operation failed.\n" msgstr "La verificaciĂłn de la firma RSA fallo en %s: %d: %s\n" -#: src/arm/gnunet-arm.c:189 +#: src/arm/gnunet-arm.c:199 msgid "Unknown response code from ARM.\n" msgstr "" -#: src/arm/gnunet-arm.c:216 +#: src/arm/gnunet-arm.c:222 +#, fuzzy +msgid "Error communicating with ARM. ARM not running?\n" +msgstr "Imprime informaciĂłn de los pares de GNUnet." + +#: src/arm/gnunet-arm.c:225 +#, fuzzy +msgid "Running services:\n" +msgstr "Iniciada colecciĂłn '%s'.\n" + +#: src/arm/gnunet-arm.c:249 #, c-format msgid "Fatal configuration error: `%s' option in section `%s' missing.\n" msgstr "" -#: src/arm/gnunet-arm.c:224 src/arm/gnunet-arm.c:324 +#: src/arm/gnunet-arm.c:257 src/arm/gnunet-arm.c:357 src/arm/gnunet-arm.c:373 msgid "Fatal error initializing ARM API.\n" msgstr "" -#: src/arm/gnunet-arm.c:247 +#: src/arm/gnunet-arm.c:280 #, fuzzy, c-format msgid "Failed to remove configuration file %s\n" msgstr "Imposible guardar el fichero de configuraciĂłn '%s':" -#: src/arm/gnunet-arm.c:253 +#: src/arm/gnunet-arm.c:286 #, fuzzy, c-format msgid "Failed to remove servicehome directory %s\n" msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" -#: src/arm/gnunet-arm.c:355 +#: src/arm/gnunet-arm.c:407 msgid "stop all GNUnet services" msgstr "" -#: src/arm/gnunet-arm.c:357 +#: src/arm/gnunet-arm.c:409 msgid "start a particular service" msgstr "" -#: src/arm/gnunet-arm.c:359 +#: src/arm/gnunet-arm.c:411 msgid "stop a particular service" msgstr "" -#: src/arm/gnunet-arm.c:361 +#: src/arm/gnunet-arm.c:413 msgid "start all GNUnet default services" msgstr "" -#: src/arm/gnunet-arm.c:364 +#: src/arm/gnunet-arm.c:416 msgid "stop and start all GNUnet default services" msgstr "" -#: src/arm/gnunet-arm.c:367 +#: src/arm/gnunet-arm.c:419 msgid "delete config file and directory on exit" msgstr "" -#: src/arm/gnunet-arm.c:369 +#: src/arm/gnunet-arm.c:421 msgid "don't print status messages" msgstr "" -#: src/arm/gnunet-arm.c:372 +#: src/arm/gnunet-arm.c:424 #, fuzzy msgid "timeout for completing current operation" msgstr "tiempo para esperar hasta completar una iteraciĂłn (en ms)" -#: src/arm/gnunet-arm.c:383 +#: src/arm/gnunet-arm.c:426 +msgid "List currently running services" +msgstr "" + +#: src/arm/gnunet-arm.c:437 msgid "Control services and the Automated Restart Manager (ARM)" msgstr "" -#: src/arm/gnunet-service-arm.c:328 +#: src/arm/gnunet-service-arm.c:332 #, fuzzy, c-format msgid "Failed to start service `%s'\n" msgstr "FallĂł al comenzar la recolecciĂłn.\n" -#: src/arm/gnunet-service-arm.c:331 +#: src/arm/gnunet-service-arm.c:335 #, fuzzy, c-format msgid "Starting service `%s'\n" msgstr "Iniciada colecciĂłn '%s'.\n" -#: src/arm/gnunet-service-arm.c:357 +#: src/arm/gnunet-service-arm.c:361 #, fuzzy msgid "Could not send status result to client\n" msgstr "Imposible mandar el mensaje a gnunetd\n" -#: src/arm/gnunet-service-arm.c:484 +#: src/arm/gnunet-service-arm.c:393 +#, fuzzy +msgid "Could not send list result to client\n" +msgstr "Imposible mandar el mensaje a gnunetd\n" + +#: src/arm/gnunet-service-arm.c:523 #, fuzzy, c-format msgid "Unable to create socket for service `%s': %s\n" msgstr "Imposible crear la cuenta de usuario:" -#: src/arm/gnunet-service-arm.c:506 +#: src/arm/gnunet-service-arm.c:545 #, c-format msgid "Unable to bind listening socket for service `%s' to address `%s': %s\n" msgstr "" -#: src/arm/gnunet-service-arm.c:520 +#: src/arm/gnunet-service-arm.c:559 #, c-format msgid "ARM now monitors connections to service `%s' at `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:628 +#: src/arm/gnunet-service-arm.c:667 #, fuzzy, c-format msgid "Preparing to stop `%s'\n" msgstr "Iniciada colecciĂłn '%s'.\n" -#: src/arm/gnunet-service-arm.c:782 +#: src/arm/gnunet-service-arm.c:878 #, fuzzy, c-format msgid "Restarting service `%s'.\n" msgstr "Iniciada colecciĂłn '%s'.\n" -#: src/arm/gnunet-service-arm.c:877 +#: src/arm/gnunet-service-arm.c:970 msgid "exit" msgstr "" -#: src/arm/gnunet-service-arm.c:882 +#: src/arm/gnunet-service-arm.c:975 msgid "signal" msgstr "" -#: src/arm/gnunet-service-arm.c:887 +#: src/arm/gnunet-service-arm.c:980 msgid "unknown" msgstr "desconocido" -#: src/arm/gnunet-service-arm.c:921 +#: src/arm/gnunet-service-arm.c:986 +#, fuzzy, c-format +msgid "Service `%s' took %llu ms to terminate\n" +msgstr "Servicio eliminado.\n" + +#: src/arm/gnunet-service-arm.c:1021 #, c-format msgid "Service `%s' terminated with status %s/%d, will restart in %llu ms\n" msgstr "" -#: src/arm/gnunet-service-arm.c:967 src/arm/mockup-service.c:41 -#, fuzzy -msgid "Failed to transmit shutdown ACK.\n" -msgstr "FallĂł al comenzar la recolecciĂłn.\n" - -#: src/arm/gnunet-service-arm.c:1067 +#: src/arm/gnunet-service-arm.c:1127 #, fuzzy, c-format msgid "Configuration file `%s' for service `%s' not valid: %s\n" msgstr "Fichero de configuraciĂłn '%s' creado.\n" -#: src/arm/gnunet-service-arm.c:1069 +#: src/arm/gnunet-service-arm.c:1129 msgid "option missing" msgstr "" -#: src/arm/gnunet-service-arm.c:1152 +#: src/arm/gnunet-service-arm.c:1213 #, fuzzy, c-format msgid "Starting default services `%s'\n" msgstr "Iniciada colecciĂłn '%s'.\n" -#: src/arm/gnunet-service-arm.c:1163 +#: src/arm/gnunet-service-arm.c:1224 #, c-format msgid "Default service `%s' not configured correctly!\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1177 +#: src/arm/gnunet-service-arm.c:1238 msgid "" "No default services configured, GNUnet will not really start right now.\n" msgstr "" -#: src/arm/mockup-service.c:46 -msgid "Transmitting shutdown ACK.\n" -msgstr "" - -#: src/arm/mockup-service.c:69 +#: src/arm/mockup-service.c:44 msgid "Initiating shutdown as requested by client.\n" msgstr "" @@ -330,195 +345,198 @@ msgstr "" msgid "Undefined mandatory parameter: memberCallback\n" msgstr "" -#: src/chat/gnunet-chat.c:92 +#: src/chat/gnunet-chat.c:93 msgid "Joined\n" msgstr "" -#: src/chat/gnunet-chat.c:124 +#: src/chat/gnunet-chat.c:125 src/chat/gnunet-chat.c:133 +#: src/chat/gnunet-chat.c:213 src/chat/gnunet-chat.c:253 +#: src/chat/gnunet-chat.c:329 src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:400 src/chat/gnunet-chat.c:700 msgid "anonymous" msgstr "" -#: src/chat/gnunet-chat.c:130 +#: src/chat/gnunet-chat.c:144 #, fuzzy, c-format msgid "(%s) `%s' said: %s\n" msgstr "'%s' %s fallĂł: %s\n" -#: src/chat/gnunet-chat.c:133 src/chat/gnunet-chat.c:136 +#: src/chat/gnunet-chat.c:147 src/chat/gnunet-chat.c:150 #, fuzzy, c-format msgid "(%s) `%s' said to you: %s\n" msgstr "'%s' %s fallĂł: %s\n" -#: src/chat/gnunet-chat.c:139 +#: src/chat/gnunet-chat.c:153 #, fuzzy, c-format msgid "(%s) `%s' said for sure: %s\n" msgstr "'%s' %s fallĂł: %s\n" -#: src/chat/gnunet-chat.c:142 +#: src/chat/gnunet-chat.c:156 #, fuzzy, c-format msgid "(%s) `%s' said to you for sure: %s\n" msgstr "'%s' fallĂł con el cĂłdigo de error %s: %s" -#: src/chat/gnunet-chat.c:145 +#: src/chat/gnunet-chat.c:159 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you received: %s\n" msgstr "'%s' fallĂł con el cĂłdigo de error %d: %s" -#: src/chat/gnunet-chat.c:148 +#: src/chat/gnunet-chat.c:162 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you and only you received: %s\n" msgstr "'%s' fallĂł con el cĂłdigo de error %d: %s" -#: src/chat/gnunet-chat.c:151 +#: src/chat/gnunet-chat.c:165 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you received from him or her: %s\n" msgstr "'%s' fallĂł con el cĂłdigo de error %d: %s" -#: src/chat/gnunet-chat.c:156 +#: src/chat/gnunet-chat.c:170 #, fuzzy, c-format msgid "" "(%s) `%s' was confirmed that you and only you received from him or her: %s\n" msgstr "'%s' fallĂł con el cĂłdigo de error %d: %s" -#: src/chat/gnunet-chat.c:159 +#: src/chat/gnunet-chat.c:173 #, fuzzy, c-format msgid "(%s) `%s' said off the record: %s\n" msgstr "'%s' fallĂł con el cĂłdigo de error %s: %s" -#: src/chat/gnunet-chat.c:162 +#: src/chat/gnunet-chat.c:176 #, c-format msgid "(%s) <%s> said using an unknown message type: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:193 +#: src/chat/gnunet-chat.c:217 #, c-format msgid "'%s' acknowledged message #%d\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' entered the room\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' left the room\n" msgstr "" -#: src/chat/gnunet-chat.c:284 src/chat/gnunet-chat.c:316 +#: src/chat/gnunet-chat.c:321 src/chat/gnunet-chat.c:363 #, fuzzy msgid "Could not change username\n" msgstr "Imposible crear el espacio '%s' (Âżexiste?).\n" -#: src/chat/gnunet-chat.c:288 src/chat/gnunet-chat.c:630 +#: src/chat/gnunet-chat.c:334 src/chat/gnunet-chat.c:702 #, fuzzy, c-format msgid "Joining room `%s' as user `%s'...\n" msgstr "Respuesta invĂĄlida a '%s' del par '%s'.\n" -#: src/chat/gnunet-chat.c:320 +#: src/chat/gnunet-chat.c:373 #, fuzzy, c-format msgid "Changed username to `%s'\n" msgstr "Imposible cambiar el usuario/grupo a '%s': %s\n" -#: src/chat/gnunet-chat.c:333 +#: src/chat/gnunet-chat.c:388 #, fuzzy, c-format msgid "Users in room `%s': " msgstr "Fichero almacenado en '%s'.\n" -#: src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:434 msgid "Syntax: /msg USERNAME MESSAGE" msgstr "" -#: src/chat/gnunet-chat.c:379 -#, fuzzy, c-format -msgid "Unknown user `%s'\n" -msgstr "OperaciĂłn desconocida '%s'\n" +#: src/chat/gnunet-chat.c:443 +#, c-format +msgid "Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n" +msgstr "" -#: src/chat/gnunet-chat.c:395 +#: src/chat/gnunet-chat.c:460 #, c-format msgid "User `%s' is currently not in the room!\n" msgstr "" -#: src/chat/gnunet-chat.c:448 +#: src/chat/gnunet-chat.c:513 #, fuzzy, c-format msgid "Unknown command `%s'\n" msgstr "OperaciĂłn desconocida '%s'\n" -#: src/chat/gnunet-chat.c:459 +#: src/chat/gnunet-chat.c:524 msgid "" "Use `/join #roomname' to join a chat room. Joining a room will cause you to " "leave the current room" msgstr "" -#: src/chat/gnunet-chat.c:463 +#: src/chat/gnunet-chat.c:528 msgid "" "Use `/nick nickname' to change your nickname. This will cause you to leave " "the current room and immediately rejoin it with the new name." msgstr "" -#: src/chat/gnunet-chat.c:467 +#: src/chat/gnunet-chat.c:532 msgid "" "Use `/msg nickname message' to send a private message to the specified user" msgstr "" -#: src/chat/gnunet-chat.c:470 +#: src/chat/gnunet-chat.c:535 msgid "The `/notice' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:472 +#: src/chat/gnunet-chat.c:537 msgid "The `/query' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:474 +#: src/chat/gnunet-chat.c:539 msgid "Use `/sig message' to send a signed public message" msgstr "" -#: src/chat/gnunet-chat.c:477 +#: src/chat/gnunet-chat.c:542 msgid "Use `/ack message' to require signed acknowledgment of the message" msgstr "" -#: src/chat/gnunet-chat.c:480 +#: src/chat/gnunet-chat.c:545 msgid "Use `/anonymous message' to send a public anonymous message" msgstr "" -#: src/chat/gnunet-chat.c:482 +#: src/chat/gnunet-chat.c:547 msgid "The `/anon' command is an alias for `/anonymous'" msgstr "" -#: src/chat/gnunet-chat.c:484 +#: src/chat/gnunet-chat.c:549 msgid "Use `/quit' to terminate gnunet-chat" msgstr "" -#: src/chat/gnunet-chat.c:486 +#: src/chat/gnunet-chat.c:551 msgid "The `/leave' command is an alias for `/quit'" msgstr "" -#: src/chat/gnunet-chat.c:489 +#: src/chat/gnunet-chat.c:554 msgid "Use `/names' to list all of the current members in the chat room" msgstr "" -#: src/chat/gnunet-chat.c:491 +#: src/chat/gnunet-chat.c:556 msgid "Use `/help command' to get help for a specific command" msgstr "" -#: src/chat/gnunet-chat.c:606 +#: src/chat/gnunet-chat.c:672 #, fuzzy msgid "You must specify a nickname\n" msgstr "ÂĄDebes especificar un receptor!\n" -#: src/chat/gnunet-chat.c:622 +#: src/chat/gnunet-chat.c:688 #, fuzzy, c-format msgid "Failed to join room `%s'\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/chat/gnunet-chat.c:655 +#: src/chat/gnunet-chat.c:727 msgid "set the nickname to use (required)" msgstr "" -#: src/chat/gnunet-chat.c:658 +#: src/chat/gnunet-chat.c:730 msgid "set the chat room to join" msgstr "" -#: src/chat/gnunet-chat.c:670 +#: src/chat/gnunet-chat.c:742 msgid "Join a chat on GNUnet." msgstr "" @@ -542,184 +560,186 @@ msgstr "Imposible guardar la configuraciĂłn" msgid "Failed to queue a leave notification\n" msgstr "Imposible guardar la configuraciĂłn" -#: src/core/core_api.c:798 +#: src/core/core_api.c:786 msgid "Client was disconnected from core service, trying to reconnect.\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:77 -#: src/peerinfo-tool/gnunet-peerinfo.c:60 +#: src/core/gnunet-core.c:54 src/peerinfo-tool/gnunet-peerinfo.c:286 #, fuzzy, c-format msgid "Peer `%s'\n" msgstr "Yo soy el par '%s'.\n" -#: src/core/gnunet-core-list-connections.c:175 -#: src/peerinfo-tool/gnunet-peerinfo.c:194 +#: src/core/gnunet-core.c:72 src/peerinfo-tool/gnunet-peerinfo.c:817 #, fuzzy, c-format msgid "Invalid command line argument `%s'\n" msgstr "Argumentos en la linea de comandos invĂĄlidos:\n" -#: src/core/gnunet-core-list-connections.c:196 -#: src/peerinfo-tool/gnunet-peerinfo.c:252 -msgid "don't resolve host names" -msgstr "" - -#: src/core/gnunet-core-list-connections.c:203 +#: src/core/gnunet-core.c:95 #, fuzzy msgid "Print information about connected peers." msgstr "Imprime informaciĂłn de los pares de GNUnet." -#: src/core/gnunet-service-core.c:99 +#: src/core/gnunet-service-core.c:97 #, c-format msgid "Core service of `%4s' ready.\n" msgstr "" -#: src/core/gnunet-service-core_clients.c:360 +#: src/core/gnunet-service-core_clients.c:370 #, fuzzy msgid "# send requests dropped (disconnected)" msgstr "# Anuncios de los pares recibidos" -#: src/core/gnunet-service-core_clients.c:465 +#: src/core/gnunet-service-core_clients.c:475 #, fuzzy msgid "# messages discarded (session disconnected)" msgstr "# mensajes defragmentados" -#: src/core/gnunet-service-core_clients.c:801 +#: src/core/gnunet-service-core_clients.c:818 #, fuzzy, c-format msgid "# bytes of messages of type %u received" msgstr "# bytes de ruido recibidos" -#: src/core/gnunet-service-core_kx.c:493 +#: src/core/gnunet-service-core_kx.c:565 msgid "# bytes encrypted" msgstr "# bytes encriptados" -#: src/core/gnunet-service-core_kx.c:543 +#: src/core/gnunet-service-core_kx.c:617 msgid "# bytes decrypted" msgstr "# bytes desencriptados" -#: src/core/gnunet-service-core_kx.c:604 src/dv/gnunet-service-dv.c:3002 -#: src/hostlist/hostlist-server.c:436 src/peerinfo-tool/gnunet-peerinfo.c:151 +#: src/core/gnunet-service-core_kx.c:681 src/dv/gnunet-service-dv.c:3003 #, fuzzy msgid "Error in communication with PEERINFO service\n" msgstr "Imprime informaciĂłn de los pares de GNUnet." -#: src/core/gnunet-service-core_kx.c:623 +#: src/core/gnunet-service-core_kx.c:700 msgid "# Delayed connecting due to lack of public key" msgstr "" -#: src/core/gnunet-service-core_kx.c:673 +#: src/core/gnunet-service-core_kx.c:753 msgid "# key exchanges initiated" msgstr "" -#: src/core/gnunet-service-core_kx.c:694 +#: src/core/gnunet-service-core_kx.c:775 msgid "# key exchanges stopped" msgstr "" -#: src/core/gnunet-service-core_kx.c:746 +#: src/core/gnunet-service-core_kx.c:828 #, fuzzy msgid "# session keys received" msgstr "# claves de la sesiĂłn rechazadas" -#: src/core/gnunet-service-core_kx.c:765 +#: src/core/gnunet-service-core_kx.c:845 #, fuzzy, c-format msgid "`%s' is for `%s', not for me. Ignoring.\n" msgstr "el tamaĂąo del '%s' mensaje es demasiado corto. Ignorandolo.\n" -#: src/core/gnunet-service-core_kx.c:803 +#: src/core/gnunet-service-core_kx.c:890 #, fuzzy msgid "# SET_KEY messages decrypted" msgstr "# mensajes defragmentados" -#: src/core/gnunet-service-core_kx.c:883 -#: src/transport/gnunet-service-transport_validation.c:803 +#: src/core/gnunet-service-core_kx.c:977 +#: src/transport/gnunet-service-transport_validation.c:810 #, fuzzy msgid "# PING messages received" msgstr "# mensajes PONG encriptados recibidos" -#: src/core/gnunet-service-core_kx.c:917 +#: src/core/gnunet-service-core_kx.c:1010 #, c-format msgid "" "Received PING from `%s' for different identity: I am `%s', PONG identity: `" "%s'\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:938 +#: src/core/gnunet-service-core_kx.c:1029 #, fuzzy msgid "# PONG messages created" msgstr "# mensajes fragmentados" -#: src/core/gnunet-service-core_kx.c:1026 +#: src/core/gnunet-service-core_kx.c:1125 #, fuzzy msgid "# sessions terminated by timeout" msgstr "# bytes omitidos por TCP (salientes)" -#: src/core/gnunet-service-core_kx.c:1037 +#: src/core/gnunet-service-core_kx.c:1135 #, fuzzy msgid "# keepalive messages sent" msgstr "# mensajes PONG encriptados recibidos" -#: src/core/gnunet-service-core_kx.c:1095 -#: src/transport/gnunet-service-transport_validation.c:1026 +#: src/core/gnunet-service-core_kx.c:1236 +#: src/transport/gnunet-service-transport_validation.c:1031 #, fuzzy msgid "# PONG messages received" msgstr "# mensajes PONG encriptados recibidos" -#: src/core/gnunet-service-core_kx.c:1125 +#: src/core/gnunet-service-core_kx.c:1275 #, fuzzy msgid "# PONG messages decrypted" msgstr "# mensajes defragmentados" -#: src/core/gnunet-service-core_kx.c:1157 +#: src/core/gnunet-service-core_kx.c:1303 #, fuzzy msgid "# session keys confirmed via PONG" msgstr "# Anuncios de los pares recibidos" -#: src/core/gnunet-service-core_kx.c:1223 +#: src/core/gnunet-service-core_kx.c:1329 +#, fuzzy +msgid "# rekey operations confirmed via PONG" +msgstr "# Anuncios de los pares recibidos" + +#: src/core/gnunet-service-core_kx.c:1381 +#: src/core/gnunet-service-core_kx.c:1398 #, fuzzy msgid "# SET_KEY and PING messages created" msgstr "# mensajes de texto mandados por PING" -#: src/core/gnunet-service-core_kx.c:1364 +#: src/core/gnunet-service-core_kx.c:1402 +msgid "# REKEY operations performed" +msgstr "" + +#: src/core/gnunet-service-core_kx.c:1537 msgid "# failed to decrypt message (no session key)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1406 -#: src/core/gnunet-service-core_kx.c:1431 +#: src/core/gnunet-service-core_kx.c:1577 +#: src/core/gnunet-service-core_kx.c:1602 #, fuzzy msgid "# bytes dropped (duplicates)" msgstr "# bytes omitidos por UDP (salientes)" -#: src/core/gnunet-service-core_kx.c:1418 +#: src/core/gnunet-service-core_kx.c:1589 #, fuzzy msgid "# bytes dropped (out of sequence)" msgstr "# bytes omitidos por UDP (salientes)" -#: src/core/gnunet-service-core_kx.c:1455 +#: src/core/gnunet-service-core_kx.c:1626 #, fuzzy, c-format msgid "Message received far too old (%llu ms). Content ignored.\n" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/core/gnunet-service-core_kx.c:1459 +#: src/core/gnunet-service-core_kx.c:1630 #, fuzzy msgid "# bytes dropped (ancient message)" msgstr "# bytes omitidos por UDP (salientes)" -#: src/core/gnunet-service-core_kx.c:1467 +#: src/core/gnunet-service-core_kx.c:1638 #, fuzzy msgid "# bytes of payload decrypted" msgstr "# bytes desencriptados" -#: src/core/gnunet-service-core_kx.c:1528 +#: src/core/gnunet-service-core_kx.c:1700 #, fuzzy msgid "Core service is lacking HOSTKEY configuration setting. Exiting.\n" msgstr "ConfiguraciĂłn de GNUnet" -#: src/core/gnunet-service-core_kx.c:1536 +#: src/core/gnunet-service-core_kx.c:1708 msgid "Core service could not access hostkey. Exiting.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1546 src/hostlist/hostlist-server.c:555 -#: src/peerinfo-tool/gnunet-peerinfo.c:202 -#: src/transport/gnunet-service-transport.c:595 +#: src/core/gnunet-service-core_kx.c:1718 src/hostlist/hostlist-server.c:551 +#: src/peerinfo-tool/gnunet-peerinfo.c:823 +#: src/transport/gnunet-service-transport.c:611 #, fuzzy msgid "Could not access PEERINFO service. Exiting.\n" msgstr "Imposible acceder a la informaciĂłn del espacio.\n" @@ -730,29 +750,40 @@ msgid "# sessions terminated by transport disconnect" msgstr "# Anuncios de los pares recibidos" #: src/core/gnunet-service-core_neighbours.c:180 -#: src/core/gnunet-service-core_neighbours.c:342 +#: src/core/gnunet-service-core_neighbours.c:334 msgid "# neighbour entries allocated" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:251 +#: src/core/gnunet-service-core_neighbours.c:247 msgid "# encrypted bytes given to transport" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:430 +#: src/core/gnunet-service-core_neighbours.c:418 #, fuzzy, c-format msgid "Unsupported message of type %u (%u bytes) received from peer `%s'\n" msgstr "Mensaje no vĂĄlido del tipo %u recibido. Omitiendo.\n" -#: src/core/gnunet-service-core_sessions.c:208 -#: src/core/gnunet-service-core_sessions.c:273 -msgid "# entries in session map" -msgstr "" +#: src/core/gnunet-service-core_sessions.c:206 +#: src/core/gnunet-service-core_sessions.c:269 +#: src/dht/gnunet-service-dht_neighbours.c:625 +#: src/dht/gnunet-service-dht_neighbours.c:683 +#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 +#: src/topology/gnunet-daemon-topology.c:709 +#: src/topology/gnunet-daemon-topology.c:810 +#: src/transport/gnunet-service-transport_neighbours.c:874 +#: src/transport/gnunet-service-transport_neighbours.c:1080 +#: src/transport/gnunet-service-transport_neighbours.c:1089 +#: src/transport/gnunet-service-transport_neighbours.c:2568 +#: src/transport/gnunet-service-transport_neighbours.c:2814 +#, fuzzy +msgid "# peers connected" +msgstr "# de pares conectados" -#: src/core/gnunet-service-core_sessions.c:238 +#: src/core/gnunet-service-core_sessions.c:236 msgid "# type map refreshes sent" msgstr "" -#: src/core/gnunet-service-core_sessions.c:414 +#: src/core/gnunet-service-core_sessions.c:406 msgid "# messages discarded (expired prior to transmission)" msgstr "" @@ -766,426 +797,405 @@ msgstr "# mensajes PONG encriptados recibidos" msgid "# updates to my type map" msgstr "" -#: src/datacache/datacache.c:118 src/datacache/datacache.c:255 -#: src/datastore/gnunet-service-datastore.c:854 +#: src/datacache/datacache.c:115 src/datacache/datacache.c:250 +#: src/datastore/gnunet-service-datastore.c:834 #, fuzzy msgid "# bytes stored" msgstr "# bytes en la base de datos" -#: src/datacache/datacache.c:144 src/datacache/datacache.c:151 -#: src/datastore/gnunet-service-datastore.c:1531 -#: src/datastore/gnunet-service-datastore.c:1542 +#: src/datacache/datacache.c:141 src/datacache/datacache.c:148 +#: src/datastore/gnunet-service-datastore.c:1483 +#: src/datastore/gnunet-service-datastore.c:1494 #, fuzzy, c-format msgid "No `%s' specified for `%s' in configuration!\n" msgstr "ÂĄNinguna aplicaciĂłn definida en la configuraciĂłn!\n" -#: src/datacache/datacache.c:183 +#: src/datacache/datacache.c:180 #, c-format msgid "Loading `%s' datacache plugin\n" msgstr "" -#: src/datacache/datacache.c:191 +#: src/datacache/datacache.c:188 #, fuzzy, c-format msgid "Failed to load datacache plugin for `%s'\n" msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" -#: src/datacache/datacache.c:281 +#: src/datacache/datacache.c:276 #, fuzzy msgid "# requests received" msgstr "# mensajes PONG encriptados recibidos" -#: src/datacache/datacache.c:291 +#: src/datacache/datacache.c:284 msgid "# requests filtered by bloom filter" msgstr "" -#: src/datacache/plugin_datacache_mysql.c:103 -#: src/datacache/plugin_datacache_mysql.c:110 -#: src/datacache/plugin_datacache_mysql.c:517 -#: src/datacache/plugin_datacache_mysql.c:526 -#: src/datacache/plugin_datacache_mysql.c:598 -#: src/datacache/plugin_datacache_mysql.c:614 -#: src/datacache/plugin_datacache_sqlite.c:71 -#: src/datacache/plugin_datacache_sqlite.c:74 -#: src/datastore/plugin_datastore_mysql.c:139 -#: src/datastore/plugin_datastore_mysql.c:146 -#: src/datastore/plugin_datastore_mysql.c:613 -#: src/datastore/plugin_datastore_mysql.c:673 -#: src/datastore/plugin_datastore_mysql.c:685 -#: src/datastore/plugin_datastore_mysql.c:1362 -#: src/datastore/plugin_datastore_mysql.c:1376 -#: src/datastore/plugin_datastore_sqlite.c:61 -#: src/namestore/plugin_namestore_sqlite.c:49 src/util/crypto_ksk.c:49 -#: src/util/crypto_rsa.c:92 src/include/gnunet_common.h:507 -#: src/include/gnunet_common.h:514 +#: src/datacache/plugin_datacache_mysql.c:97 +#: src/datacache/plugin_datacache_mysql.c:104 +#: src/datacache/plugin_datacache_sqlite.c:69 +#: src/datacache/plugin_datacache_sqlite.c:72 +#: src/datastore/plugin_datastore_mysql.c:803 +#: src/datastore/plugin_datastore_mysql.c:817 +#: src/datastore/plugin_datastore_sqlite.c:57 src/mysql/mysql.c:41 +#: src/mysql/mysql.c:48 src/mysql/mysql.c:522 src/mysql/mysql.c:531 +#: src/mysql/mysql.c:591 src/mysql/mysql.c:607 +#: src/namestore/plugin_namestore_sqlite.c:51 src/util/crypto_ksk.c:49 +#: src/util/crypto_rsa.c:67 src/include/gnunet_common.h:525 +#: src/include/gnunet_common.h:532 #, c-format msgid "`%s' failed at %s:%d with error: %s\n" msgstr "'%s' fallĂł en %s: %d con el error: %s\n" -#: src/datacache/plugin_datacache_mysql.c:224 -#: src/datastore/plugin_datastore_mysql.c:316 -#, c-format -msgid "Trying to use file `%s' for MySQL configuration.\n" -msgstr "Intentando usar el fichero '%s' para la configuraciĂłn de MySQL.\n" - -#: src/datacache/plugin_datacache_mysql.c:230 -#: src/datastore/plugin_datastore_mysql.c:322 -#, fuzzy, c-format -msgid "Could not access file `%s': %s\n" -msgstr "Imposible ejecutar '%s': %s\n" - -#: src/datacache/plugin_datacache_mysql.c:979 +#: src/datacache/plugin_datacache_mysql.c:450 msgid "MySQL datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_postgres.c:79 -#: src/datastore/plugin_datastore_postgres.c:93 -#, fuzzy, c-format -msgid "`%s:%s' failed at %s:%d with error: %s" -msgstr "'%s' fallĂł en %s: %d con el error: %s\n" - -#: src/datacache/plugin_datacache_postgres.c:149 -#, fuzzy, c-format -msgid "Unable to initialize Postgres: %s" -msgstr "Imposible inicializar SQLite.\n" - -#: src/datacache/plugin_datacache_postgres.c:499 +#: src/datacache/plugin_datacache_postgres.c:367 msgid "Postgres datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:424 +#: src/datacache/plugin_datacache_sqlite.c:410 msgid "Sqlite datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:457 -#: src/datastore/plugin_datastore_sqlite.c:414 -#: src/namestore/plugin_namestore_sqlite.c:381 +#: src/datacache/plugin_datacache_sqlite.c:443 +#: src/datastore/plugin_datastore_sqlite.c:408 +#: src/namestore/plugin_namestore_sqlite.c:370 msgid "Tried to close sqlite without finalizing all prepared statements.\n" msgstr "" +#: src/datacache/plugin_datacache_sqlite.c:450 +#, fuzzy, c-format +msgid "Failed to close statement %p: %d\n" +msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" + #: src/datacache/plugin_datacache_template.c:121 msgid "Template datacache running\n" msgstr "" -#: src/datastore/datastore_api.c:289 +#: src/datastore/datastore_api.c:305 #, fuzzy msgid "Failed to transmit request to drop database.\n" msgstr "FallĂł al mandar la peticiĂłn HTTP al host '%s': %s\n" -#: src/datastore/datastore_api.c:372 +#: src/datastore/datastore_api.c:388 msgid "# queue entry timeouts" msgstr "" -#: src/datastore/datastore_api.c:418 +#: src/datastore/datastore_api.c:432 msgid "# queue overflows" msgstr "" -#: src/datastore/datastore_api.c:445 +#: src/datastore/datastore_api.c:459 msgid "# queue entries created" msgstr "" -#: src/datastore/datastore_api.c:465 +#: src/datastore/datastore_api.c:477 #, fuzzy msgid "# Requests dropped from datastore queue" msgstr "# Anuncios de los pares recibidos" -#: src/datastore/datastore_api.c:513 +#: src/datastore/datastore_api.c:525 msgid "# datastore connections (re)created" msgstr "" -#: src/datastore/datastore_api.c:540 +#: src/datastore/datastore_api.c:548 msgid "# reconnected to DATASTORE" msgstr "" -#: src/datastore/datastore_api.c:608 +#: src/datastore/datastore_api.c:612 #, fuzzy msgid "# transmission request failures" msgstr "# mensajes de texto mandados por PING" -#: src/datastore/datastore_api.c:631 +#: src/datastore/datastore_api.c:633 #, fuzzy msgid "# bytes sent to datastore" msgstr "# bytes en la base de datos" -#: src/datastore/datastore_api.c:772 +#: src/datastore/datastore_api.c:764 #, fuzzy msgid "Failed to receive status response from database." msgstr "" "\n" "Fallo al recibir la respuesta de gnunetd.\n" -#: src/datastore/datastore_api.c:786 +#: src/datastore/datastore_api.c:778 msgid "Error reading response from datastore service" msgstr "" -#: src/datastore/datastore_api.c:798 src/datastore/datastore_api.c:804 +#: src/datastore/datastore_api.c:790 src/datastore/datastore_api.c:796 #, fuzzy msgid "Invalid error message received from datastore service" msgstr "Mensaje '%s' invĂĄlido recibido del par '%s'.\n" -#: src/datastore/datastore_api.c:810 +#: src/datastore/datastore_api.c:800 #, fuzzy msgid "# status messages received" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/datastore_api.c:883 +#: src/datastore/datastore_api.c:869 #, fuzzy msgid "# PUT requests executed" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/datastore_api.c:954 +#: src/datastore/datastore_api.c:936 msgid "# RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1019 +#: src/datastore/datastore_api.c:997 msgid "# RELEASE RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1080 +#: src/datastore/datastore_api.c:1054 #, fuzzy msgid "# UPDATE requests executed" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/datastore_api.c:1148 +#: src/datastore/datastore_api.c:1118 #, fuzzy msgid "# REMOVE requests executed" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/datastore_api.c:1193 +#: src/datastore/datastore_api.c:1163 #, fuzzy msgid "Failed to receive response from database.\n" msgstr "" "\n" "Fallo al recibir la respuesta de gnunetd.\n" -#: src/datastore/datastore_api.c:1253 +#: src/datastore/datastore_api.c:1221 #, fuzzy msgid "# Results received" msgstr "# bytes recibidos por TCP" -#: src/datastore/datastore_api.c:1324 +#: src/datastore/datastore_api.c:1286 msgid "# GET REPLICATION requests executed" msgstr "" -#: src/datastore/datastore_api.c:1391 +#: src/datastore/datastore_api.c:1349 msgid "# GET ZERO ANONYMITY requests executed" msgstr "" -#: src/datastore/datastore_api.c:1455 +#: src/datastore/datastore_api.c:1409 #, fuzzy msgid "# GET requests executed" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/gnunet-service-datastore.c:351 +#: src/datastore/gnunet-service-datastore.c:349 #, fuzzy msgid "# bytes expired" msgstr "# bytes recibidos por TCP" -#: src/datastore/gnunet-service-datastore.c:426 +#: src/datastore/gnunet-service-datastore.c:422 msgid "# bytes purged (low-priority)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:486 +#: src/datastore/gnunet-service-datastore.c:480 msgid "Transmission to client failed!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:640 +#: src/datastore/gnunet-service-datastore.c:511 +msgid "Shutdown in progress, aborting transmission.\n" +msgstr "" + +#: src/datastore/gnunet-service-datastore.c:626 msgid "# results found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:685 +#: src/datastore/gnunet-service-datastore.c:669 #, c-format msgid "" "Insufficient space (%llu bytes are available) to satisfy `%s' request for " "%llu bytes\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:696 +#: src/datastore/gnunet-service-datastore.c:680 #, c-format msgid "" "The requested amount (%llu bytes) is larger than the cache size (%llu " "bytes)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:700 +#: src/datastore/gnunet-service-datastore.c:684 msgid "" "Insufficient space to satisfy request and requested amount is larger than " "cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:706 +#: src/datastore/gnunet-service-datastore.c:690 msgid "Insufficient space to satisfy request" msgstr "" -#: src/datastore/gnunet-service-datastore.c:711 -#: src/datastore/gnunet-service-datastore.c:765 -#: src/datastore/gnunet-service-datastore.c:986 -#: src/datastore/gnunet-service-datastore.c:1465 +#: src/datastore/gnunet-service-datastore.c:695 +#: src/datastore/gnunet-service-datastore.c:747 +#: src/datastore/gnunet-service-datastore.c:960 +#: src/datastore/gnunet-service-datastore.c:1417 msgid "# reserved" msgstr "" -#: src/datastore/gnunet-service-datastore.c:780 +#: src/datastore/gnunet-service-datastore.c:760 msgid "Could not find matching reservation" msgstr "" -#: src/datastore/gnunet-service-datastore.c:868 +#: src/datastore/gnunet-service-datastore.c:846 #, c-format msgid "Need %llu bytes more space (%llu allowed, using %llu)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1034 +#: src/datastore/gnunet-service-datastore.c:1006 #, fuzzy msgid "# GET requests received" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/gnunet-service-datastore.c:1048 +#: src/datastore/gnunet-service-datastore.c:1018 msgid "# requests filtered by bloomfilter" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1076 +#: src/datastore/gnunet-service-datastore.c:1046 #, fuzzy msgid "# UPDATE requests received" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/gnunet-service-datastore.c:1110 +#: src/datastore/gnunet-service-datastore.c:1076 #, fuzzy msgid "# GET REPLICATION requests received" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/gnunet-service-datastore.c:1145 +#: src/datastore/gnunet-service-datastore.c:1109 #, fuzzy msgid "# GET ZERO ANONYMITY requests received" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/gnunet-service-datastore.c:1172 +#: src/datastore/gnunet-service-datastore.c:1134 #, fuzzy msgid "Content not found" msgstr "ÂĄComando '%s' no encontrado!\n" -#: src/datastore/gnunet-service-datastore.c:1182 +#: src/datastore/gnunet-service-datastore.c:1142 msgid "# bytes removed (explicit request)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1216 +#: src/datastore/gnunet-service-datastore.c:1174 #, fuzzy msgid "# REMOVE requests received" msgstr "# mensajes PONG encriptados recibidos" -#: src/datastore/gnunet-service-datastore.c:1260 +#: src/datastore/gnunet-service-datastore.c:1216 #, c-format msgid "Datastore payload inaccurate (%lld < %lld). Trying to fix.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1323 +#: src/datastore/gnunet-service-datastore.c:1277 #, c-format msgid "Loading `%s' datastore plugin\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1332 +#: src/datastore/gnunet-service-datastore.c:1286 #, fuzzy, c-format msgid "Failed to load datastore plugin for `%s'\n" msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" -#: src/datastore/gnunet-service-datastore.c:1536 +#: src/datastore/gnunet-service-datastore.c:1488 #, fuzzy, c-format msgid "# bytes used in file-sharing datastore `%s'" msgstr "# bytes en la base de datos" -#: src/datastore/gnunet-service-datastore.c:1547 +#: src/datastore/gnunet-service-datastore.c:1499 msgid "# quota" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1549 +#: src/datastore/gnunet-service-datastore.c:1501 msgid "# cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1562 +#: src/datastore/gnunet-service-datastore.c:1514 #, c-format msgid "Could not use specified filename `%s' for bloomfilter.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1580 -#: src/datastore/gnunet-service-datastore.c:1596 +#: src/datastore/gnunet-service-datastore.c:1532 +#: src/datastore/gnunet-service-datastore.c:1548 #, fuzzy, c-format msgid "Failed to remove bogus bloomfilter file `%s'\n" msgstr "Imposible guardar el fichero de configuraciĂłn '%s':" -#: src/datastore/gnunet-service-datastore.c:1626 +#: src/datastore/gnunet-service-datastore.c:1578 #, fuzzy msgid "Failed to initialize bloomfilter.\n" msgstr "Imposible inicializar SQLite.\n" -#: src/datastore/gnunet-service-datastore.c:1655 +#: src/datastore/gnunet-service-datastore.c:1607 msgid "Rebuilding bloomfilter. Please be patient.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1660 +#: src/datastore/gnunet-service-datastore.c:1612 msgid "Plugin does not support get_keys function. Please fix!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1663 +#: src/datastore/gnunet-service-datastore.c:1615 msgid "Bloomfilter construction complete.\n" msgstr "" -#: src/datastore/plugin_datastore_mysql.c:529 -#: src/datastore/plugin_datastore_mysql.c:1336 +#: src/datastore/plugin_datastore_mysql.c:780 #, fuzzy, c-format msgid "Failed to prepare statement `%s'\n" msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" -#: src/datastore/plugin_datastore_mysql.c:622 -#: src/datastore/plugin_datastore_mysql.c:1346 +#: src/datastore/plugin_datastore_mysql.c:788 #, fuzzy, c-format msgid "`%s' for `%s' failed at %s:%d with error: %s\n" msgstr "'%s' a '%s' fallĂł en %s: %d con error %s\n" -#: src/datastore/plugin_datastore_mysql.c:1581 +#: src/datastore/plugin_datastore_mysql.c:1019 msgid "Mysql database running\n" msgstr "" -#: src/datastore/plugin_datastore_postgres.c:173 -#, fuzzy, c-format -msgid "Unable to initialize Postgres with configuration `%s': %s" -msgstr "Imposible guardar el fichero de configuraciĂłn '%s':" +#: src/datastore/plugin_datastore_postgres.c:824 +#, fuzzy +msgid "Failed to drop table from database.\n" +msgstr "" +"\n" +"Fallo al recibir la respuesta de gnunetd.\n" -#: src/datastore/plugin_datastore_postgres.c:1017 +#: src/datastore/plugin_datastore_postgres.c:860 msgid "Postgres database running\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:61 +#: src/datastore/plugin_datastore_sqlite.c:57 #, fuzzy, c-format msgid "`%s' failed at %s:%u with error: %s" msgstr "'%s' fallĂł en %s: %d con el error: %s\n" -#: src/datastore/plugin_datastore_sqlite.c:239 -#: src/namestore/plugin_namestore_sqlite.c:223 +#: src/datastore/plugin_datastore_sqlite.c:233 +#: src/namestore/plugin_namestore_sqlite.c:204 #, fuzzy, c-format msgid "Option `%s' in section `%s' missing in configuration!\n" msgstr "ÂĄNinguna aplicaciĂłn definida en la configuraciĂłn!\n" -#: src/datastore/plugin_datastore_sqlite.c:266 -#: src/namestore/plugin_namestore_sqlite.c:248 +#: src/datastore/plugin_datastore_sqlite.c:260 +#: src/namestore/plugin_namestore_sqlite.c:229 #, fuzzy, c-format msgid "Unable to initialize SQLite: %s.\n" msgstr "Imposible inicializar SQLite.\n" -#: src/datastore/plugin_datastore_sqlite.c:669 +#: src/datastore/plugin_datastore_sqlite.c:655 #, fuzzy msgid "Invalid data in database. Trying to fix (by deletion).\n" msgstr "Datos no vĂĄlidos en %s. Intentando fijar (por borrado).\n" -#: src/datastore/plugin_datastore_sqlite.c:1159 +#: src/datastore/plugin_datastore_sqlite.c:1139 msgid "sqlite version to old to determine size, assuming zero\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1178 +#: src/datastore/plugin_datastore_sqlite.c:1158 #, c-format msgid "" "Using sqlite page utilization to estimate payload (%llu pages of size %llu " "bytes)\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1218 -#: src/namestore/plugin_namestore_sqlite.c:779 +#: src/datastore/plugin_datastore_sqlite.c:1198 +#: src/namestore/plugin_namestore_sqlite.c:829 #, fuzzy msgid "Sqlite database running\n" msgstr "base de datos sqlite" @@ -1194,33 +1204,32 @@ msgstr "base de datos sqlite" msgid "Template database running\n" msgstr "" -#: src/dht/dht_api.c:280 +#: src/dht/dht_api.c:348 #, fuzzy msgid "Failed to connect to the DHT service!\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-put.c:172 -#: src/gns/gnunet-gns-lookup.c:179 +#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-monitor.c:293 +#: src/dht/gnunet-dht-put.c:192 msgid "the query key" msgstr "" -#: src/dht/gnunet-dht-get.c:204 src/gns/gnunet-gns-lookup.c:182 +#: src/dht/gnunet-dht-get.c:204 msgid "how many parallel requests (replicas) to create" msgstr "" -#: src/dht/gnunet-dht-get.c:207 src/gns/gnunet-gns-lookup.c:185 +#: src/dht/gnunet-dht-get.c:207 src/dht/gnunet-dht-monitor.c:296 msgid "the type of data to look for" msgstr "" -#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:181 -#: src/gns/gnunet-gns-lookup.c:188 +#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:201 msgid "how long to execute this query before giving up?" msgstr "" -#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-put.c:184 -#: src/fs/gnunet-download.c:270 src/fs/gnunet-publish.c:725 -#: src/fs/gnunet-search.c:297 src/fs/gnunet-unindex.c:169 -#: src/gns/gnunet-gns-lookup.c:191 src/nse/gnunet-nse-profiler.c:908 +#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-monitor.c:302 +#: src/dht/gnunet-dht-put.c:204 src/fs/gnunet-download.c:271 +#: src/fs/gnunet-publish.c:731 src/fs/gnunet-search.c:297 +#: src/fs/gnunet-unindex.c:169 src/nse/gnunet-nse-profiler.c:910 msgid "be verbose (print progress information)" msgstr "" @@ -1228,99 +1237,116 @@ msgstr "" msgid "Issue a GET request to the GNUnet DHT, prints results." msgstr "" -#: src/dht/gnunet-dht-put.c:100 +#: src/dht/gnunet-dht-monitor.c:299 +msgid "how long to execute? 0 = forever" +msgstr "" + +#: src/dht/gnunet-dht-monitor.c:321 +msgid "Prints all packets that go through the DHT." +msgstr "" + +#: src/dht/gnunet-dht-put.c:108 msgid "PUT request sent!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:124 +#: src/dht/gnunet-dht-put.c:111 +msgid "Timeout sending PUT request!\n" +msgstr "" + +#: src/dht/gnunet-dht-put.c:114 +#, fuzzy +msgid "PUT request not confirmed!\n" +msgstr "# mensajes PONG encriptados recibidos" + +#: src/dht/gnunet-dht-put.c:144 msgid "Must provide KEY and DATA for DHT put!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:132 +#: src/dht/gnunet-dht-put.c:152 #, fuzzy, c-format msgid "Could not connect to %s service!\n" msgstr "Imposible conectar con gnunetd.\n" -#: src/dht/gnunet-dht-put.c:137 +#: src/dht/gnunet-dht-put.c:157 #, fuzzy, c-format msgid "Connected to %s service!\n" msgstr "'%s' conectado a '%s'.\n" -#: src/dht/gnunet-dht-put.c:152 +#: src/dht/gnunet-dht-put.c:172 #, c-format msgid "Issuing put request for `%s' with data `%s'!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:166 +#: src/dht/gnunet-dht-put.c:186 msgid "the data to insert under the key" msgstr "" -#: src/dht/gnunet-dht-put.c:169 +#: src/dht/gnunet-dht-put.c:189 msgid "how long to store this entry in the dht (in seconds)" msgstr "" -#: src/dht/gnunet-dht-put.c:175 +#: src/dht/gnunet-dht-put.c:195 msgid "how many replicas to create" msgstr "" -#: src/dht/gnunet-dht-put.c:178 +#: src/dht/gnunet-dht-put.c:198 msgid "the type to insert data as" msgstr "" -#: src/dht/gnunet-dht-put.c:203 +#: src/dht/gnunet-dht-put.c:223 msgid "Issue a PUT request to the GNUnet DHT insert DATA under KEY." msgstr "" -#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:556 -#: src/testing/testing.c:1979 src/testing/testing.c:2009 +#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:544 +#: src/testing/testing.c:1968 src/testing/testing.c:1998 #, fuzzy msgid "Failed to connect to transport service!\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/dht/gnunet-service-dht_clients.c:371 +#: src/dht/gnunet-service-dht_clients.c:407 #, fuzzy msgid "# GET requests from clients injected" msgstr "# mensajes PONG encriptados recibidos" -#: src/dht/gnunet-service-dht_clients.c:462 +#: src/dht/gnunet-service-dht_clients.c:500 #, fuzzy msgid "# PUT requests received from clients" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/dht/gnunet-service-dht_clients.c:529 +#: src/dht/gnunet-service-dht_clients.c:584 #, fuzzy msgid "# GET requests received from clients" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/dht/gnunet-service-dht_clients.c:624 +#: src/dht/gnunet-service-dht_clients.c:682 #, fuzzy msgid "# GET STOP requests received from clients" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/dht/gnunet-service-dht_clients.c:854 +#: src/dht/gnunet-service-dht_clients.c:919 msgid "# Key match, type mismatches in REPLY to CLIENT" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:869 +#: src/dht/gnunet-service-dht_clients.c:932 msgid "# Duplicate REPLIES to CLIENT request dropped" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:906 +#: src/dht/gnunet-service-dht_clients.c:967 #, fuzzy, c-format msgid "Unsupported block type (%u) in request!\n" msgstr "Mensaje no vĂĄlido del tipo %u recibido. Omitiendo.\n" -#: src/dht/gnunet-service-dht_clients.c:928 +#: src/dht/gnunet-service-dht_clients.c:989 #, fuzzy msgid "# RESULTS queued for clients" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/dht/gnunet-service-dht_clients.c:979 -#: src/dht/gnunet-service-dht_clients.c:1022 +#: src/dht/gnunet-service-dht_clients.c:1038 +#: src/dht/gnunet-service-dht_clients.c:1081 msgid "# REPLIES ignored for CLIENTS (no match)" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:989 +#: src/dht/gnunet-service-dht_clients.c:1048 #, fuzzy msgid "Could not pass reply to client, message too big!\n" msgstr "Imposible mandar el mensaje a gnunetd\n" @@ -1334,28 +1360,28 @@ msgstr "# bytes recibidos por TCP" msgid "# ITEMS stored in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:209 +#: src/dht/gnunet-service-dht_datacache.c:207 msgid "# Good RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:220 +#: src/dht/gnunet-service-dht_datacache.c:218 msgid "# Duplicate RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:226 +#: src/dht/gnunet-service-dht_datacache.c:224 msgid "# Invalid RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:238 +#: src/dht/gnunet-service-dht_datacache.c:236 msgid "# Unsupported RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:241 +#: src/dht/gnunet-service-dht_datacache.c:239 #, c-format msgid "Unsupported block type (%u) in local response!\n" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:271 +#: src/dht/gnunet-service-dht_datacache.c:269 #, fuzzy msgid "# GET requests given to datacache" msgstr "# mensajes PONG encriptados recibidos" @@ -1369,96 +1395,90 @@ msgstr "El mensaje recibido del cliente es invĂĄlido\n" msgid "# Preference updates given to core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:573 +#: src/dht/gnunet-service-dht_neighbours.c:571 #, fuzzy msgid "# FIND PEER messages initiated" msgstr "# mensajes fragmentados" -#: src/dht/gnunet-service-dht_neighbours.c:629 -#: src/dht/gnunet-service-dht_neighbours.c:689 -#, fuzzy -msgid "# Peers connected" -msgstr "# de pares conectados" - -#: src/dht/gnunet-service-dht_neighbours.c:723 +#: src/dht/gnunet-service-dht_neighbours.c:717 #, fuzzy msgid "# Queued messages discarded (peer disconnected)" msgstr "# mensajes defragmentados" -#: src/dht/gnunet-service-dht_neighbours.c:778 +#: src/dht/gnunet-service-dht_neighbours.c:772 #, fuzzy msgid "# Bytes transmitted to other peers" msgstr "# bytes recibidos por TCP" -#: src/dht/gnunet-service-dht_neighbours.c:816 +#: src/dht/gnunet-service-dht_neighbours.c:810 #, fuzzy msgid "# Bytes of bandwdith requested from core" msgstr "# mensajes PONG encriptados recibidos" -#: src/dht/gnunet-service-dht_neighbours.c:1040 -#: src/dht/gnunet-service-dht_neighbours.c:1068 +#: src/dht/gnunet-service-dht_neighbours.c:1032 +#: src/dht/gnunet-service-dht_neighbours.c:1060 msgid "# Peers excluded from routing due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1049 -#: src/dht/gnunet-service-dht_neighbours.c:1085 +#: src/dht/gnunet-service-dht_neighbours.c:1041 +#: src/dht/gnunet-service-dht_neighbours.c:1075 #, fuzzy msgid "# Peer selection failed" msgstr "ConexiĂłn fallida\n" -#: src/dht/gnunet-service-dht_neighbours.c:1221 +#: src/dht/gnunet-service-dht_neighbours.c:1207 #, fuzzy msgid "# PUT requests routed" msgstr "# mensajes PONG encriptados recibidos" -#: src/dht/gnunet-service-dht_neighbours.c:1252 +#: src/dht/gnunet-service-dht_neighbours.c:1236 #, fuzzy msgid "# PUT messages queued for transmission" msgstr "# bytes de mensajes salientes omitidos" -#: src/dht/gnunet-service-dht_neighbours.c:1333 +#: src/dht/gnunet-service-dht_neighbours.c:1315 #, fuzzy msgid "# GET requests routed" msgstr "# mensajes PONG encriptados recibidos" -#: src/dht/gnunet-service-dht_neighbours.c:1364 +#: src/dht/gnunet-service-dht_neighbours.c:1342 #, fuzzy msgid "# GET messages queued for transmission" msgstr "# bytes de mensajes salientes omitidos" -#: src/dht/gnunet-service-dht_neighbours.c:1467 +#: src/dht/gnunet-service-dht_neighbours.c:1443 msgid "# RESULT messages queued for transmission" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1555 +#: src/dht/gnunet-service-dht_neighbours.c:1531 #, fuzzy msgid "# P2P PUT requests received" msgstr "# mensajes PONG encriptados recibidos" -#: src/dht/gnunet-service-dht_neighbours.c:1668 +#: src/dht/gnunet-service-dht_neighbours.c:1647 msgid "# FIND PEER requests ignored due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1676 +#: src/dht/gnunet-service-dht_neighbours.c:1655 msgid "# FIND PEER requests ignored due to lack of HELLO" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1767 +#: src/dht/gnunet-service-dht_neighbours.c:1746 #, fuzzy msgid "# P2P GET requests received" msgstr "# mensajes PONG encriptados recibidos" -#: src/dht/gnunet-service-dht_neighbours.c:1811 +#: src/dht/gnunet-service-dht_neighbours.c:1788 #, fuzzy msgid "# P2P FIND PEER requests processed" msgstr "# mensajes PONG encriptados recibidos" -#: src/dht/gnunet-service-dht_neighbours.c:1825 +#: src/dht/gnunet-service-dht_neighbours.c:1802 #, fuzzy msgid "# P2P GET requests ONLY routed" msgstr "# mensajes PONG encriptados recibidos" -#: src/dht/gnunet-service-dht_neighbours.c:1895 +#: src/dht/gnunet-service-dht_neighbours.c:1876 #, fuzzy msgid "# P2P RESULTS received" msgstr "# bytes recibidos por TCP" @@ -1480,29 +1500,28 @@ msgstr "" msgid "# Invalid REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:236 +#: src/dht/gnunet-service-dht_routing.c:238 msgid "# Unsupported REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:314 -#: src/dht/gnunet-service-dht_routing.c:368 +#: src/dht/gnunet-service-dht_routing.c:311 msgid "# Entries removed from routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:324 +#: src/dht/gnunet-service-dht_routing.c:352 msgid "# Entries added to routing table" msgstr "" -#: src/dht/plugin_block_dht.c:124 +#: src/dht/plugin_block_dht.c:136 #, c-format msgid "Block not of type %u\n" msgstr "" -#: src/dht/plugin_block_dht.c:131 +#: src/dht/plugin_block_dht.c:143 msgid "Size mismatch for block\n" msgstr "" -#: src/dht/plugin_block_dht.c:140 +#: src/dht/plugin_block_dht.c:152 #, c-format msgid "Block of type %u is malformed\n" msgstr "" @@ -1531,68 +1550,69 @@ msgstr "" msgid "Change DNS replies to point elsewhere." msgstr "" -#: src/dns/gnunet-service-dns.c:480 +#: src/dns/gnunet-service-dns.c:485 #, fuzzy, c-format msgid "Could not bind to any port: %s\n" msgstr "Imposible encontrar la IP del host '%s': %s\n" -#: src/dns/gnunet-service-dns.c:634 +#: src/dns/gnunet-service-dns.c:639 msgid "# DNS requests answered via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:818 +#: src/dns/gnunet-service-dns.c:822 msgid "# DNS exit failed (failed to open socket)" msgstr "" -#: src/dns/gnunet-service-dns.c:1001 +#: src/dns/gnunet-service-dns.c:1005 #, c-format msgid "Received DNS response that is too small (%u bytes)" msgstr "" -#: src/dns/gnunet-service-dns.c:1046 +#: src/dns/gnunet-service-dns.c:1050 msgid "# External DNS response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1165 +#: src/dns/gnunet-service-dns.c:1168 msgid "# Client response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1198 -msgid "Changing DNS reply according to client specifications\n" -msgstr "" - -#: src/dns/gnunet-service-dns.c:1279 +#: src/dns/gnunet-service-dns.c:1281 msgid "Received malformed IPv4-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1294 +#: src/dns/gnunet-service-dns.c:1297 msgid "Received malformed IPv6-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1303 +#: src/dns/gnunet-service-dns.c:1306 #, c-format msgid "Got non-IP packet with %u bytes and protocol %u from TUN\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1312 +#: src/dns/gnunet-service-dns.c:1315 msgid "# Non-DNS UDP packet received via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:1377 +#: src/dns/gnunet-service-dns.c:1380 #, fuzzy msgid "# DNS requests received via TUN interface" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/dns/gnunet-service-dns.c:1461 +#: src/dns/gnunet-service-dns.c:1465 #, c-format msgid "Configured DNS exit `%s' is not working / valid.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1493 src/exit/gnunet-daemon-exit.c:2673 +#: src/dns/gnunet-service-dns.c:1497 src/exit/gnunet-daemon-exit.c:2674 msgid "# Inbound MESH tunnels created" msgstr "" -#: src/dns/gnunet-service-dns.c:1567 +#: src/dns/gnunet-service-dns.c:1561 src/exit/gnunet-daemon-exit.c:3032 +#, c-format +msgid "`%s' must be installed SUID, refusing to run\n" +msgstr "" + +#: src/dns/gnunet-service-dns.c:1581 msgid "Configured to provide DNS exit, but no valid DNS server configured!\n" msgstr "" @@ -1616,15 +1636,15 @@ msgstr "" msgid "# Bytes transmitted via mesh tunnels" msgstr "# bytes desencriptados" -#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2068 -#: src/exit/gnunet-daemon-exit.c:2318 src/vpn/gnunet-service-vpn.c:1388 -#: src/vpn/gnunet-service-vpn.c:1788 src/vpn/gnunet-service-vpn.c:1951 +#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2069 +#: src/exit/gnunet-daemon-exit.c:2319 src/vpn/gnunet-service-vpn.c:1394 +#: src/vpn/gnunet-service-vpn.c:1795 src/vpn/gnunet-service-vpn.c:1958 msgid "# ICMPv4 packets dropped (type not allowed)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2127 -#: src/exit/gnunet-daemon-exit.c:2377 src/vpn/gnunet-service-vpn.c:1444 -#: src/vpn/gnunet-service-vpn.c:1847 src/vpn/gnunet-service-vpn.c:1984 +#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2128 +#: src/exit/gnunet-daemon-exit.c:2378 src/vpn/gnunet-service-vpn.c:1450 +#: src/vpn/gnunet-service-vpn.c:1854 src/vpn/gnunet-service-vpn.c:1991 msgid "# ICMPv6 packets dropped (type not allowed)" msgstr "" @@ -1673,138 +1693,138 @@ msgstr "" msgid "Packet from unknown protocol %u received. Ignored.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1470 +#: src/exit/gnunet-daemon-exit.c:1471 #, fuzzy msgid "# TCP packets sent via TUN" msgstr "# bytes enviados vĂ­a UDP" -#: src/exit/gnunet-daemon-exit.c:1570 +#: src/exit/gnunet-daemon-exit.c:1571 #, fuzzy msgid "# TCP service creation requests received via mesh" msgstr "# mensajes PONG encriptados recibidos" -#: src/exit/gnunet-daemon-exit.c:1573 src/exit/gnunet-daemon-exit.c:1652 -#: src/exit/gnunet-daemon-exit.c:1762 src/exit/gnunet-daemon-exit.c:1992 -#: src/exit/gnunet-daemon-exit.c:2234 src/exit/gnunet-daemon-exit.c:2515 -#: src/exit/gnunet-daemon-exit.c:2615 +#: src/exit/gnunet-daemon-exit.c:1574 src/exit/gnunet-daemon-exit.c:1653 +#: src/exit/gnunet-daemon-exit.c:1763 src/exit/gnunet-daemon-exit.c:1993 +#: src/exit/gnunet-daemon-exit.c:2235 src/exit/gnunet-daemon-exit.c:2516 +#: src/exit/gnunet-daemon-exit.c:2616 #, fuzzy msgid "# Bytes received from MESH" msgstr "# bytes recibidos vĂ­a HTTP" -#: src/exit/gnunet-daemon-exit.c:1606 src/exit/gnunet-daemon-exit.c:2637 +#: src/exit/gnunet-daemon-exit.c:1607 src/exit/gnunet-daemon-exit.c:2638 #, c-format msgid "No service found for %s on port %d!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1610 +#: src/exit/gnunet-daemon-exit.c:1611 #, fuzzy msgid "# TCP requests dropped (no such service)" msgstr "# Anuncios de los pares recibidos" -#: src/exit/gnunet-daemon-exit.c:1655 +#: src/exit/gnunet-daemon-exit.c:1656 #, fuzzy msgid "# TCP IP-exit creation requests received via mesh" msgstr "# mensajes PONG encriptados recibidos" -#: src/exit/gnunet-daemon-exit.c:1765 +#: src/exit/gnunet-daemon-exit.c:1766 #, fuzzy msgid "# TCP data requests received via mesh" msgstr "# mensajes PONG encriptados recibidos" -#: src/exit/gnunet-daemon-exit.c:1779 +#: src/exit/gnunet-daemon-exit.c:1780 #, fuzzy msgid "# TCP DATA requests dropped (no session)" msgstr "# Anuncios de los pares recibidos" -#: src/exit/gnunet-daemon-exit.c:1829 +#: src/exit/gnunet-daemon-exit.c:1830 #, fuzzy msgid "# ICMP packets sent via TUN" msgstr "# bytes enviados vĂ­a UDP" -#: src/exit/gnunet-daemon-exit.c:1995 +#: src/exit/gnunet-daemon-exit.c:1996 #, fuzzy msgid "# ICMP IP-exit requests received via mesh" msgstr "# mensajes PONG encriptados recibidos" -#: src/exit/gnunet-daemon-exit.c:2237 +#: src/exit/gnunet-daemon-exit.c:2238 #, fuzzy msgid "# ICMP service requests received via mesh" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/exit/gnunet-daemon-exit.c:2303 src/vpn/gnunet-service-vpn.c:1378 -#: src/vpn/gnunet-service-vpn.c:1945 +#: src/exit/gnunet-daemon-exit.c:2304 src/vpn/gnunet-service-vpn.c:1384 +#: src/vpn/gnunet-service-vpn.c:1952 msgid "# ICMPv4 packets dropped (impossible PT to v6)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2362 src/vpn/gnunet-service-vpn.c:1414 -#: src/vpn/gnunet-service-vpn.c:1426 src/vpn/gnunet-service-vpn.c:1835 +#: src/exit/gnunet-daemon-exit.c:2363 src/vpn/gnunet-service-vpn.c:1420 +#: src/vpn/gnunet-service-vpn.c:1432 src/vpn/gnunet-service-vpn.c:1842 msgid "# ICMPv6 packets dropped (impossible PT to v4)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2412 +#: src/exit/gnunet-daemon-exit.c:2413 #, fuzzy msgid "# UDP packets sent via TUN" msgstr "# bytes enviados vĂ­a UDP" -#: src/exit/gnunet-daemon-exit.c:2518 +#: src/exit/gnunet-daemon-exit.c:2519 #, fuzzy msgid "# UDP IP-exit requests received via mesh" msgstr "# mensajes PONG encriptados recibidos" -#: src/exit/gnunet-daemon-exit.c:2618 +#: src/exit/gnunet-daemon-exit.c:2619 #, fuzzy msgid "# UDP service requests received via mesh" msgstr "# mensajes PONG encriptados recibidos" -#: src/exit/gnunet-daemon-exit.c:2641 +#: src/exit/gnunet-daemon-exit.c:2642 #, fuzzy msgid "# UDP requests dropped (no such service)" msgstr "# Anuncios de los pares recibidos" -#: src/exit/gnunet-daemon-exit.c:2881 +#: src/exit/gnunet-daemon-exit.c:2882 #, c-format msgid "No addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2895 src/exit/gnunet-daemon-exit.c:2907 +#: src/exit/gnunet-daemon-exit.c:2896 src/exit/gnunet-daemon-exit.c:2908 #, c-format msgid "Service `%s' configured for IPv4, but IPv4 is disabled!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2918 +#: src/exit/gnunet-daemon-exit.c:2919 #, c-format msgid "No IP addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3047 +#: src/exit/gnunet-daemon-exit.c:3048 msgid "" "This system does not support IPv4, will disable IPv4 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3055 +#: src/exit/gnunet-daemon-exit.c:3056 msgid "" "This system does not support IPv6, will disable IPv6 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3062 +#: src/exit/gnunet-daemon-exit.c:3063 msgid "" "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use " "ENABLE_IPv4=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3068 +#: src/exit/gnunet-daemon-exit.c:3069 msgid "" "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use " "ENABLE_IPv6=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3074 src/pt/gnunet-daemon-pt.c:884 +#: src/exit/gnunet-daemon-exit.c:3075 src/pt/gnunet-daemon-pt.c:884 msgid "No useful service enabled. Exiting.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3235 +#: src/exit/gnunet-daemon-exit.c:3236 msgid "Daemon to run to provide an IP exit node for the VPN" msgstr "" @@ -1812,122 +1832,127 @@ msgstr "" msgid "# acknowledgements sent for fragment" msgstr "" -#: src/fragmentation/defragmentation.c:454 +#: src/fragmentation/defragmentation.c:456 #, fuzzy msgid "# fragments received" msgstr "# fragmentos descartados" -#: src/fragmentation/defragmentation.c:513 +#: src/fragmentation/defragmentation.c:521 #, fuzzy msgid "# duplicate fragments received" msgstr "# bytes recibidos por TCP" -#: src/fragmentation/defragmentation.c:526 +#: src/fragmentation/defragmentation.c:534 msgid "# messages defragmented" msgstr "# mensajes defragmentados" -#: src/fragmentation/fragmentation.c:188 +#: src/fragmentation/fragmentation.c:203 #, fuzzy msgid "# fragments transmitted" msgstr "# Auto-anuncios transmitidos" -#: src/fragmentation/fragmentation.c:191 +#: src/fragmentation/fragmentation.c:206 #, fuzzy msgid "# fragments retransmitted" msgstr "# Auto-anuncios transmitidos" -#: src/fragmentation/fragmentation.c:255 +#: src/fragmentation/fragmentation.c:232 +#, fuzzy +msgid "# fragments wrap arounds" +msgstr "# Auto-anuncios transmitidos" + +#: src/fragmentation/fragmentation.c:273 msgid "# messages fragmented" msgstr "# mensajes fragmentados" -#: src/fragmentation/fragmentation.c:258 +#: src/fragmentation/fragmentation.c:276 msgid "# total size of fragmented messages" msgstr "" -#: src/fragmentation/fragmentation.c:343 +#: src/fragmentation/fragmentation.c:363 #, fuzzy msgid "# fragment acknowledgements received" msgstr "# Anuncios de los pares recibidos" -#: src/fragmentation/fragmentation.c:349 +#: src/fragmentation/fragmentation.c:369 msgid "# bits removed from fragmentation ACKs" msgstr "" -#: src/fragmentation/fragmentation.c:373 +#: src/fragmentation/fragmentation.c:393 #, fuzzy msgid "# fragmentation transmissions completed" msgstr "# mensajes de texto mandados por PING" -#: src/fs/fs_api.c:284 +#: src/fs/fs_api.c:339 #, fuzzy, c-format msgid "Could not open file `%s': %s" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_api.c:293 +#: src/fs/fs_api.c:348 #, fuzzy, c-format msgid "Could not read file `%s': %s" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_api.c:299 +#: src/fs/fs_api.c:354 #, c-format msgid "Short read reading from file `%s'!" msgstr "" -#: src/fs/fs_api.c:877 +#: src/fs/fs_api.c:938 #, fuzzy, c-format msgid "Failed to resume publishing information `%s': %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_api.c:1334 +#: src/fs/fs_api.c:1395 #, c-format msgid "Failed to recover namespace `%s', cannot resume publishing operation.\n" msgstr "" -#: src/fs/fs_api.c:1376 +#: src/fs/fs_api.c:1437 #, c-format msgid "Failure while resuming publishing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:1392 +#: src/fs/fs_api.c:1453 #, fuzzy, c-format msgid "Failed to resume publishing operation `%s': %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_api.c:2004 +#: src/fs/fs_api.c:2106 #, c-format msgid "Failure while resuming unindexing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2014 +#: src/fs/fs_api.c:2116 #, fuzzy, c-format msgid "Failed to resume unindexing operation `%s': %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_api.c:2139 src/fs/fs_api.c:2378 +#: src/fs/fs_api.c:2241 src/fs/fs_api.c:2480 #, fuzzy, c-format msgid "Failed to resume sub-download `%s': %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_api.c:2156 +#: src/fs/fs_api.c:2258 #, fuzzy, c-format msgid "Failed to resume sub-search `%s': %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_api.c:2168 src/fs/fs_api.c:2187 src/fs/fs_api.c:2671 +#: src/fs/fs_api.c:2270 src/fs/fs_api.c:2289 src/fs/fs_api.c:2773 #, c-format msgid "Failure while resuming search operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2369 +#: src/fs/fs_api.c:2471 #, c-format msgid "Failed to resume sub-download `%s': could not open file `%s'\n" msgstr "" -#: src/fs/fs_api.c:2615 +#: src/fs/fs_api.c:2717 msgid "Could not resume running search, will resume as paused search\n" msgstr "" -#: src/fs/fs_api.c:2709 +#: src/fs/fs_api.c:2811 #, c-format msgid "Failure while resuming download operation `%s': %s\n" msgstr "" @@ -1937,53 +1962,58 @@ msgstr "" msgid "MAGIC mismatch. This is not a GNUnet directory.\n" msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" -#: src/fs/fs_download.c:310 +#: src/fs/fs_download.c:311 msgid "" "Recursive downloads of directories larger than 4 GB are not supported on 32-" "bit systems\n" msgstr "" -#: src/fs/fs_download.c:330 +#: src/fs/fs_download.c:331 msgid "Directory too large for system address space\n" msgstr "" -#: src/fs/fs_download.c:488 src/fs/fs_download.c:500 +#: src/fs/fs_download.c:497 src/fs/fs_download.c:509 #, fuzzy, c-format msgid "Failed to open file `%s' for writing" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_download.c:870 +#: src/fs/fs_download.c:878 #, fuzzy, c-format msgid "Failed to create directory for recursive download of `%s'\n" msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" -#: src/fs/fs_download.c:951 +#: src/fs/fs_download.c:960 #, c-format msgid "" "Internal error or bogus download URI (expected %u bytes at depth %u and " -"offset %llu/%llu, got %u bytes)\n" +"offset %llu/%llu, got %u bytes)" msgstr "" -#: src/fs/fs_download.c:977 +#: src/fs/fs_download.c:986 msgid "internal error decrypting content" msgstr "" -#: src/fs/fs_download.c:1000 +#: src/fs/fs_download.c:1009 #, fuzzy, c-format -msgid "Download failed: could not open file `%s': %s\n" +msgid "Download failed: could not open file `%s': %s" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_download.c:1010 +#: src/fs/fs_download.c:1019 #, fuzzy, c-format -msgid "Failed to seek to offset %llu in file `%s': %s\n" +msgid "Failed to seek to offset %llu in file `%s': %s" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/fs_download.c:1019 -#, c-format -msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s\n" -msgstr "" +#: src/fs/fs_download.c:1028 +#, fuzzy, c-format +msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s" +msgstr "Fichero almacenado en '%s'.\n" + +#: src/fs/fs_download.c:1125 +#, fuzzy +msgid "internal error decoding tree" +msgstr "=\tError leyendo el directorio.\n" -#: src/fs/fs_download.c:1835 +#: src/fs/fs_download.c:1888 #, fuzzy msgid "Invalid URI" msgstr "Argumento no vĂĄlido: '%s'\n" @@ -2069,69 +2099,69 @@ msgstr "Error desconocido.\n" msgid "Failed to connect to datastore." msgstr "Fallo al conectarse a gnunetd" -#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:395 +#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:397 #, fuzzy, c-format msgid "Publishing failed: %s" msgstr "" "\n" "Error subiendo el fichero %s\n" -#: src/fs/fs_publish.c:616 src/fs/fs_publish.c:633 src/fs/fs_publish.c:672 -#: src/fs/fs_publish.c:692 src/fs/fs_publish.c:717 src/fs/fs_publish.c:857 +#: src/fs/fs_publish.c:621 src/fs/fs_publish.c:638 src/fs/fs_publish.c:677 +#: src/fs/fs_publish.c:697 src/fs/fs_publish.c:722 src/fs/fs_publish.c:862 #, fuzzy, c-format msgid "Can not index file `%s': %s. Will try to insert instead.\n" msgstr "IndexaciĂłn del fichero '%s' fallida. Intentando insertar fichero...\n" -#: src/fs/fs_publish.c:618 +#: src/fs/fs_publish.c:623 msgid "timeout on index-start request to `fs' service" msgstr "" -#: src/fs/fs_publish.c:630 +#: src/fs/fs_publish.c:635 #, fuzzy msgid "unknown error" msgstr "Error desconocido" -#: src/fs/fs_publish.c:673 +#: src/fs/fs_publish.c:678 msgid "failed to compute hash" msgstr "" -#: src/fs/fs_publish.c:693 +#: src/fs/fs_publish.c:698 msgid "filename too long" msgstr "" -#: src/fs/fs_publish.c:718 +#: src/fs/fs_publish.c:723 #, fuzzy msgid "could not connect to `fs' service" msgstr "Imposible conectar con gnunetd.\n" -#: src/fs/fs_publish.c:741 +#: src/fs/fs_publish.c:746 #, fuzzy, c-format msgid "Failed to get file identifiers for `%s'\n" msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" -#: src/fs/fs_publish.c:806 +#: src/fs/fs_publish.c:811 #, fuzzy, c-format msgid "Recursive upload failed at `%s': %s" msgstr "'%s' fallĂł en %s: %d con error: '%s'.\n" -#: src/fs/fs_publish.c:812 +#: src/fs/fs_publish.c:817 #, fuzzy, c-format msgid "Recursive upload failed: %s" msgstr "" "\n" "Error subiendo el fichero %s\n" -#: src/fs/fs_publish.c:858 +#: src/fs/fs_publish.c:863 #, fuzzy msgid "needs to be an actual file" msgstr "'%s' no es un fichero regular.\n" -#: src/fs/fs_publish.c:1067 +#: src/fs/fs_publish.c:1071 #, c-format msgid "Insufficient space for publishing: %s" msgstr "" -#: src/fs/fs_publish.c:1138 +#: src/fs/fs_publish.c:1142 #, c-format msgid "Reserving space for %u entries and %llu bytes for publication\n" msgstr "" @@ -2141,7 +2171,7 @@ msgstr "" msgid "Could not connect to datastore." msgstr "Imposible conectar con gnunetd.\n" -#: src/fs/fs_search.c:810 +#: src/fs/fs_search.c:829 #, c-format msgid "Got result with unknown block type `%d', ignoring" msgstr "" @@ -2151,44 +2181,64 @@ msgstr "" msgid "Failed to start daemon: %s\n" msgstr "FallĂł al comenzar la recolecciĂłn.\n" -#: src/fs/fs_unindex.c:57 +#: src/fs/fs_unindex.c:58 msgid "Failed to find given position in file" msgstr "" -#: src/fs/fs_unindex.c:62 +#: src/fs/fs_unindex.c:63 #, fuzzy msgid "Failed to read file" msgstr "FallĂł al entregar el mensaje '%s'.\n" -#: src/fs/fs_unindex.c:231 +#: src/fs/fs_unindex.c:233 msgid "Unexpected time for a response from `fs' service." msgstr "" -#: src/fs/fs_unindex.c:239 +#: src/fs/fs_unindex.c:241 msgid "Timeout waiting for `fs' service." msgstr "" -#: src/fs/fs_unindex.c:247 +#: src/fs/fs_unindex.c:249 #, fuzzy msgid "Invalid response from `fs' service." msgstr "Respuesta invĂĄlida a '%s'.\n" -#: src/fs/fs_unindex.c:292 +#: src/fs/fs_unindex.c:293 #, fuzzy msgid "Failed to connect to FS service for unindexing." msgstr "Fallo al conectarse a gnunetd" -#: src/fs/fs_unindex.c:325 +#: src/fs/fs_unindex.c:344 +#, fuzzy +msgid "Failed to get KSKs from directory scan." +msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" + +#: src/fs/fs_unindex.c:356 +#, fuzzy, c-format +msgid "Internal error scanning `%s'.\n" +msgstr "=\tError leyendo el directorio.\n" + +#: src/fs/fs_unindex.c:411 +#, fuzzy, c-format +msgid "Failed to remove KBlock: %s\n" +msgstr "Fichero almacenado en '%s'.\n" + +#: src/fs/fs_unindex.c:501 +#, fuzzy, c-format +msgid "Failed to parse URI `%s' from KBlock!\n" +msgstr "El fichero '%s' tiene la URI: '%s'\n" + +#: src/fs/fs_unindex.c:553 src/fs/fs_unindex.c:618 #, fuzzy msgid "Failed to connect to `datastore' service." msgstr "FallĂł al inicializar el servicio '%s'.\n" -#: src/fs/fs_unindex.c:338 +#: src/fs/fs_unindex.c:631 #, fuzzy msgid "Failed to open file for unindexing." msgstr "Fallo al conectarse a gnunetd" -#: src/fs/fs_unindex.c:372 +#: src/fs/fs_unindex.c:665 #, fuzzy msgid "Failed to compute hash of file." msgstr "Fallo al conectarse a gnunetd" @@ -2301,92 +2351,92 @@ msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" msgid "Display contents of a GNUnet directory" msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" -#: src/fs/gnunet-download.c:100 +#: src/fs/gnunet-download.c:101 #, fuzzy, c-format msgid "Starting download `%s'.\n" msgstr "Iniciada colecciĂłn '%s'.\n" -#: src/fs/gnunet-download.c:109 +#: src/fs/gnunet-download.c:110 #, fuzzy msgid "" msgstr "Error desconocido" -#: src/fs/gnunet-download.c:118 +#: src/fs/gnunet-download.c:119 #, c-format msgid "" "Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to " "download\n" msgstr "" -#: src/fs/gnunet-download.c:128 +#: src/fs/gnunet-download.c:129 #, fuzzy, c-format msgid "Error downloading: %s.\n" msgstr "Error descargando: %s\n" -#: src/fs/gnunet-download.c:136 +#: src/fs/gnunet-download.c:137 #, fuzzy, c-format msgid "Downloading `%s' done (%s/s).\n" msgstr "ÂĄSubida rechazada!" -#: src/fs/gnunet-download.c:151 src/fs/gnunet-publish.c:190 +#: src/fs/gnunet-download.c:152 src/fs/gnunet-publish.c:190 #: src/fs/gnunet-search.c:190 src/fs/gnunet-unindex.c:109 #, fuzzy, c-format msgid "Unexpected status: %d\n" msgstr "Estado de descarga inesperado." -#: src/fs/gnunet-download.c:176 +#: src/fs/gnunet-download.c:177 #, fuzzy msgid "You need to specify a URI argument.\n" msgstr "ÂĄDebes especificar un receptor!\n" -#: src/fs/gnunet-download.c:182 src/fs/gnunet-publish.c:618 +#: src/fs/gnunet-download.c:183 src/fs/gnunet-publish.c:624 #, fuzzy, c-format msgid "Failed to parse URI: %s\n" msgstr "El fichero '%s' tiene la URI: '%s'\n" -#: src/fs/gnunet-download.c:189 +#: src/fs/gnunet-download.c:190 msgid "Only CHK or LOC URIs supported.\n" msgstr "" -#: src/fs/gnunet-download.c:196 +#: src/fs/gnunet-download.c:197 msgid "Target filename must be specified.\n" msgstr "" -#: src/fs/gnunet-download.c:210 src/fs/gnunet-publish.c:596 +#: src/fs/gnunet-download.c:211 src/fs/gnunet-publish.c:602 #: src/fs/gnunet-search.c:241 src/fs/gnunet-unindex.c:141 #, fuzzy, c-format msgid "Could not initialize `%s' subsystem.\n" msgstr "FallĂł al inicializar el servicio '%s'.\n" -#: src/fs/gnunet-download.c:247 src/fs/gnunet-search.c:285 +#: src/fs/gnunet-download.c:248 src/fs/gnunet-search.c:285 msgid "set the desired LEVEL of receiver-anonymity" msgstr "seleccione el NIVEL deseado de anonimidad-del-receptor" -#: src/fs/gnunet-download.c:250 +#: src/fs/gnunet-download.c:251 msgid "delete incomplete downloads (when aborted with CTRL-C)" msgstr "" -#: src/fs/gnunet-download.c:253 src/fs/gnunet-search.c:288 +#: src/fs/gnunet-download.c:254 src/fs/gnunet-search.c:288 msgid "only search the local peer (no P2P network search)" msgstr "" -#: src/fs/gnunet-download.c:256 +#: src/fs/gnunet-download.c:257 msgid "write the file to FILENAME" msgstr "escribe el fichero al FICHERO" -#: src/fs/gnunet-download.c:260 +#: src/fs/gnunet-download.c:261 msgid "set the maximum number of parallel downloads that is allowed" msgstr "" -#: src/fs/gnunet-download.c:264 +#: src/fs/gnunet-download.c:265 msgid "set the maximum number of parallel requests for blocks that is allowed" msgstr "" -#: src/fs/gnunet-download.c:267 +#: src/fs/gnunet-download.c:268 msgid "download a GNUnet directory recursively" msgstr "descarga un directorio de GNUnet recursivamente" -#: src/fs/gnunet-download.c:277 +#: src/fs/gnunet-download.c:278 msgid "" "Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/" "chk/...)" @@ -2400,35 +2450,30 @@ msgstr "" msgid "Special file-sharing operations" msgstr "" -#: src/fs/gnunet-pseudonym.c:151 src/statistics/gnunet-statistics.c:126 +#: src/fs/gnunet-pseudonym.c:160 src/statistics/gnunet-statistics.c:167 #, fuzzy, c-format msgid "Invalid argument `%s'\n" msgstr "Argumento no vĂĄlido: '%s'\n" -#: src/fs/gnunet-pseudonym.c:165 -#, fuzzy, c-format -msgid "Namespace `%s' unknown.\n" -msgstr "El espacio '%s' ha sido valorado con un %d.\n" - -#: src/fs/gnunet-pseudonym.c:240 src/fs/gnunet-pseudonym.c:247 -#: src/fs/gnunet-pseudonym.c:249 +#: src/fs/gnunet-pseudonym.c:250 src/fs/gnunet-pseudonym.c:257 +#: src/fs/gnunet-pseudonym.c:259 #, fuzzy, c-format msgid "Option `%s' ignored\n" msgstr "%s: la opciĂłn '%s' es ambigua\n" -#: src/fs/gnunet-pseudonym.c:269 src/fs/gnunet-publish.c:672 +#: src/fs/gnunet-pseudonym.c:279 src/fs/gnunet-publish.c:678 msgid "set the desired LEVEL of sender-anonymity" msgstr "seleccione el NIVEL deseado de anonimato al enviar" -#: src/fs/gnunet-pseudonym.c:272 +#: src/fs/gnunet-pseudonym.c:282 msgid "create or advertise namespace NAME" msgstr "" -#: src/fs/gnunet-pseudonym.c:275 +#: src/fs/gnunet-pseudonym.c:285 msgid "delete namespace NAME " msgstr "" -#: src/fs/gnunet-pseudonym.c:278 +#: src/fs/gnunet-pseudonym.c:288 #, fuzzy msgid "" "add an additional keyword for the advertisment (this option can be specified " @@ -2437,38 +2482,38 @@ msgstr "" "aĂąade una clave adicional para todos los ficheros y directorios (esta opciĂłn " "puede ser especificada varias veces)" -#: src/fs/gnunet-pseudonym.c:282 src/fs/gnunet-publish.c:691 +#: src/fs/gnunet-pseudonym.c:292 src/fs/gnunet-publish.c:697 msgid "set the meta-data for the given TYPE to the given VALUE" msgstr "cambia el meta-dato para el TIPO dado al VALOR dado" -#: src/fs/gnunet-pseudonym.c:285 +#: src/fs/gnunet-pseudonym.c:295 #, fuzzy msgid "print names of local namespaces" msgstr "cambia la valoraciĂłn de un espacio" -#: src/fs/gnunet-pseudonym.c:288 +#: src/fs/gnunet-pseudonym.c:298 msgid "use the given PRIORITY for the advertisments" msgstr "" -#: src/fs/gnunet-pseudonym.c:291 +#: src/fs/gnunet-pseudonym.c:301 msgid "do not print names of remote namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:294 src/fs/gnunet-publish.c:710 +#: src/fs/gnunet-pseudonym.c:304 src/fs/gnunet-publish.c:716 msgid "set the desired replication LEVEL" msgstr "" -#: src/fs/gnunet-pseudonym.c:297 +#: src/fs/gnunet-pseudonym.c:307 #, fuzzy msgid "specify ID of the root of the namespace" msgstr "cambia la valoraciĂłn de un espacio" -#: src/fs/gnunet-pseudonym.c:300 +#: src/fs/gnunet-pseudonym.c:310 #, fuzzy msgid "change rating of namespace ID by VALUE" msgstr "cambia la valoraciĂłn de un espacio" -#: src/fs/gnunet-pseudonym.c:308 +#: src/fs/gnunet-pseudonym.c:318 msgid "Manage GNUnet pseudonyms." msgstr "" @@ -2497,116 +2542,116 @@ msgstr "Yo soy el par '%s'.\n" msgid "Cleanup after abort complete.\n" msgstr "'%s' comienzo completo.\n" -#: src/fs/gnunet-publish.c:299 +#: src/fs/gnunet-publish.c:305 #, fuzzy, c-format msgid "Meta data for file `%s' (%s)\n" msgstr "Actualizando los datos del mĂłdulo '%s'\n" -#: src/fs/gnunet-publish.c:301 +#: src/fs/gnunet-publish.c:307 #, fuzzy, c-format msgid "Keywords for file `%s' (%s)\n" msgstr "Claves para los ficheros '%s':\n" -#: src/fs/gnunet-publish.c:352 +#: src/fs/gnunet-publish.c:358 #, fuzzy, c-format msgid "Failed to create namespace `%s'\n" msgstr "Imposible crear el espacio '%s' (Âżexiste?).\n" -#: src/fs/gnunet-publish.c:427 +#: src/fs/gnunet-publish.c:433 #, fuzzy msgid "Could not publish\n" msgstr "Imposible ejecutar '%s': %s\n" -#: src/fs/gnunet-publish.c:454 +#: src/fs/gnunet-publish.c:460 #, fuzzy msgid "Could not start publishing.\n" msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" -#: src/fs/gnunet-publish.c:485 +#: src/fs/gnunet-publish.c:491 #, fuzzy, c-format msgid "Scanning directory `%s'.\n" msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" -#: src/fs/gnunet-publish.c:487 +#: src/fs/gnunet-publish.c:493 #, fuzzy, c-format msgid "Scanning file `%s'.\n" msgstr "Iniciada colecciĂłn '%s'.\n" -#: src/fs/gnunet-publish.c:492 +#: src/fs/gnunet-publish.c:498 #, c-format msgid "There was trouble processing file `%s', skipping it.\n" msgstr "" -#: src/fs/gnunet-publish.c:497 +#: src/fs/gnunet-publish.c:503 #, fuzzy msgid "Preprocessing complete.\n" msgstr "Cierre completado.\n" -#: src/fs/gnunet-publish.c:501 +#: src/fs/gnunet-publish.c:507 #, fuzzy, c-format msgid "Extracting meta data from file `%s' complete.\n" msgstr "Actualizando los datos del mĂłdulo '%s'\n" -#: src/fs/gnunet-publish.c:505 +#: src/fs/gnunet-publish.c:511 msgid "Meta data extraction has finished.\n" msgstr "" -#: src/fs/gnunet-publish.c:512 +#: src/fs/gnunet-publish.c:518 #, fuzzy msgid "Internal error scanning directory.\n" msgstr "=\tError leyendo el directorio.\n" -#: src/fs/gnunet-publish.c:546 +#: src/fs/gnunet-publish.c:552 #, c-format msgid "Cannot extract metadata from a URI!\n" msgstr "" -#: src/fs/gnunet-publish.c:553 +#: src/fs/gnunet-publish.c:559 #, fuzzy, c-format msgid "You must specify one and only one filename for insertion.\n" msgstr "Debes especificar uno y solo un fichero para desindexar.\n" -#: src/fs/gnunet-publish.c:559 +#: src/fs/gnunet-publish.c:565 #, fuzzy, c-format msgid "You must NOT specify an URI and a filename.\n" msgstr "ÂĄDebes especificar un receptor!\n" -#: src/fs/gnunet-publish.c:567 src/vpn/gnunet-vpn.c:214 +#: src/fs/gnunet-publish.c:573 src/vpn/gnunet-vpn.c:214 #, fuzzy, c-format msgid "Option `%s' is required when using option `%s'.\n" msgstr "La opciĂłn '%s' no tiene sentido sin la opciĂłn '%s'.\n" -#: src/fs/gnunet-publish.c:577 src/fs/gnunet-publish.c:584 -#: src/transport/gnunet-transport.c:530 +#: src/fs/gnunet-publish.c:583 src/fs/gnunet-publish.c:590 +#: src/transport/gnunet-transport.c:560 #, c-format msgid "Option `%s' makes no sense without option `%s'.\n" msgstr "La opciĂłn '%s' no tiene sentido sin la opciĂłn '%s'.\n" -#: src/fs/gnunet-publish.c:606 +#: src/fs/gnunet-publish.c:612 #, fuzzy, c-format msgid "Could not create namespace `%s'\n" msgstr "Imposible crear el espacio '%s' (Âżexiste?).\n" -#: src/fs/gnunet-publish.c:639 +#: src/fs/gnunet-publish.c:645 #, fuzzy, c-format msgid "Failed to access `%s': %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/fs/gnunet-publish.c:651 +#: src/fs/gnunet-publish.c:657 msgid "" "Failed to start meta directory scanner. Is gnunet-helper-publish-fs " "installed?\n" msgstr "" -#: src/fs/gnunet-publish.c:676 +#: src/fs/gnunet-publish.c:682 msgid "disable adding the creation time to the metadata of the uploaded file" msgstr "" -#: src/fs/gnunet-publish.c:679 +#: src/fs/gnunet-publish.c:685 msgid "do not use libextractor to add keywords or metadata" msgstr "" -#: src/fs/gnunet-publish.c:683 +#: src/fs/gnunet-publish.c:689 msgid "" "print list of extracted keywords that would be used, but do not perform " "upload" @@ -2614,7 +2659,7 @@ msgstr "" "imprime la lista de las claves extraidas que podrĂ­an ser usadas, pero no " "realiza la subida" -#: src/fs/gnunet-publish.c:687 +#: src/fs/gnunet-publish.c:693 msgid "" "add an additional keyword for the top-level file or directory (this option " "can be specified multiple times)" @@ -2622,7 +2667,7 @@ msgstr "" "aĂąade una clave adicional para el fichero del nivel mĂĄs alto o el directorio " "(esta opciĂłn puede ser especificada varias veces)" -#: src/fs/gnunet-publish.c:694 +#: src/fs/gnunet-publish.c:700 msgid "" "do not index, perform full insertion (stores entire file in encrypted form " "in GNUnet database)" @@ -2630,7 +2675,7 @@ msgstr "" "no indexar, hacer inserciones totales (almacena el fichero entero de forma " "encriptada en la base de datos de GNUnet)" -#: src/fs/gnunet-publish.c:699 +#: src/fs/gnunet-publish.c:705 msgid "" "specify ID of an updated version to be published in the future (for " "namespace insertions only)" @@ -2638,36 +2683,36 @@ msgstr "" "especifica la ID de una versiĂłn actualizada para ser publicada en el futuro " "(para inserciones en el espacio Ăşnicamente)" -#: src/fs/gnunet-publish.c:703 +#: src/fs/gnunet-publish.c:709 msgid "specify the priority of the content" msgstr "especifica la prioridad del contenido" -#: src/fs/gnunet-publish.c:707 +#: src/fs/gnunet-publish.c:713 msgid "publish the files under the pseudonym NAME (place file into namespace)" msgstr "" "publica los ficheros bajo el pseudĂłnimo NOMBRE (coloca el fichero en el " "espacio)" -#: src/fs/gnunet-publish.c:713 +#: src/fs/gnunet-publish.c:719 msgid "" "only simulate the process but do not do any actual publishing (useful to " "compute URIs)" msgstr "" -#: src/fs/gnunet-publish.c:717 +#: src/fs/gnunet-publish.c:723 msgid "" "set the ID of this version of the publication (for namespace insertions only)" msgstr "" "cambia la ID de esta versiĂłn de la publicaciĂłn (para inserciones en el " "espacio Ăşnicamente)" -#: src/fs/gnunet-publish.c:721 +#: src/fs/gnunet-publish.c:727 msgid "" "URI to be published (can be used instead of passing a file to add keywords " "to the file with the respective URI)" msgstr "" -#: src/fs/gnunet-publish.c:736 +#: src/fs/gnunet-publish.c:742 msgid "Publish a file or directory on GNUnet" msgstr "" @@ -2716,24 +2761,12 @@ msgid "# Loopback routes suppressed" msgstr "" #: src/fs/gnunet-service-fs.c:581 src/hostlist/gnunet-daemon-hostlist.c:297 -#: src/topology/gnunet-daemon-topology.c:1290 -#: src/topology/gnunet-daemon-topology.c:1297 +#: src/topology/gnunet-daemon-topology.c:1330 +#: src/topology/gnunet-daemon-topology.c:1337 #, fuzzy, c-format msgid "Failed to connect to `%s' service.\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 -#: src/topology/gnunet-daemon-topology.c:654 -#: src/topology/gnunet-daemon-topology.c:756 -#: src/transport/gnunet-service-transport_neighbours.c:960 -#: src/transport/gnunet-service-transport_neighbours.c:1289 -#: src/transport/gnunet-service-transport_neighbours.c:1841 -#: src/transport/gnunet-service-transport_neighbours.c:2499 -#: src/transport/gnunet-service-transport_neighbours.c:2566 -#, fuzzy -msgid "# peers connected" -msgstr "# de pares conectados" - #: src/fs/gnunet-service-fs_cp.c:696 #, fuzzy msgid "# migration stop messages received" @@ -3084,15 +3117,132 @@ msgstr "" msgid "Reply mismatched in terms of namespace. Discarded.\n" msgstr "" -#: src/gns/gns_api.c:221 +#: src/gns/gnunet-gns.c:191 #, fuzzy -msgid "Failed to connect to the GNS service!\n" +msgid "Failed to connect to GNS\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/gns/gnunet-gns-lookup.c:210 -msgid "Issue a request to the GNUnet Naming System, prints results." +#: src/gns/gnunet-gns.c:232 +msgid "try to shorten a given GNS name" +msgstr "" + +#: src/gns/gnunet-gns.c:235 +msgid "Lookup a record using GNS (NOT IMPLEMENTED)" +msgstr "" + +#: src/gns/gnunet-gns.c:238 +msgid "Get the authority of a particular name" +msgstr "" + +#: src/gns/gnunet-gns.c:241 +#, fuzzy +msgid "Specify the type of the record lookup" +msgstr "especifica la prioridad del contenido" + +#: src/gns/gnunet-gns.c:244 +msgid "No unneeded output" +msgstr "" + +#: src/gns/gnunet-gns.c:255 +msgid "GNUnet GNS access tool" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:280 +#, fuzzy, c-format +msgid "Unsupported form value `%s'\n" +msgstr "Comando inesperado '%s'. Abortando.\n" + +#: src/gns/gnunet-gns-fcfsd.c:333 +#, fuzzy, c-format +msgid "Failed to create record for domain `%s': %s\n" +msgstr "Imposible pasar el fichero de configuraciĂłn '%s'.\n" + +#: src/gns/gnunet-gns-fcfsd.c:377 +#, c-format +msgid "Found existing name `%s' for the given key\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:439 +#, c-format +msgid "Found %u existing records for domain `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:498 +#, fuzzy, c-format +msgid "Failed to create page for `%s'\n" +msgstr "Imposible crear el espacio '%s' (Âżexiste?).\n" + +#: src/gns/gnunet-gns-fcfsd.c:514 +#, fuzzy, c-format +msgid "Failed to setup post processor for `%s'\n" +msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" + +#: src/gns/gnunet-gns-fcfsd.c:725 src/gns/gnunet-gns-fcfsd.c:737 +#, fuzzy, c-format +msgid "Option `%s' not specified in configuration section `%s'\n" +msgstr "ÂĄNinguna aplicaciĂłn definida en la configuraciĂłn!\n" + +#: src/gns/gnunet-gns-fcfsd.c:747 src/namestore/gnunet-namestore.c:299 +#, fuzzy +msgid "Failed to read or create private zone key\n" +msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" + +#: src/gns/gnunet-gns-fcfsd.c:757 src/namestore/gnunet-namestore.c:310 +#, fuzzy +msgid "Failed to connect to namestore\n" +msgstr "Fallo al conectarse a gnunetd" + +#: src/gns/gnunet-gns-fcfsd.c:773 src/gns/gnunet-gns-proxy.c:525 +#, fuzzy +msgid "Failed to start HTTP server\n" +msgstr "FallĂł al comenzar la recolecciĂłn.\n" + +#: src/gns/gnunet-gns-fcfsd.c:804 +msgid "GNUnet GNS first come first serve registration service" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:800 +msgid "listen on specified port" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:811 +msgid "GNUnet GNS proxy" +msgstr "" + +#: src/hello/gnunet-hello.c:122 +msgid "Call with name of HELLO file to modify.\n" +msgstr "" + +#: src/hello/gnunet-hello.c:128 +#, fuzzy, c-format +msgid "Error accessing file `%s': %s\n" +msgstr "Error creando usuario" + +#: src/hello/gnunet-hello.c:136 +#, c-format +msgid "File `%s' is too big to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:143 +#, c-format +msgid "File `%s' is too small to be a HELLO\n" msgstr "" +#: src/hello/gnunet-hello.c:153 src/hello/gnunet-hello.c:181 +#, fuzzy, c-format +msgid "Error opening file `%s': %s\n" +msgstr "Error creando usuario" + +#: src/hello/gnunet-hello.c:169 +#, fuzzy, c-format +msgid "Did not find well-formed HELLO in file `%s'\n" +msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" + +#: src/hello/gnunet-hello.c:193 +#, fuzzy, c-format +msgid "Error writing HELLO to file `%s': %s\n" +msgstr "Error creando usuario" + #: src/hostlist/gnunet-daemon-hostlist.c:264 msgid "" "None of the functions for the hostlist daemon were enabled. I have no " @@ -3121,195 +3271,197 @@ msgstr "" msgid "GNUnet hostlist server and client" msgstr "" -#: src/hostlist/hostlist-client.c:286 +#: src/hostlist/hostlist-client.c:289 msgid "# bytes downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:307 src/hostlist/hostlist-client.c:339 +#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:340 #, fuzzy msgid "# invalid HELLOs downloaded from hostlist servers" msgstr "# saludos descargados vĂ­a HTTP" -#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:342 +#: src/hostlist/hostlist-client.c:313 src/hostlist/hostlist-client.c:343 #, fuzzy, c-format msgid "Invalid `%s' message received from hostlist at `%s'\n" msgstr "Mensaje '%s' invĂĄlido recibido del par '%s'.\n" -#: src/hostlist/hostlist-client.c:330 +#: src/hostlist/hostlist-client.c:331 #, fuzzy msgid "# valid HELLOs downloaded from hostlist servers" msgstr "# saludos descargados vĂ­a HTTP" -#: src/hostlist/hostlist-client.c:374 src/hostlist/hostlist-client.c:395 +#: src/hostlist/hostlist-client.c:375 src/hostlist/hostlist-client.c:396 #, c-format msgid "No `%s' specified in `%s' configuration, will not bootstrap.\n" msgstr "" -#: src/hostlist/hostlist-client.c:472 src/hostlist/hostlist-client.c:682 -#: src/hostlist/hostlist-client.c:688 src/hostlist/hostlist-client.c:740 -#: src/hostlist/hostlist-client.c:749 src/hostlist/hostlist-client.c:877 -#: src/hostlist/hostlist-client.c:967 src/hostlist/hostlist-client.c:972 -#: src/transport/plugin_transport_http_client.c:108 -#: src/transport/plugin_transport_http_client.c:123 +#: src/hostlist/hostlist-client.c:473 src/hostlist/hostlist-client.c:683 +#: src/hostlist/hostlist-client.c:689 src/hostlist/hostlist-client.c:741 +#: src/hostlist/hostlist-client.c:750 src/hostlist/hostlist-client.c:871 +#: src/hostlist/hostlist-client.c:961 src/hostlist/hostlist-client.c:966 +#: src/transport/plugin_transport_http_client.c:110 +#: src/transport/plugin_transport_http_client.c:125 #, fuzzy, c-format msgid "%s failed at %s:%d: `%s'\n" msgstr "'%s' fallĂł en %s: %d con error: '%s'.\n" -#: src/hostlist/hostlist-client.c:592 src/hostlist/hostlist-client.c:1342 +#: src/hostlist/hostlist-client.c:593 src/hostlist/hostlist-client.c:1331 msgid "# advertised hostlist URIs" msgstr "" -#: src/hostlist/hostlist-client.c:622 +#: src/hostlist/hostlist-client.c:623 #, c-format msgid "# advertised URI `%s' downloaded" msgstr "" -#: src/hostlist/hostlist-client.c:663 +#: src/hostlist/hostlist-client.c:664 #, c-format msgid "" "Advertised hostlist with URI `%s' could not be downloaded. Advertised URI " "gets dismissed.\n" msgstr "" -#: src/hostlist/hostlist-client.c:805 +#: src/hostlist/hostlist-client.c:802 #, c-format msgid "Timeout trying to download hostlist from `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:822 +#: src/hostlist/hostlist-client.c:816 #, c-format msgid "Download limit of %u bytes exceeded, stopping download\n" msgstr "" -#: src/hostlist/hostlist-client.c:842 +#: src/hostlist/hostlist-client.c:836 #, fuzzy, c-format -msgid "%s failed for `%s' at %s:%d: `%s'\n" -msgstr "'%s' fallĂł en %s: %d con error: '%s'.\n" +msgid "Download of hostlist from `%s' failed: `%s'\n" +msgstr "" +"Subida de '%s' completada, la velocidad media de subida actual es %8.3f " +"kbps.\n" -#: src/hostlist/hostlist-client.c:848 +#: src/hostlist/hostlist-client.c:842 #, fuzzy, c-format msgid "Download of hostlist `%s' completed.\n" msgstr "" "Subida de '%s' completada, la velocidad media de subida actual es %8.3f " "kbps.\n" -#: src/hostlist/hostlist-client.c:856 +#: src/hostlist/hostlist-client.c:850 #, c-format msgid "Adding successfully tested hostlist `%s' datastore.\n" msgstr "" -#: src/hostlist/hostlist-client.c:909 +#: src/hostlist/hostlist-client.c:903 #, c-format msgid "Bootstrapping using hostlist at `%s'.\n" msgstr "" -#: src/hostlist/hostlist-client.c:917 +#: src/hostlist/hostlist-client.c:911 msgid "# hostlist downloads initiated" msgstr "" -#: src/hostlist/hostlist-client.c:1045 src/hostlist/hostlist-client.c:1515 +#: src/hostlist/hostlist-client.c:1037 src/hostlist/hostlist-client.c:1505 msgid "# milliseconds between hostlist downloads" msgstr "" -#: src/hostlist/hostlist-client.c:1054 +#: src/hostlist/hostlist-client.c:1046 #, c-format msgid "Have %u/%u connections. Will consider downloading hostlist in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1092 +#: src/hostlist/hostlist-client.c:1084 msgid "Scheduled saving of hostlists\n" msgstr "" -#: src/hostlist/hostlist-client.c:1096 +#: src/hostlist/hostlist-client.c:1088 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1119 src/hostlist/hostlist-client.c:1135 +#: src/hostlist/hostlist-client.c:1111 src/hostlist/hostlist-client.c:1127 #, fuzzy msgid "# active connections" msgstr "ConfiguraciĂłn de GNUnet" -#: src/hostlist/hostlist-client.c:1253 +#: src/hostlist/hostlist-client.c:1242 #, c-format msgid "Initial time between hostlist downloads is %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1284 +#: src/hostlist/hostlist-client.c:1273 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot load hostlists from file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1290 +#: src/hostlist/hostlist-client.c:1279 #, c-format msgid "Loading saved hostlist entries from file `%s' \n" msgstr "" -#: src/hostlist/hostlist-client.c:1294 +#: src/hostlist/hostlist-client.c:1283 #, c-format msgid "Hostlist file `%s' is not existing\n" msgstr "" -#: src/hostlist/hostlist-client.c:1305 +#: src/hostlist/hostlist-client.c:1294 #, fuzzy, c-format msgid "Could not open file `%s' for reading to load hostlists: %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/hostlist/hostlist-client.c:1338 +#: src/hostlist/hostlist-client.c:1327 #, c-format msgid "%u hostlist URIs loaded from file\n" msgstr "" -#: src/hostlist/hostlist-client.c:1340 +#: src/hostlist/hostlist-client.c:1329 msgid "# hostlist URIs read from file" msgstr "" -#: src/hostlist/hostlist-client.c:1373 +#: src/hostlist/hostlist-client.c:1362 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot save hostlists to file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1387 +#: src/hostlist/hostlist-client.c:1376 #, fuzzy, c-format msgid "Could not open file `%s' for writing to save hostlists: %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/hostlist/hostlist-client.c:1392 +#: src/hostlist/hostlist-client.c:1381 #, c-format msgid "Writing %u hostlist URIs to `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:1416 src/hostlist/hostlist-client.c:1433 +#: src/hostlist/hostlist-client.c:1405 src/hostlist/hostlist-client.c:1422 #, fuzzy, c-format msgid "Error writing hostlist URIs to file `%s'\n" msgstr "Error creando usuario" -#: src/hostlist/hostlist-client.c:1428 +#: src/hostlist/hostlist-client.c:1417 msgid "# hostlist URIs written to file" msgstr "" -#: src/hostlist/hostlist-client.c:1480 +#: src/hostlist/hostlist-client.c:1470 msgid "Learning is enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1483 +#: src/hostlist/hostlist-client.c:1473 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1492 +#: src/hostlist/hostlist-client.c:1482 msgid "Learning is not enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1504 +#: src/hostlist/hostlist-client.c:1494 #, c-format msgid "" "Since learning is not enabled on this peer, hostlist file `%s' was removed\n" msgstr "" -#: src/hostlist/hostlist-client.c:1508 +#: src/hostlist/hostlist-client.c:1498 #, fuzzy, c-format msgid "Hostlist file `%s' could not be removed\n" msgstr "La clave de sesiĂłn del par '%s' no pudo ser verificada.\n" @@ -3323,8 +3475,10 @@ msgstr "# bytes en la base de datos" msgid "expired addresses encountered" msgstr "" -#: src/hostlist/hostlist-server.c:184 -#: src/topology/gnunet-daemon-topology.c:875 +#: src/hostlist/hostlist-server.c:184 src/hostlist/hostlist-server.c:425 +#: src/peerinfo-tool/gnunet-peerinfo.c:403 +#: src/peerinfo-tool/gnunet-peerinfo.c:519 +#: src/topology/gnunet-daemon-topology.c:927 #, fuzzy, c-format msgid "Error in communication with PEERINFO service: %s\n" msgstr "Imprime informaciĂłn de los pares de GNUnet." @@ -3333,189 +3487,406 @@ msgstr "Imprime informaciĂłn de los pares de GNUnet." msgid "HELLOs without addresses encountered (ignored)" msgstr "" -#: src/hostlist/hostlist-server.c:221 +#: src/hostlist/hostlist-server.c:219 msgid "bytes not included in hostlist (size limit)" msgstr "" -#: src/hostlist/hostlist-server.c:269 +#: src/hostlist/hostlist-server.c:263 #, c-format msgid "Refusing `%s' request to hostlist server\n" msgstr "" -#: src/hostlist/hostlist-server.c:272 +#: src/hostlist/hostlist-server.c:266 #, fuzzy msgid "hostlist requests refused (not HTTP GET)" msgstr "# mensajes PONG encriptados recibidos" -#: src/hostlist/hostlist-server.c:280 +#: src/hostlist/hostlist-server.c:273 msgid "Sending 100 CONTINUE reply\n" msgstr "" -#: src/hostlist/hostlist-server.c:287 +#: src/hostlist/hostlist-server.c:279 #, c-format msgid "Refusing `%s' request with %llu bytes of upload data\n" msgstr "" -#: src/hostlist/hostlist-server.c:291 +#: src/hostlist/hostlist-server.c:283 #, fuzzy msgid "hostlist requests refused (upload data)" msgstr "# mensajes PONG encriptados recibidos" -#: src/hostlist/hostlist-server.c:299 +#: src/hostlist/hostlist-server.c:291 msgid "Could not handle hostlist request since I do not have a response yet\n" msgstr "" -#: src/hostlist/hostlist-server.c:302 +#: src/hostlist/hostlist-server.c:294 #, fuzzy msgid "hostlist requests refused (not ready)" msgstr "# mensajes PONG encriptados recibidos" -#: src/hostlist/hostlist-server.c:306 +#: src/hostlist/hostlist-server.c:298 msgid "Received request for our hostlist\n" msgstr "" -#: src/hostlist/hostlist-server.c:307 +#: src/hostlist/hostlist-server.c:299 #, fuzzy msgid "hostlist requests processed" msgstr "# mensajes PONG encriptados recibidos" -#: src/hostlist/hostlist-server.c:350 +#: src/hostlist/hostlist-server.c:341 #, fuzzy msgid "# hostlist advertisements send" msgstr "# Anuncios a extraĂąos mandados" -#: src/hostlist/hostlist-server.c:397 +#: src/hostlist/hostlist-server.c:388 msgid "Advertisement message could not be queued by core\n" msgstr "" -#: src/hostlist/hostlist-server.c:565 +#: src/hostlist/hostlist-server.c:561 #, fuzzy, c-format msgid "Invalid port number %llu. Exiting.\n" msgstr "Argumentos no vĂĄlidos. Saliendo.\n" -#: src/hostlist/hostlist-server.c:574 +#: src/hostlist/hostlist-server.c:570 #, c-format msgid "Hostlist service starts on %s:%llu\n" msgstr "" -#: src/hostlist/hostlist-server.c:588 +#: src/hostlist/hostlist-server.c:584 #, c-format msgid "Address to obtain hostlist: `%s'\n" msgstr "" -#: src/hostlist/hostlist-server.c:626 +#: src/hostlist/hostlist-server.c:624 +#, fuzzy, c-format +msgid "`%s' is not a valid IP address! Ignoring BINDTOIP.\n" +msgstr "'%s' no esta disponible." + +#: src/hostlist/hostlist-server.c:666 #, c-format msgid "Could not start hostlist HTTP server on port %u\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4595 +#: src/integration-tests/connection_watchdog.c:997 +#, fuzzy, c-format +msgid "Transport plugin: `%s' port %llu\n" +msgstr "Probando transporte(s) %s\n" + +#: src/integration-tests/connection_watchdog.c:1030 +#, fuzzy, c-format +msgid "Found %u transport plugins: `%s'\n" +msgstr "Probando transporte(s) %s\n" + +#: src/integration-tests/connection_watchdog.c:1089 +msgid "Send ping messages to test connectivity (default == NO)" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1095 +#: src/template/gnunet-template.c:68 +#, fuzzy +msgid "help text" +msgstr "texto de ayuda para -t" + +#: src/mesh/gnunet-service-mesh.c:4590 #, fuzzy msgid "Wrong CORE service\n" msgstr "Deteniendo cron\n" -#: src/mesh/gnunet-service-mesh.c:4789 +#: src/mesh/gnunet-service-mesh.c:4784 #, fuzzy msgid "Mesh service is lacking key configuration settings. Exiting.\n" msgstr "ConfiguraciĂłn de GNUnet" -#: src/mesh/gnunet-service-mesh.c:4798 +#: src/mesh/gnunet-service-mesh.c:4793 #, fuzzy msgid "Mesh service could not access hostkey. Exiting.\n" msgstr "Imposible acceder a la informaciĂłn del espacio.\n" -#: src/namestore/namestore_api.c:272 src/namestore/namestore_api.c:313 -msgid "Namestore added record successfully" +#: src/mysql/mysql.c:174 +#, c-format +msgid "Trying to use file `%s' for MySQL configuration.\n" +msgstr "Intentando usar el fichero '%s' para la configuraciĂłn de MySQL.\n" + +#: src/mysql/mysql.c:181 +#, fuzzy, c-format +msgid "Could not access file `%s': %s\n" +msgstr "Imposible ejecutar '%s': %s\n" + +#: src/namestore/gnunet-namestore.c:157 +#, fuzzy, c-format +msgid "Adding record failed: %s\n" msgstr "" +"\n" +"Error subiendo el fichero %s\n" -#: src/namestore/namestore_api.c:281 src/namestore/namestore_api.c:322 -msgid "Namestore failed to add record" +#: src/namestore/gnunet-namestore.c:183 +#, fuzzy, c-format +msgid "Deleting record failed: %s\n" msgstr "" +"\n" +"Error subiendo el fichero %s\n" -#: src/nat/gnunet-nat-server.c:289 +#: src/namestore/gnunet-namestore.c:239 #, c-format -msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgid "\tCorrupt or unsupported record of type %u\n" msgstr "" -#: src/nat/gnunet-nat-server.c:328 -msgid "GNUnet NAT traversal test helper daemon" +#: src/namestore/gnunet-namestore.c:276 +#, c-format +msgid "Option `%s' not given, but I need a zone key file!\n" msgstr "" -#: src/nat/nat.c:803 +#: src/namestore/gnunet-namestore.c:281 +#, fuzzy, c-format +msgid "Using default zone file `%s'\n" +msgstr "Iniciada colecciĂłn '%s'.\n" + +#: src/namestore/gnunet-namestore.c:291 #, c-format -msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgid "No options given\n" msgstr "" -#: src/nat/nat.c:852 +#: src/namestore/gnunet-namestore.c:321 #, fuzzy, c-format -msgid "Failed to start %s\n" -msgstr "FallĂł al comenzar la recolecciĂłn.\n" +msgid "Unsupported type `%s'\n" +msgstr "Mensaje no vĂĄlido del tipo %u recibido. Omitiendo.\n" -#: src/nat/nat.c:1121 +#: src/namestore/gnunet-namestore.c:328 src/namestore/gnunet-namestore.c:350 +#: src/namestore/gnunet-namestore.c:374 src/namestore/gnunet-namestore.c:384 +#: src/namestore/gnunet-namestore.c:409 +#, fuzzy, c-format +msgid "Missing option `%s' for operation `%s'\n" +msgstr "Fichero de configuraciĂłn '%s' creado.\n" + +#: src/namestore/gnunet-namestore.c:329 src/namestore/gnunet-namestore.c:351 +msgid "add/del" +msgstr "" + +#: src/namestore/gnunet-namestore.c:341 +#, fuzzy, c-format +msgid "Value `%s' invalid for record type `%s'\n" +msgstr "%s: valor del sĂ­mbolo '%s' no vĂĄlido para %s\n" + +#: src/namestore/gnunet-namestore.c:366 +#, fuzzy, c-format +msgid "Invalid time format `%s'\n" +msgstr "Argumento no vĂĄlido: '%s'\n" + +#: src/namestore/gnunet-namestore.c:375 src/namestore/gnunet-namestore.c:385 +msgid "add" +msgstr "" + +#: src/namestore/gnunet-namestore.c:410 +msgid "del" +msgstr "" + +#: src/namestore/gnunet-namestore.c:462 +msgid "add record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:465 +msgid "delete record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:468 +msgid "display records" +msgstr "" + +#: src/namestore/gnunet-namestore.c:471 +msgid "" +"expiration time for record to use (for adding only), \"never\" is possible" +msgstr "" + +#: src/namestore/gnunet-namestore.c:474 +msgid "name of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:477 +msgid "type of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:480 +msgid "value of the record to add/delete" +msgstr "" + +#: src/namestore/gnunet-namestore.c:483 +msgid "create or list public record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:486 +msgid "create or list non-authority record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:489 +msgid "filename with the zone key" +msgstr "" + +#: src/namestore/gnunet-namestore.c:500 +#, fuzzy +msgid "GNUnet zone manipulation tool" +msgstr "ConfiguraciĂłn de GNUnet" + +#: src/namestore/gnunet-service-namestore.c:143 +#, c-format +msgid "File zone `%s' but corrupt content already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:154 +#, c-format +msgid "File zone `%s' containing this key already exists\n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:160 +#, c-format +msgid "" +"File zone `%s' but different zone key already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:198 +#, fuzzy, c-format +msgid "Stored zonekey for zone `%s' in file `%s'\n" +msgstr "Fichero almacenado en '%s'.\n" + +#: src/namestore/gnunet-service-namestore.c:1909 +#, fuzzy +msgid "No directory to load zonefiles specified in configuration\n" +msgstr "ÂĄNinguna aplicaciĂłn definida en la configuraciĂłn!\n" + +#: src/namestore/gnunet-service-namestore.c:1918 +#, c-format +msgid "Creating directory `%s' for zone files failed!\n" +msgstr "" + +#: src/namestore/namestore_api.c:315 src/namestore/namestore_api.c:353 +msgid "Namestore added record successfully" +msgstr "" + +#: src/namestore/namestore_api.c:323 +msgid "Namestore failed to add record" +msgstr "" + +#: src/namestore/namestore_api.c:361 +msgid "Namestore record already existed" +msgstr "" + +#: src/namestore/namestore_api.c:368 +msgid "Namestore failed to add record\n" +msgstr "" + +#: src/namestore/namestore_api.c:401 +#, fuzzy +msgid "Namestore removed record successfully" +msgstr "Servicio de GNUnet instalado satisfactoriamente.\n" + +#: src/namestore/namestore_api.c:408 +msgid "No records for entry" +msgstr "" + +#: src/namestore/namestore_api.c:415 +#, fuzzy +msgid "Could not find record to remove" +msgstr "Imposible conectar con gnunetd.\n" + +#: src/namestore/namestore_api.c:422 +#, fuzzy +msgid "Failed to create new signature" +msgstr "Imposible crear el espacio '%s' (Âżexiste?).\n" + +#: src/namestore/namestore_api.c:429 +#, fuzzy +msgid "Failed to put new set of records in database" +msgstr "FallĂł al mandar la peticiĂłn HTTP al host '%s': %s\n" + +#: src/nat/gnunet-nat-server.c:279 +#, c-format +msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgstr "" + +#: src/nat/gnunet-nat-server.c:318 +msgid "GNUnet NAT traversal test helper daemon" +msgstr "" + +#: src/nat/nat.c:799 +#, c-format +msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgstr "" + +#: src/nat/nat.c:844 +#, fuzzy, c-format +msgid "Failed to start %s\n" +msgstr "FallĂł al comenzar la recolecciĂłn.\n" + +#: src/nat/nat.c:1111 #, fuzzy, c-format msgid "Malformed %s `%s' given in configuration!\n" msgstr "Imposible guardar la configuraciĂłn" -#: src/nat/nat.c:1187 src/nat/nat.c:1197 +#: src/nat/nat.c:1177 src/nat/nat.c:1187 #, c-format msgid "" "Configuration requires `%s', but binary is not installed properly (SUID bit " "not set). Option disabled.\n" msgstr "" -#: src/nat/nat.c:1329 +#: src/nat/nat.c:1321 msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" msgstr "" -#: src/nat/nat.c:1341 +#: src/nat/nat.c:1332 #, c-format msgid "Running gnunet-helper-nat-client %s %s %u\n" msgstr "" -#: src/nat/nat_test.c:348 +#: src/nat/nat_test.c:341 #, fuzzy msgid "Failed to connect to `gnunet-nat-server'\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/nat/nat_test.c:418 +#: src/nat/nat_test.c:411 #, c-format msgid "Failed to create listen socket bound to `%s' for NAT test: %s\n" msgstr "" -#: src/nse/gnunet-nse-profiler.c:926 +#: src/nse/gnunet-nse-profiler.c:928 #, fuzzy msgid "Measure quality and performance of the NSE service." msgstr "Imposible acceder al servicio" -#: src/nse/gnunet-service-nse.c:936 +#: src/nse/gnunet-service-nse.c:925 #, c-format msgid "Proof of work invalid: %llu!\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1391 src/nse/gnunet-service-nse.c:1410 -#: src/nse/gnunet-service-nse.c:1431 +#: src/nse/gnunet-service-nse.c:1381 src/nse/gnunet-service-nse.c:1400 +#: src/nse/gnunet-service-nse.c:1421 msgid "NSE service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1398 +#: src/nse/gnunet-service-nse.c:1388 #, fuzzy msgid "Invalid work requirement for NSE service. Exiting.\n" msgstr "Argumentos no vĂĄlidos. Saliendo.\n" -#: src/nse/gnunet-service-nse.c:1419 +#: src/nse/gnunet-service-nse.c:1409 #, fuzzy msgid "NSE service could not access hostkey. Exiting.\n" msgstr "Imposible acceder a la informaciĂłn del espacio.\n" -#: src/peerinfo/gnunet-service-peerinfo.c:133 +#: src/peerinfo/gnunet-service-peerinfo.c:134 #, fuzzy, c-format msgid "Removing expired address of transport `%s'\n" msgstr "Transporte(s) disponible(s): %s\n" -#: src/peerinfo/gnunet-service-peerinfo.c:195 +#: src/peerinfo/gnunet-service-peerinfo.c:203 +#, fuzzy, c-format +msgid "Failed to parse HELLO in file `%s'\n" +msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" + +#: src/peerinfo/gnunet-service-peerinfo.c:229 msgid "# peers known" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:239 +#: src/peerinfo/gnunet-service-peerinfo.c:254 #, c-format msgid "" "File `%s' in directory `%s' does not match naming convention. Removed.\n" @@ -3523,68 +3894,164 @@ msgstr "" "El fichero '%s' en el directorio '%s' no sigue la convenciĂłn de nombres. " "Eliminando.\n" -#: src/peerinfo/gnunet-service-peerinfo.c:305 +#: src/peerinfo/gnunet-service-peerinfo.c:353 #, fuzzy, c-format msgid "Still no peers found in `%s'!\n" msgstr "ÂĄImposible descargar adecuadamente el servicio '%s'!\n" -#: src/peerinfo/peerinfo_api.c:279 -#, fuzzy, c-format -msgid "Failed to transmit message to `%s' service.\n" -msgstr "FallĂł al inicializar el servicio '%s'.\n" +#: src/peerinfo/gnunet-service-peerinfo.c:710 +#, c-format +msgid "Importing HELLOs from `%s'\n" +msgstr "" -#: src/peerinfo/peerinfo_api.c:435 +#: src/peerinfo/peerinfo_api.c:238 +msgid "aborted due to explicit disconnect request" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:358 +#, fuzzy +msgid "failed to transmit request (service down?)" +msgstr "FallĂł al mandar la peticiĂłn HTTP al host '%s': %s\n" + +#: src/peerinfo/peerinfo_api.c:505 #, fuzzy msgid "Failed to receive response from `PEERINFO' service." msgstr "FallĂł al recibir la respuesta al mensaje '%s' de gnunetd\n" -#: src/peerinfo/peerinfo_api.c:463 src/peerinfo/peerinfo_api.c:481 +#: src/peerinfo/peerinfo_api.c:531 src/peerinfo/peerinfo_api.c:550 +#: src/peerinfo/peerinfo_api.c:565 src/peerinfo/peerinfo_api.c:576 +#: src/peerinfo/peerinfo_api.c:587 #, fuzzy -msgid "Received invalid message from `PEERINFO' service.\n" +msgid "Received invalid message from `PEERINFO' service." msgstr "Recibido mensaje UDP6 invĂĄlido de %s:%d, omitiendo.\n" -#: src/peerinfo/peerinfo_api.c:523 +#: src/peerinfo/peerinfo_api.c:663 #, fuzzy -msgid "Failed to transmit iteration request to `PEERINFO' service\n" +msgid "Timeout transmitting iteration request to `PEERINFO' service." msgstr "FallĂł al inicializar el servicio '%s'.\n" -#: src/peerinfo/peerinfo_api.c:557 -msgid "Timeout transmitting iteration request to `PEERINFO' service.\n" -msgstr "" - -#: src/peerinfo/peerinfo_api_notify.c:258 +#: src/peerinfo/peerinfo_api_notify.c:256 #, fuzzy, c-format msgid "Could not connect to `%s' service.\n" msgstr "Imposible conectar con gnunetd.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:216 +#: src/peerinfo-tool/gnunet-peerinfo.c:581 +#, fuzzy +msgid "Failed to parse HELLO message: missing expiration time\n" +msgstr "Imposible guardar la configuraciĂłn" + +#: src/peerinfo-tool/gnunet-peerinfo.c:589 +#, fuzzy +msgid "Failed to parse HELLO message: invalid expiration time\n" +msgstr "Imposible guardar la configuraciĂłn" + +#: src/peerinfo-tool/gnunet-peerinfo.c:598 +#, fuzzy +msgid "Failed to parse HELLO message: malformed\n" +msgstr "FallĂł al pasar los datos de la interfaz de '%s' de %s:%d.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:608 +#, fuzzy +msgid "Failed to parse HELLO message: missing transport plugin\n" +msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:625 +#, c-format +msgid "Plugin `%s' not found\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:634 +#, c-format +msgid "Plugin `%s' does not support URIs yet\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:653 +#, fuzzy, c-format +msgid "Failed to parse `%s' as an address for plugin `%s'\n" +msgstr "Fallo al conectar a gnunetd.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:685 +#, fuzzy, c-format +msgid "Failure adding HELLO: %s\n" +msgstr "Fallo en %s:%d.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:833 #, fuzzy, c-format msgid "Could not find option `%s:%s' in configuration.\n" msgstr "ÂĄImposible encontrar el par '%s' en la tabla de enrutado!\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:223 +#: src/peerinfo-tool/gnunet-peerinfo.c:840 #, fuzzy, c-format msgid "Loading hostkey from `%s' failed.\n" msgstr "Analizando saludo de '%s' se produjo un fallo.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:235 +#: src/peerinfo-tool/gnunet-peerinfo.c:875 +#, fuzzy, c-format +msgid "Invalid URI `%s'\n" +msgstr "Argumento no vĂĄlido: '%s'\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:899 #, c-format msgid "I am peer `%s'.\n" msgstr "Yo soy el par '%s'.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:255 +#: src/peerinfo-tool/gnunet-peerinfo.c:936 +msgid "don't resolve host names" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:939 msgid "output only the identity strings" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:258 +#: src/peerinfo-tool/gnunet-peerinfo.c:942 msgid "output our own identity only" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:264 +#: src/peerinfo-tool/gnunet-peerinfo.c:945 +msgid "list all known peers" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:948 +msgid "also output HELLO uri(s)" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:951 +msgid "add given HELLO uri to the database" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:957 #, fuzzy msgid "Print information about peers." msgstr "Imprime informaciĂłn de los pares de GNUnet." +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:105 +#: src/transport/gnunet-service-transport_plugins.c:118 +#, fuzzy, c-format +msgid "Starting transport plugins `%s'\n" +msgstr "Probando transporte(s) %s\n" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:109 +#: src/transport/gnunet-service-transport_plugins.c:122 +#, fuzzy, c-format +msgid "Loading `%s' transport plugin\n" +msgstr "Probando transporte(s) %s\n" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:129 +#: src/transport/gnunet-service-transport_plugins.c:150 +#, fuzzy, c-format +msgid "Failed to load transport plugin for `%s'\n" +msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" + +#: src/postgres/postgres.c:59 +#, fuzzy, c-format +msgid "`%s:%s' failed at %s:%d with error: %s" +msgstr "'%s' fallĂł en %s: %d con el error: %s\n" + +#: src/postgres/postgres.c:148 +#, fuzzy, c-format +msgid "Unable to initialize Postgres: %s" +msgstr "Imposible inicializar SQLite.\n" + #: src/pt/gnunet-daemon-pt.c:264 #, fuzzy msgid "Failed to pack DNS request. Dropping.\n" @@ -3652,50 +4119,65 @@ msgstr "Fallo al conectar a gnunetd.\n" msgid "Daemon to run to perform IP protocol translation to GNUnet" msgstr "" -#: src/statistics/gnunet-service-statistics.c:209 +#: src/statistics/gnunet-service-statistics.c:271 #, fuzzy, c-format msgid "Loading %llu bytes of statistics from `%s'\n" msgstr "Descarga los ficheros de GNUnet" -#: src/statistics/gnunet-service-statistics.c:267 +#: src/statistics/gnunet-service-statistics.c:330 #, fuzzy, c-format msgid "Wrote %llu bytes of statistics to `%s'\n" msgstr "Descarga los ficheros de GNUnet" -#: src/statistics/gnunet-statistics.c:98 +#: src/statistics/gnunet-statistics.c:122 #, fuzzy msgid "Failed to obtain statistics.\n" msgstr "Fallo en las estadĂ­sticas del trĂĄfico.\n" -#: src/statistics/gnunet-statistics.c:164 +#: src/statistics/gnunet-statistics.c:199 +#, c-format +msgid "No subsystem or name given\n" +msgstr "" + +#: src/statistics/gnunet-statistics.c:207 +#, fuzzy, c-format +msgid "Failed to initialize watch routine\n" +msgstr "Imposible inicializar SQLite.\n" + +#: src/statistics/gnunet-statistics.c:227 msgid "limit output to statistics for the given NAME" msgstr "" -#: src/statistics/gnunet-statistics.c:167 +#: src/statistics/gnunet-statistics.c:230 msgid "make the value being set persistent" msgstr "" -#: src/statistics/gnunet-statistics.c:170 +#: src/statistics/gnunet-statistics.c:233 msgid "limit output to the given SUBSYSTEM" msgstr "" -#: src/statistics/gnunet-statistics.c:173 +#: src/statistics/gnunet-statistics.c:236 msgid "just print the statistics value" msgstr "" -#: src/statistics/gnunet-statistics.c:180 +#: src/statistics/gnunet-statistics.c:239 +msgid "watch value continously" +msgstr "" + +#: src/statistics/gnunet-statistics.c:246 msgid "Print statistics about GNUnet operations." msgstr "Imprime estadĂ­sticas acerca de las operaciones de GNUnet." -#: src/statistics/statistics_api.c:390 +#: src/statistics/statistics_api.c:456 #, fuzzy -msgid "Failed to connect to statistics service!\n" -msgstr "Fallo al conectar a gnunetd.\n" +msgid "Could not save some persistent statistics\n" +msgstr "Imposible crear el espacio '%s' (Âżexiste?).\n" -#: src/template/gnunet-template.c:68 -#, fuzzy -msgid "help text" -msgstr "texto de ayuda para -t" +#: src/statistics/statistics_api.c:999 +msgid "" +"Failed to receive acknowledgement from statistics service, some statistics " +"might have been lost!\n" +msgstr "" #: src/testing/gnunet-testing.c:157 #, fuzzy @@ -3744,605 +4226,443 @@ msgstr "ConfiguraciĂłn de GNUnet" msgid "Could not access hostkey.\n" msgstr "Imposible pasar el fichero de configuraciĂłn '%s'.\n" -#: src/testing/testing.c:204 +#: src/testing/testing.c:200 msgid "`scp' does not seem to terminate (timeout copying config).\n" msgstr "" -#: src/testing/testing.c:218 src/testing/testing.c:808 +#: src/testing/testing.c:214 src/testing/testing.c:798 #, fuzzy msgid "`scp' did not complete cleanly.\n" msgstr "'%s' no esta conectado a ningĂşn par.\n" -#: src/testing/testing.c:239 +#: src/testing/testing.c:237 #, fuzzy msgid "Failed to create pipe for `gnunet-peerinfo' process.\n" msgstr "FallĂł al comenzar la recolecciĂłn.\n" -#: src/testing/testing.c:240 +#: src/testing/testing.c:238 #, fuzzy msgid "Failed to create pipe for `ssh' process.\n" msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" -#: src/testing/testing.c:292 +#: src/testing/testing.c:286 #, fuzzy, c-format msgid "Could not start `%s' process to create hostkey.\n" msgstr "Imposible mandar el mensaje a gnunetd\n" -#: src/testing/testing.c:299 +#: src/testing/testing.c:293 #, fuzzy msgid "Failed to start `gnunet-peerinfo' process.\n" msgstr "FallĂł al comenzar la recolecciĂłn.\n" -#: src/testing/testing.c:300 src/testing/testing.c:488 +#: src/testing/testing.c:294 src/testing/testing.c:471 #, fuzzy msgid "Failed to start `ssh' process.\n" msgstr "FallĂł al comenzar la recolecciĂłn.\n" -#: src/testing/testing.c:360 +#: src/testing/testing.c:354 #, fuzzy, c-format msgid "Error reading from gnunet-peerinfo: %s\n" msgstr "Se produjo un error leyendo informaciĂłn de gnunetd.\n" -#: src/testing/testing.c:364 +#: src/testing/testing.c:358 #, fuzzy msgid "Malformed output from gnunet-peerinfo!\n" msgstr "Se produjo un error leyendo informaciĂłn de gnunetd.\n" -#: src/testing/testing.c:374 +#: src/testing/testing.c:368 #, fuzzy msgid "Failed to get hostkey!\n" msgstr "Fallo en las estadĂ­sticas del trĂĄfico.\n" -#: src/testing/testing.c:406 +#: src/testing/testing.c:400 msgid "`Failed while waiting for topology setup!\n" msgstr "" -#: src/testing/testing.c:480 +#: src/testing/testing.c:463 #, fuzzy, c-format msgid "Could not start `%s' process to start GNUnet.\n" msgstr "Imposible crear el espacio '%s' (Âżexiste?).\n" -#: src/testing/testing.c:487 +#: src/testing/testing.c:470 #, fuzzy msgid "Failed to start `gnunet-arm' process.\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/testing/testing.c:509 src/testing/testing.c:612 +#: src/testing/testing.c:493 src/testing/testing.c:600 msgid "`gnunet-arm' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:510 src/testing/testing.c:613 -#: src/testing/testing.c:633 +#: src/testing/testing.c:494 src/testing/testing.c:601 +#: src/testing/testing.c:621 msgid "`ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:582 +#: src/testing/testing.c:570 msgid "Unable to get HELLO for peer!\n" msgstr "" -#: src/testing/testing.c:632 +#: src/testing/testing.c:620 msgid "`gnunet-arm' terminated with non-zero exit status (or timed out)!\n" msgstr "" -#: src/testing/testing.c:653 src/testing/testing.c:685 +#: src/testing/testing.c:643 src/testing/testing.c:675 msgid "either `gnunet-arm' or `ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:668 src/testing/testing.c:723 +#: src/testing/testing.c:658 src/testing/testing.c:713 #, fuzzy msgid "shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n" msgstr "'%s' no esta conectado a ningĂşn par.\n" -#: src/testing/testing.c:796 +#: src/testing/testing.c:786 msgid "`scp' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:966 +#: src/testing/testing.c:948 #, fuzzy, c-format msgid "Starting service %s for peer `%4s'\n" msgstr "Iniciada colecciĂłn '%s'.\n" -#: src/testing/testing.c:1237 src/testing/testing_group.c:6278 +#: src/testing/testing.c:1207 src/testing/testing_group.c:6154 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration directory.\n" msgstr "Imposible acceder a la informaciĂłn del espacio.\n" -#: src/testing/testing.c:1322 src/testing/testing.c:1397 +#: src/testing/testing.c:1292 src/testing/testing.c:1359 #, fuzzy, c-format msgid "Terminating peer `%4s'\n" msgstr "Permiso denegado para '%s' en %s:%d.\n" -#: src/testing/testing.c:1480 +#: src/testing/testing.c:1448 #, fuzzy, c-format msgid "Setting d->dead on peer `%4s'\n" msgstr "Iniciada colecciĂłn '%s'.\n" -#: src/testing/testing.c:1610 +#: src/testing/testing.c:1601 msgid "Peer not yet running, can not change configuration at this point." msgstr "" -#: src/testing/testing.c:1618 +#: src/testing/testing.c:1609 #, fuzzy msgid "Failed to write new configuration to disk." msgstr "Imposible guardar la configuraciĂłn" -#: src/testing/testing.c:1647 +#: src/testing/testing.c:1636 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration file.\n" msgstr "ÂĄImposible encontrar el par '%s' en la tabla de enrutado!\n" -#: src/testing/testing.c:1650 +#: src/testing/testing.c:1639 #, fuzzy msgid "Failed to copy new configuration to remote machine." msgstr "Imposible guardar la configuraciĂłn" -#: src/testing/testing.c:1805 +#: src/testing/testing.c:1794 #, fuzzy msgid "Peers failed to connect" msgstr "Fallo al conectar a gnunetd.\n" -#: src/testing/testing.c:1933 +#: src/testing/testing.c:1922 #, fuzzy msgid "Failed to connect to core service of first peer!\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/testing/testing.c:2156 +#: src/testing/testing.c:2145 msgid "Peers are not fully running yet, can not connect!\n" msgstr "" -#: src/testing/testing_group.c:1910 src/testing/testing_group.c:1922 -#: src/testing/testing_group.c:2023 src/testing/testing_group.c:2082 -#: src/testing/testing_group.c:2171 src/testing/testing_group.c:2191 -#: src/testing/testing_group.c:2328 src/testing/testing_peergroup.c:940 +#: src/testing/testing_group.c:1895 src/testing/testing_group.c:1907 +#: src/testing/testing_group.c:2008 src/testing/testing_group.c:2065 +#: src/testing/testing_group.c:2152 src/testing/testing_group.c:2172 +#: src/testing/testing_group.c:2302 src/testing/testing_peergroup.c:950 #, fuzzy, c-format msgid "Invalid value `%s' for option `%s' in section `%s': expected float\n" msgstr "" "El fichero de configuraciĂłn debe especificar el directorio para almacenar " "los datos FS en la secciĂłn '%s' bajo '%s'.\n" -#: src/testing/testing_group.c:1932 -#, fuzzy, c-format -msgid "Target is %d connections per peer." -msgstr "Se produjo un error estableciendo conexiĂłn con gnunetd.\n" - -#: src/testing/testing_group.c:2179 +#: src/testing/testing_group.c:2160 #, c-format msgid "" "Invalid value `%s' for option `%s' in section `%s': got %f, needed value " "greater than 0\n" msgstr "" -#: src/testing/testing_group.c:2209 src/testing/testing_group.c:2402 -#, c-format -msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n" -msgstr "" - -#: src/testing/testing_group.c:2246 -#, c-format -msgid "natural log of %d is %d, will run %d iterations\n" -msgstr "" - -#: src/testing/testing_group.c:2249 -#, c-format -msgid "Total connections added thus far: %u!\n" -msgstr "" - -#: src/testing/testing_group.c:2290 -#, c-format -msgid "Total connections added for small world: %d!\n" -msgstr "" - -#: src/testing/testing_group.c:2342 -#, c-format -msgid "rand is %f probability is %f\n" -msgstr "" - -#: src/testing/testing_group.c:2919 src/testing/testing_group.c:3118 +#: src/testing/testing_group.c:2877 src/testing/testing_group.c:3063 #, c-format msgid "" "No `%s' specified in peer configuration in section `%s', cannot copy friends " "file!\n" msgstr "" -#: src/testing/testing_group.c:3020 -msgid "Finished copying all friend files!\n" -msgstr "" - -#: src/testing/testing_group.c:3133 -#, fuzzy, c-format -msgid "Copying file with command cp %s %s\n" -msgstr "'%s' fallĂł con el cĂłdigo de error %s: %s" - -#: src/testing/testing_group.c:3156 -#, fuzzy, c-format -msgid "Copying file with command scp %s %s\n" -msgstr "'%s' fallĂł con el cĂłdigo de error %s: %s" - -#: src/testing/testing_group.c:3173 -#, c-format -msgid "Checking copy status of file %d\n" +#: src/testing/testing_group.c:3957 +msgid "Creating no allowed topology (all peers can connect at core level)\n" msgstr "" -#: src/testing/testing_group.c:3191 -#, c-format -msgid "File %d copied\n" +#: src/testing/testing_group.c:5226 +msgid "Unknown topology specification, can't connect peers!\n" msgstr "" -#: src/testing/testing_group.c:3206 +#: src/testing/testing_group.c:5944 src/transport/transport-testing.c:636 #, fuzzy -msgid "Finished copying all blacklist files!\n" +msgid "Could not read hostkeys file!\n" msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" -#: src/testing/testing_group.c:3586 src/testing/testing_group.c:3723 -#: src/testing/testing_group.c:4884 src/testing/testing_group.c:5025 -msgid "Delaying connect, we have too many outstanding connections!\n" +#: src/testing/testing_group.c:6011 +#, fuzzy, c-format +msgid "Could not create configuration for peer number %u on `%s'!\n" +msgstr "Imposible acceder a la informaciĂłn del espacio.\n" + +#: src/testing/testing_new.c:169 +msgid "tmppath cannot be NULL\n" msgstr "" -#: src/testing/testing_group.c:3596 src/testing/testing_group.c:4894 -#: src/testing/testing_group.c:5035 +#: src/testing/testing_new.c:356 #, c-format -msgid "Creating connection, outstanding_connections is %d\n" +msgid "Hostkeys file not found: %s\n" msgstr "" -#: src/testing/testing_group.c:3608 +#: src/testing/testing_new.c:365 #, fuzzy, c-format -msgid "Offering HELLO of peer %s to peer %s\n" -msgstr "Imposible conectar a %u.%u.%u.%u:%u: %s\n" +msgid "Could not open hostkeys file: %s\n" +msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" -#: src/testing/testing_group.c:3734 +#: src/testing/testing_new.c:380 #, c-format -msgid "Creating connection, outstanding_connections is %d (max %d)\n" -msgstr "" - -#: src/testing/testing_group.c:3988 -msgid "Creating clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:3993 -msgid "Creating small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:3998 -msgid "Creating small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4002 -msgid "Creating ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4006 -msgid "Creating 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4010 -msgid "Creating Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4014 -msgid "Creating InterNAT topology\n" -msgstr "" - -#: src/testing/testing_group.c:4018 -msgid "Creating Scale Free topology\n" -msgstr "" - -#: src/testing/testing_group.c:4023 -msgid "Creating straight line topology\n" -msgstr "" - -#: src/testing/testing_group.c:4027 -msgid "Creating topology from file!\n" -msgstr "" - -#: src/testing/testing_group.c:4043 -msgid "Creating no allowed topology (all peers can connect at core level)\n" -msgstr "" - -#: src/testing/testing_group.c:4058 -msgid "Failed during friend file copying!\n" -msgstr "" - -#: src/testing/testing_group.c:4064 -msgid "Friend files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:4081 -msgid "Blacklisting all but clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:4087 -msgid "Blacklisting all but small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4093 -msgid "Blacklisting all but small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4099 -msgid "Blacklisting all but ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4105 -msgid "Blacklisting all but 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4111 -msgid "Blacklisting all but Erdos-Renyi topology\n" +msgid "Incorrect hostkey file format: %s\n" msgstr "" -#: src/testing/testing_group.c:4117 -msgid "Blacklisting all but InterNAT topology\n" -msgstr "" - -#: src/testing/testing_group.c:4152 -msgid "Blacklisting all but Scale Free topology\n" -msgstr "" +#: src/testing/testing_new.c:437 +#, fuzzy, c-format +msgid "Key number %u does not exist\n" +msgstr "nĂşmero de mensajes a usar por iteraciĂłn" -#: src/testing/testing_group.c:4158 -msgid "Blacklisting all but straight line topology\n" -msgstr "" +#: src/testing/testing_new.c:446 +#, fuzzy, c-format +msgid "Error while decoding key %u\n" +msgstr "Error descargando: %s\n" -#: src/testing/testing_group.c:4173 +#: src/testing/testing_new.c:680 #, fuzzy -msgid "Failed during blacklist file copying!\n" -msgstr "FallĂł al pasar los datos de la interfaz de '%s' de %s:%d.\n" - -#: src/testing/testing_group.c:4179 -msgid "Blacklist files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:5263 -msgid "Creating clique CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5270 -msgid "Creating small world (ring) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5277 -msgid "Creating small world (2d-torus) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5283 -msgid "Creating ring CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5290 -msgid "Creating 2d torus CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5297 -msgid "Creating Erdos-Renyi CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5304 -msgid "Creating InterNAT CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5311 -msgid "Creating Scale Free CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5318 -msgid "Creating straight line CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5324 -msgid "Creating no CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5330 -msgid "Unknown topology specification, can't connect peers!\n" -msgstr "" +msgid "Failed to create configuration for peer (not enough free ports?)\n" +msgstr "Imposible acceder a la informaciĂłn del espacio.\n" -#: src/testing/testing_group.c:5340 +#: src/testing/testing_new.c:691 #, c-format -msgid "Connecting random subset (%'.2f percent) of possible peers\n" +msgid "" +"You attempted to create a testbed with more than %u hosts. Please " +"precompute more hostkeys first.\n" msgstr "" -#: src/testing/testing_group.c:5348 -#, c-format -msgid "Connecting a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:704 +#, fuzzy, c-format +msgid "Failed to initialize hostkey for peer %u\n" +msgstr "Imposible inicializar SQLite.\n" -#: src/testing/testing_group.c:5357 -#, c-format -msgid "Using DFS to connect a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:734 +#, fuzzy, c-format +msgid "Failed to write hostkey file for peer %u: %s\n" +msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" -#: src/testing/testing_group.c:5367 -#, c-format -msgid "Finding additional %u closest peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:751 +#, fuzzy, c-format +msgid "Failed to write configuration file `%s' for peer %u: %s\n" +msgstr "Imposible guardar el fichero de configuraciĂłn '%s':" -#: src/testing/testing_group.c:6062 src/transport/transport-testing.c:650 -#, fuzzy -msgid "Could not read hostkeys file!\n" -msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" +#: src/testing/testing_new.c:791 +#, fuzzy, c-format +msgid "Failed to start `%s': %s\n" +msgstr "Fallo al conectar a gnunetd.\n" -#: src/testing/testing_group.c:6131 +#: src/testing/testing_new.c:959 #, fuzzy, c-format -msgid "Could not create configuration for peer number %u on `%s'!\n" -msgstr "Imposible acceder a la informaciĂłn del espacio.\n" +msgid "Failed to load configuration from %s\n" +msgstr "Imposible guardar el fichero de configuraciĂłn '%s':" -#: src/topology/gnunet-daemon-topology.c:244 +#: src/topology/gnunet-daemon-topology.c:259 msgid "# peers blacklisted" msgstr "" -#: src/topology/gnunet-daemon-topology.c:380 +#: src/topology/gnunet-daemon-topology.c:392 #, fuzzy msgid "# connect requests issued to transport" msgstr "# mensajes PONG encriptados recibidos" -#: src/topology/gnunet-daemon-topology.c:675 -#: src/topology/gnunet-daemon-topology.c:761 +#: src/topology/gnunet-daemon-topology.c:730 +#: src/topology/gnunet-daemon-topology.c:815 #, fuzzy msgid "# friends connected" msgstr "# de pares conectados" -#: src/topology/gnunet-daemon-topology.c:950 +#: src/topology/gnunet-daemon-topology.c:996 msgid "Failed to connect to core service, can not manage topology!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:982 +#: src/topology/gnunet-daemon-topology.c:1026 #, c-format msgid "Option `%s' in section `%s' not specified!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:994 +#: src/topology/gnunet-daemon-topology.c:1039 #, fuzzy, c-format msgid "Could not read friends list `%s'\n" msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" -#: src/topology/gnunet-daemon-topology.c:1000 +#: src/topology/gnunet-daemon-topology.c:1045 #, fuzzy, c-format msgid "Friends file `%s' is empty.\n" msgstr "El formato del fichero '%s' no es vĂĄlido.\n" -#: src/topology/gnunet-daemon-topology.c:1009 +#: src/topology/gnunet-daemon-topology.c:1054 #, fuzzy, c-format msgid "Failed to read friends list from `%s': out of memory\n" msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" -#: src/topology/gnunet-daemon-topology.c:1017 +#: src/topology/gnunet-daemon-topology.c:1062 #, c-format msgid "Failed to read friends list from `%s'\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1037 +#: src/topology/gnunet-daemon-topology.c:1082 #, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1050 +#: src/topology/gnunet-daemon-topology.c:1095 #, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1060 +#: src/topology/gnunet-daemon-topology.c:1105 #, fuzzy, c-format msgid "Found friend `%s' in configuration\n" msgstr " gconfig\tConfiguraciĂłn GTK\n" -#: src/topology/gnunet-daemon-topology.c:1066 +#: src/topology/gnunet-daemon-topology.c:1111 #, c-format msgid "Found myself `%s' in friend list (useless, ignored)\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1076 +#: src/topology/gnunet-daemon-topology.c:1121 #, fuzzy msgid "# friends in configuration" msgstr " gconfig\tConfiguraciĂłn GTK\n" -#: src/topology/gnunet-daemon-topology.c:1082 +#: src/topology/gnunet-daemon-topology.c:1127 msgid "" "Fewer friends specified than required by minimum friend count. Will only " "connect to friends.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1089 +#: src/topology/gnunet-daemon-topology.c:1134 msgid "" "More friendly connections required than target total number of connections.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1126 +#: src/topology/gnunet-daemon-topology.c:1169 #, fuzzy msgid "# HELLO messages received" msgstr "# mensajes PONG encriptados recibidos" -#: src/topology/gnunet-daemon-topology.c:1183 +#: src/topology/gnunet-daemon-topology.c:1224 #, fuzzy msgid "# HELLO messages gossipped" msgstr "# mensajes salientes omitidos" -#: src/topology/gnunet-daemon-topology.c:1323 +#: src/topology/gnunet-daemon-topology.c:1363 msgid "GNUnet topology control (maintaining P2P mesh and F2F constraints)" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:247 +#: src/transport/gnunet-service-transport_blacklist.c:246 #, fuzzy, c-format msgid "Could not read blacklist file `%s'\n" msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" -#: src/transport/gnunet-service-transport_blacklist.c:254 +#: src/transport/gnunet-service-transport_blacklist.c:252 #, c-format msgid "Blacklist file `%s' is empty.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:266 +#: src/transport/gnunet-service-transport_blacklist.c:263 #, fuzzy, c-format msgid "Failed to read blacklist from `%s'\n" msgstr "FallĂł al pasar los datos de la interfaz de '%s' de %s:%d.\n" -#: src/transport/gnunet-service-transport_blacklist.c:287 -#: src/transport/gnunet-service-transport_blacklist.c:311 +#: src/transport/gnunet-service-transport_blacklist.c:284 +#: src/transport/gnunet-service-transport_blacklist.c:308 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, giving up!\n" msgstr "" "Error de sintaxis en el fichero de configuraciĂłn '%s' en la linea %d.\n" -#: src/transport/gnunet-service-transport_blacklist.c:298 -#: src/transport/gnunet-service-transport_blacklist.c:336 +#: src/transport/gnunet-service-transport_blacklist.c:295 +#: src/transport/gnunet-service-transport_blacklist.c:331 #, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:350 +#: src/transport/gnunet-service-transport_blacklist.c:345 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n" msgstr "" "Error de sintaxis en el fichero de configuraciĂłn '%s' en la linea %d.\n" -#: src/transport/gnunet-service-transport_blacklist.c:364 +#: src/transport/gnunet-service-transport_blacklist.c:359 #, c-format msgid "Found myself `%s' in blacklist (useless, ignored)\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:523 -#: src/transport/gnunet-service-transport_blacklist.c:764 +#: src/transport/gnunet-service-transport_blacklist.c:514 +#: src/transport/gnunet-service-transport_blacklist.c:747 msgid "# disconnects due to blacklist" msgstr "" -#: src/transport/gnunet-service-transport.c:158 +#: src/transport/gnunet-service-transport.c:163 #, fuzzy msgid "# bytes payload discarded due to not connected peer " msgstr "# Anuncios de los pares recibidos" -#: src/transport/gnunet-service-transport.c:572 +#: src/transport/gnunet-service-transport.c:237 +#, fuzzy +msgid "# bytes total received" +msgstr "# bytes en la base de datos" + +#: src/transport/gnunet-service-transport.c:284 +#, fuzzy +msgid "# bytes payload received" +msgstr "# bytes desencriptados" + +#: src/transport/gnunet-service-transport.c:582 msgid "Transport service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport.c:581 +#: src/transport/gnunet-service-transport.c:591 msgid "Transport service could not access hostkey. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:353 +#: src/transport/gnunet-service-transport_clients.c:352 #, c-format msgid "Dropping message of type %u and size %u, have %u/%u messages pending\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:358 +#: src/transport/gnunet-service-transport_clients.c:357 #, fuzzy msgid "# messages dropped due to slow client" msgstr "# Anuncios de los pares recibidos" -#: src/transport/gnunet-service-transport_clients.c:510 +#: src/transport/gnunet-service-transport_clients.c:503 #, c-format msgid "Rejecting control connection from peer `%s', which is not me!\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:628 -#, fuzzy -msgid "# bytes payload received for other peers" -msgstr "# bytes recibidos por TCP" - -#: src/transport/gnunet-service-transport_clients.c:645 +#: src/transport/gnunet-service-transport_clients.c:631 msgid "# bytes payload dropped (other peer was not connected)" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:696 +#: src/transport/gnunet-service-transport_clients.c:682 #, fuzzy msgid "# REQUEST CONNECT messages received" msgstr "# mensajes PONG encriptados recibidos" @@ -4351,616 +4671,562 @@ msgstr "# mensajes PONG encriptados recibidos" msgid "# refreshed my HELLO" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:482 -msgid "# failed connection attempts due to timeout" -msgstr "" +#: src/transport/gnunet-service-transport_neighbours.c:1032 +#, fuzzy +msgid "# DISCONNECT messages sent" +msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/gnunet-service-transport_neighbours.c:883 +#: src/transport/gnunet-service-transport_neighbours.c:1148 +#: src/transport/gnunet-service-transport_neighbours.c:1482 #, fuzzy -msgid "# peers disconnected due to external request" -msgstr "# Anuncios de los pares recibidos" +msgid "# bytes in message queue for other peers" +msgstr "# bytes de mensajes salientes omitidos" -#: src/transport/gnunet-service-transport_neighbours.c:966 +#: src/transport/gnunet-service-transport_neighbours.c:1153 #, fuzzy -msgid "# fast reconnects failed" -msgstr "# de pares conectados" +msgid "# messages transmitted to other peers" +msgstr "# bytes recibidos por TCP" -#: src/transport/gnunet-service-transport_neighbours.c:1022 +#: src/transport/gnunet-service-transport_neighbours.c:1158 #, fuzzy -msgid "# peers disconnected due to timeout" -msgstr "# de pares conectados" +msgid "# transmission failures for messages to other peers" +msgstr "# bytes de mensajes salientes omitidos" -#: src/transport/gnunet-service-transport_neighbours.c:1047 +#: src/transport/gnunet-service-transport_neighbours.c:1215 +msgid "# messages timed out while in transport queue" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:1254 #, fuzzy msgid "# keepalives sent" msgstr "# claves de la sesiĂłn mandadas" -#: src/transport/gnunet-service-transport_neighbours.c:1088 +#: src/transport/gnunet-service-transport_neighbours.c:1278 #, fuzzy -msgid "# peers disconnected due to global disconnect" -msgstr "# Anuncios de los pares recibidos" +msgid "# KEEPALIVE messages discarded (peer unknown)" +msgstr "# mensajes defragmentados" -#: src/transport/gnunet-service-transport_neighbours.c:1888 -#: src/transport/gnunet-service-transport_neighbours.c:1909 +#: src/transport/gnunet-service-transport_neighbours.c:1286 #, fuzzy -msgid "# messages not sent (no such peer or not connected)" +msgid "# KEEPALIVE messages discarded (no session)" msgstr "# mensajes defragmentados" -#: src/transport/gnunet-service-transport_neighbours.c:1925 +#: src/transport/gnunet-service-transport_neighbours.c:1323 #, fuzzy -msgid "# bytes in message queue for other peers" -msgstr "# bytes de mensajes salientes omitidos" +msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" +msgstr "# mensajes defragmentados" -#: src/transport/gnunet-service-transport_neighbours.c:1977 +#: src/transport/gnunet-service-transport_neighbours.c:1332 +#, fuzzy +msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" +msgstr "# mensajes defragmentados" + +#: src/transport/gnunet-service-transport_neighbours.c:1388 #, fuzzy msgid "# messages discarded due to lack of neighbour record" msgstr "# mensajes defragmentados" -#: src/transport/gnunet-service-transport_neighbours.c:2013 +#: src/transport/gnunet-service-transport_neighbours.c:1422 msgid "# bandwidth quota violations by other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2031 +#: src/transport/gnunet-service-transport_neighbours.c:1438 msgid "# ms throttling suggested" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2060 +#: src/transport/gnunet-service-transport_neighbours.c:2544 #, fuzzy -msgid "# KEEPALIVE messages discarded (not connected)" -msgstr "# mensajes defragmentados" +msgid "# unexpected CONNECT_ACK messages (no peer)" +msgstr "envia COUNT mensajes" -#: src/transport/gnunet-service-transport_neighbours.c:2113 +#: src/transport/gnunet-service-transport_neighbours.c:2559 +#: src/transport/gnunet-service-transport_neighbours.c:2585 #, fuzzy -msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" -msgstr "# mensajes defragmentados" +msgid "# unexpected CONNECT_ACK messages (not ready)" +msgstr "envia COUNT mensajes" -#: src/transport/gnunet-service-transport_neighbours.c:2121 +#: src/transport/gnunet-service-transport_neighbours.c:2598 #, fuzzy -msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" -msgstr "# mensajes defragmentados" +msgid "# unexpected CONNECT_ACK messages (waiting on ATS)" +msgstr "envia COUNT mensajes" + +#: src/transport/gnunet-service-transport_neighbours.c:2627 +#, fuzzy +msgid "# unexpected CONNECT_ACK messages (disconnecting)" +msgstr "envia COUNT mensajes" + +#: src/transport/gnunet-service-transport_neighbours.c:2807 +#, fuzzy +msgid "# unexpected SESSION ACK messages" +msgstr "# de pares conectados" -#: src/transport/gnunet-service-transport_neighbours.c:2187 +#: src/transport/gnunet-service-transport_neighbours.c:2856 msgid "# SET QUOTA messages ignored (no such peer)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2205 +#: src/transport/gnunet-service-transport_neighbours.c:2870 msgid "# disconnects due to quota of 0" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2323 +#: src/transport/gnunet-service-transport_neighbours.c:2901 msgid "# disconnect messages ignored (old format)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2336 +#: src/transport/gnunet-service-transport_neighbours.c:2912 msgid "# disconnect messages ignored (timestamp)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2411 -#, fuzzy -msgid "# unexpected CONNECT_ACK messages (no peer)" -msgstr "envia COUNT mensajes" - -#: src/transport/gnunet-service-transport_neighbours.c:2453 -#, fuzzy -msgid "# unexpected CONNECT_ACK messages" -msgstr "envia COUNT mensajes" - -#: src/transport/gnunet-service-transport_neighbours.c:2544 -#, fuzzy -msgid "# unexpected ACK messages" -msgstr "# de pares conectados" - -#: src/transport/gnunet-service-transport_plugins.c:111 -msgid "Transport service is lacking NEIGHBOUR_LIMIT option.\n" +#: src/transport/gnunet-service-transport_neighbours.c:2943 +msgid "# other peer asked to disconnect from us" msgstr "" -#: src/transport/gnunet-service-transport_plugins.c:118 -#, fuzzy, c-format -msgid "Starting transport plugins `%s'\n" -msgstr "Probando transporte(s) %s\n" - -#: src/transport/gnunet-service-transport_plugins.c:122 -#, fuzzy, c-format -msgid "Loading `%s' transport plugin\n" -msgstr "Probando transporte(s) %s\n" - -#: src/transport/gnunet-service-transport_plugins.c:150 -#, fuzzy, c-format -msgid "Failed to load transport plugin for `%s'\n" -msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" +#: src/transport/gnunet-service-transport_neighbours.c:3020 +#, fuzzy +msgid "# disconnected from peer upon explicit request" +msgstr "# Anuncios de los pares recibidos" -#: src/transport/gnunet-service-transport_validation.c:410 +#: src/transport/gnunet-service-transport_plugins.c:111 +msgid "Transport service is lacking NEIGHBOUR_LIMIT option.\n" +msgstr "" + +#: src/transport/gnunet-service-transport_validation.c:414 msgid "# address records discarded" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:459 +#: src/transport/gnunet-service-transport_validation.c:463 #, c-format msgid "" "Not transmitting `%s' with `%s', message too big (%u bytes!). This should " "not happen.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:508 +#: src/transport/gnunet-service-transport_validation.c:512 #, fuzzy msgid "# PING without HELLO messages sent" msgstr "# mensajes de texto mandados por PING" -#: src/transport/gnunet-service-transport_validation.c:566 +#: src/transport/gnunet-service-transport_validation.c:570 msgid "# address revalidations started" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:798 +#: src/transport/gnunet-service-transport_validation.c:805 #, fuzzy msgid "# PING message for different peer received" msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/gnunet-service-transport_validation.c:833 +#: src/transport/gnunet-service-transport_validation.c:840 #, c-format msgid "" "Not confirming PING with address `%s' since I cannot confirm having this " "address.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:919 +#: src/transport/gnunet-service-transport_validation.c:924 msgid "# PONGs unicast via reliable transport" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:928 +#: src/transport/gnunet-service-transport_validation.c:933 msgid "# PONGs multicast to all available addresses" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1050 +#: src/transport/gnunet-service-transport_validation.c:1055 msgid "# PONGs dropped, no matching pending validation" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1075 +#: src/transport/gnunet-service-transport_validation.c:1080 msgid "# PONGs dropped, signature expired" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1134 +#: src/transport/gnunet-service-transport_validation.c:1136 #, fuzzy, c-format msgid "Adding `%s' without addresses for peer `%s'\n" msgstr "Imposible obtener la direcciĂłn del par '%s'.\n" -#: src/transport/gnunet-transport.c:256 +#: src/transport/gnunet-transport.c:260 msgid "No transport plugins configured, peer will never communicate\n" msgstr "" -#: src/transport/gnunet-transport.c:269 +#: src/transport/gnunet-transport.c:273 #, c-format msgid "No port configured for plugin `%s', cannot test it\n" msgstr "" -#: src/transport/gnunet-transport.c:319 +#: src/transport/gnunet-transport.c:323 #, c-format msgid "Received %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:326 +#: src/transport/gnunet-transport.c:330 #, c-format msgid "Transmitted %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:359 +#: src/transport/gnunet-transport.c:363 #, c-format msgid "Transmitting %u bytes to %s\n" msgstr "" -#: src/transport/gnunet-transport.c:379 +#: src/transport/gnunet-transport.c:383 #, fuzzy, c-format msgid "Connected to %s\n" msgstr "'%s' conectado a '%s'.\n" -#: src/transport/gnunet-transport.c:410 +#: src/transport/gnunet-transport.c:414 #, fuzzy, c-format msgid "Disconnected from %s\n" msgstr "'%s' conectado a '%s'.\n" -#: src/transport/gnunet-transport.c:439 +#: src/transport/gnunet-transport.c:443 #, fuzzy, c-format msgid "Received %u bytes from %s\n" msgstr "GAP recibido contenido no vĂĄlido de '%s'\n" -#: src/transport/gnunet-transport.c:453 +#: src/transport/gnunet-transport.c:466 #, fuzzy, c-format msgid "Peer `%s': %s %s\n" msgstr "Yo soy el par '%s'.\n" -#: src/transport/gnunet-transport.c:483 +#: src/transport/gnunet-transport.c:473 +#, c-format +msgid "Peer `%s': %s \n" +msgstr "" + +#: src/transport/gnunet-transport.c:501 #, fuzzy, c-format msgid "Peer `%s' disconnected\n" msgstr "# de pares conectados" -#: src/transport/gnunet-transport.c:539 +#: src/transport/gnunet-transport.c:569 #, fuzzy, c-format msgid "Failed to parse peer identity `%s'\n" msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" -#: src/transport/gnunet-transport.c:587 +#: src/transport/gnunet-transport.c:618 msgid "measure how fast we are receiving data (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:590 +#: src/transport/gnunet-transport.c:621 #, fuzzy msgid "try to connect to the given peer" msgstr "Fallo al conectar a gnunetd.\n" -#: src/transport/gnunet-transport.c:593 +#: src/transport/gnunet-transport.c:624 #, fuzzy msgid "provide information about all current connections (once)" msgstr "Imprime informaciĂłn de los pares de GNUnet." -#: src/transport/gnunet-transport.c:596 +#: src/transport/gnunet-transport.c:627 #, fuzzy msgid "provide information about all current connections (continuously)" msgstr "Imprime informaciĂłn de los pares de GNUnet." -#: src/transport/gnunet-transport.c:599 +#: src/transport/gnunet-transport.c:630 msgid "do not resolve hostnames" msgstr "" -#: src/transport/gnunet-transport.c:603 +#: src/transport/gnunet-transport.c:634 msgid "send data for benchmarking to the other peer (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:606 +#: src/transport/gnunet-transport.c:637 msgid "test transport configuration (involves external server)" msgstr "" -#: src/transport/gnunet-transport.c:614 +#: src/transport/gnunet-transport.c:645 #, fuzzy msgid "Direct access to transport service." msgstr "Fallo al conectar a gnunetd.\n" -#: src/transport/plugin_transport_http.c:981 +#: src/transport/plugin_transport_http.c:1100 msgid "Disabling IPv6 since it is not supported on this system!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1029 +#: src/transport/plugin_transport_http.c:1149 #, fuzzy msgid "Require valid port number for service in configuration!\n" msgstr "ÂĄNinguna aplicaciĂłn definida en la configuraciĂłn!\n" -#: src/transport/plugin_transport_http.c:1054 src/util/service.c:986 +#: src/transport/plugin_transport_http.c:1174 src/util/service.c:1036 #, fuzzy, c-format msgid "Failed to resolve `%s': %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/transport/plugin_transport_http.c:1071 src/util/service.c:1003 +#: src/transport/plugin_transport_http.c:1191 src/util/service.c:1053 #, fuzzy, c-format msgid "Failed to find %saddress for `%s'.\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/transport/plugin_transport_http.c:1176 +#: src/transport/plugin_transport_http.c:1296 #, c-format msgid "Found %u addresses to report to NAT service\n" msgstr "" -#: src/transport/plugin_transport_http.c:1189 +#: src/transport/plugin_transport_http.c:1309 #, c-format msgid "FREEING %s\n" msgstr "" -#: src/transport/plugin_transport_http.c:1264 +#: src/transport/plugin_transport_http.c:1386 #, fuzzy msgid "Neither IPv4 nor IPv6 are enabled! Fix in configuration\n" msgstr "ÂĄAdvertencias de la red desconectadas por configuraciĂłn!\n" -#: src/transport/plugin_transport_http.c:1277 +#: src/transport/plugin_transport_http.c:1399 #, fuzzy msgid "Port is required! Fix in configuration\n" msgstr " gconfig\tConfiguraciĂłn GTK\n" -#: src/transport/plugin_transport_http.c:1288 +#: src/transport/plugin_transport_http.c:1410 msgid "Port 0, client only mode\n" msgstr "" -#: src/transport/plugin_transport_http.c:1308 +#: src/transport/plugin_transport_http.c:1430 #, c-format msgid "" "Specific IPv4 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1338 +#: src/transport/plugin_transport_http.c:1460 #, c-format msgid "" "Specific IPv6 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http_client.c:621 +#: src/transport/plugin_transport_http_client.c:624 #, c-format msgid "Could not initialize curl multi handle, failed to start %s plugin!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:189 +#: src/transport/plugin_transport_http_server.c:178 msgid "" "Could not create a new TLS certificate, program `gnunet-transport-" "certificate-creation' could not be started!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:213 +#: src/transport/plugin_transport_http_server.c:202 msgid "No usable TLS certificate found and creating one failed!\n" msgstr "" -#: src/transport/plugin_transport_smtp.c:370 -#, fuzzy, c-format -msgid "Received malformed message via %s. Ignored.\n" -msgstr "Recibido el mensaje '%s' con un mal formato. Omitiendo.\n" - -#: src/transport/plugin_transport_smtp.c:457 -msgid "SMTP filter string to invalid, lacks ': '\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:466 -#, c-format -msgid "SMTP filter string to long, capped to `%s'\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:561 -#: src/transport/plugin_transport_smtp.c:571 -#: src/transport/plugin_transport_smtp.c:584 -#: src/transport/plugin_transport_smtp.c:603 -#: src/transport/plugin_transport_smtp.c:626 -#: src/transport/plugin_transport_smtp.c:634 -#: src/transport/plugin_transport_smtp.c:647 -#: src/transport/plugin_transport_smtp.c:658 -#, fuzzy, c-format -msgid "SMTP: `%s' failed: %s.\n" -msgstr "'%s' %s fallĂł: %s\n" - -#: src/transport/plugin_transport_smtp.c:801 -msgid "No email-address specified, can not start SMTP transport.\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:813 -#, fuzzy -msgid "# bytes received via SMTP" -msgstr "# bytes recibidos por TCP" - -#: src/transport/plugin_transport_smtp.c:814 -#, fuzzy -msgid "# bytes sent via SMTP" -msgstr "# bytes enviados por TCP" - -#: src/transport/plugin_transport_smtp.c:816 -#, fuzzy -msgid "# bytes dropped by SMTP (outgoing)" -msgstr "# bytes omitidos por TCP (salientes)" - -#: src/transport/plugin_transport_tcp.c:512 +#: src/transport/plugin_transport_tcp.c:591 #, c-format msgid "Unexpected address length: %u bytes\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:616 -#: src/transport/plugin_transport_tcp.c:705 -#: src/transport/plugin_transport_tcp.c:757 -#: src/transport/plugin_transport_tcp.c:830 -#: src/transport/plugin_transport_tcp.c:909 +#: src/transport/plugin_transport_tcp.c:767 +#: src/transport/plugin_transport_tcp.c:856 +#: src/transport/plugin_transport_tcp.c:906 +#: src/transport/plugin_transport_tcp.c:992 +#: src/transport/plugin_transport_tcp.c:1086 +#: src/transport/plugin_transport_tcp.c:1103 #, fuzzy msgid "# bytes currently in TCP buffers" msgstr "# bytes enviados por TCP" -#: src/transport/plugin_transport_tcp.c:622 -#: src/transport/plugin_transport_tcp.c:856 -#: src/transport/plugin_transport_tcp.c:1561 +#: src/transport/plugin_transport_tcp.c:774 +#: src/transport/plugin_transport_tcp.c:963 +#: src/transport/plugin_transport_tcp.c:1761 +#: src/transport/plugin_transport_tcp.c:2390 #, fuzzy msgid "# TCP sessions active" msgstr "# claves de la sesiĂłn aceptadas" -#: src/transport/plugin_transport_tcp.c:709 +#: src/transport/plugin_transport_tcp.c:860 #, fuzzy msgid "# bytes discarded by TCP (timeout)" msgstr "# bytes omitidos por TCP (salientes)" -#: src/transport/plugin_transport_tcp.c:760 +#: src/transport/plugin_transport_tcp.c:909 #, fuzzy msgid "# bytes transmitted via TCP" msgstr "# bytes desencriptados" -#: src/transport/plugin_transport_tcp.c:834 +#: src/transport/plugin_transport_tcp.c:996 #, fuzzy msgid "# bytes discarded by TCP (disconnect)" msgstr "# bytes omitidos por TCP (salientes)" -#: src/transport/plugin_transport_tcp.c:1081 +#: src/transport/plugin_transport_tcp.c:1290 #, c-format msgid "Address of unexpected length: %u\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1116 -msgid "Found valid IPv4 NAT address (creating session)!\n" -msgstr "" - -#: src/transport/plugin_transport_tcp.c:1186 +#: src/transport/plugin_transport_tcp.c:1401 msgid "# transport-service disconnect requests for TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:1603 +#: src/transport/plugin_transport_tcp.c:1802 #, fuzzy msgid "# TCP WELCOME messages received" msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/plugin_transport_tcp.c:1756 +#: src/transport/plugin_transport_tcp.c:1973 msgid "# bytes received via TCP" msgstr "# bytes recibidos por TCP" -#: src/transport/plugin_transport_tcp.c:1823 +#: src/transport/plugin_transport_tcp.c:2043 msgid "# network-level TCP disconnect events" msgstr "" -#: src/transport/plugin_transport_tcp.c:1962 src/util/service.c:889 +#: src/transport/plugin_transport_tcp.c:2279 src/util/service.c:940 #, c-format msgid "Require valid port number for service `%s' in configuration!\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1976 +#: src/transport/plugin_transport_tcp.c:2293 #, fuzzy msgid "Failed to start service.\n" msgstr "FallĂł al comenzar la recolecciĂłn.\n" -#: src/transport/plugin_transport_tcp.c:2039 +#: src/transport/plugin_transport_tcp.c:2355 #, fuzzy, c-format msgid "Failed to find option %s in section %s!\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/transport/plugin_transport_tcp.c:2062 +#: src/transport/plugin_transport_tcp.c:2378 #, c-format msgid "TCP transport listening on port %llu\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2066 +#: src/transport/plugin_transport_tcp.c:2382 msgid "TCP transport not listening on any port (client only)\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2070 +#: src/transport/plugin_transport_tcp.c:2386 #, c-format msgid "TCP transport advertises itself as being on port %llu\n" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:130 +#: src/transport/plugin_transport_udp_broadcasting.c:128 #, fuzzy msgid "# IPv6 multicast HELLO beacons received via udp" msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/plugin_transport_udp_broadcasting.c:172 +#: src/transport/plugin_transport_udp_broadcasting.c:169 #, fuzzy msgid "# IPv4 broadcast HELLO beacons received via udp" msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/plugin_transport_udp_broadcasting.c:393 +#: src/transport/plugin_transport_udp_broadcasting.c:367 #, c-format msgid "Failed to set IPv4 broadcast option for broadcast socket on port %d\n" msgstr "" -#: src/transport/plugin_transport_udp.c:1985 +#: src/transport/plugin_transport_udp.c:1894 +#, c-format +msgid "" +"UDP could not message to `%s': `%s'. Please check your network configuration " +"and disable IPv6 if your connection does not have a global IPv6 address\n" +msgstr "" + +#: src/transport/plugin_transport_udp.c:2138 #, fuzzy msgid "Failed to open UDP sockets\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/transport/plugin_transport_udp.c:2068 +#: src/transport/plugin_transport_udp.c:2306 #, c-format msgid "Given `%s' option is out of range: %llu > %u\n" msgstr "" -#: src/transport/plugin_transport_udp.c:2112 +#: src/transport/plugin_transport_udp.c:2349 #, fuzzy, c-format msgid "Invalid IPv6 address: `%s'\n" msgstr "Argumento no vĂĄlido: '%s'\n" -#: src/transport/plugin_transport_unix.c:1051 +#: src/transport/plugin_transport_unix.c:1356 #, fuzzy msgid "Failed to open UNIX sockets\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/transport/plugin_transport_wlan.c:875 +#: src/transport/plugin_transport_wlan.c:561 +msgid "# WLAN ACKs sent" +msgstr "" + +#: src/transport/plugin_transport_wlan.c:580 #, fuzzy -msgid "# wlan session timeouts" -msgstr "# claves de la sesiĂłn aceptadas" +msgid "# WLAN messages defragmented" +msgstr "# mensajes defragmentados" -#: src/transport/plugin_transport_wlan.c:899 +#: src/transport/plugin_transport_wlan.c:626 +#: src/transport/plugin_transport_wlan.c:676 +#: src/transport/plugin_transport_wlan.c:1696 #, fuzzy -msgid "# wlan session created" +msgid "# WLAN sessions allocated" msgstr "# claves de la sesiĂłn aceptadas" -#: src/transport/plugin_transport_wlan.c:980 -#: src/transport/plugin_transport_wlan.c:1138 -#: src/transport/plugin_transport_wlan.c:1159 -#: src/transport/plugin_transport_wlan.c:1190 -#: src/transport/plugin_transport_wlan.c:2334 -#: src/transport/plugin_transport_wlan.c:3142 -msgid "# wlan pending sessions" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:1233 -#: src/transport/plugin_transport_wlan.c:1888 +#: src/transport/plugin_transport_wlan.c:749 #, fuzzy -msgid "# wlan pending fragments" -msgstr "# fragmentos descartados" - -#: src/transport/plugin_transport_wlan.c:1388 -#, c-format -msgid "" -"Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n" -msgstr "" +msgid "# WLAN message fragments sent" +msgstr "# mensajes fragmentados" -#: src/transport/plugin_transport_wlan.c:1732 -msgid "# wlan hello beacons send" +#: src/transport/plugin_transport_wlan.c:767 +msgid "# WLAN messages pending (with fragmentation)" msgstr "" -#: src/transport/plugin_transport_wlan.c:1765 -#: src/transport/plugin_transport_wlan.c:1968 -#: src/transport/plugin_transport_wlan.c:2059 -#, c-format -msgid "Error writing to wlan helper. errno == %d, ERROR: %s\n" -msgstr "" +#: src/transport/plugin_transport_wlan.c:867 +#: src/transport/plugin_transport_wlan.c:948 +#: src/transport/plugin_transport_wlan.c:1698 +#, fuzzy +msgid "# WLAN MAC endpoints allocated" +msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/plugin_transport_wlan.c:1954 -msgid "# wlan acks send" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1119 +#, fuzzy +msgid "# HELLO messages received via WLAN" +msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/plugin_transport_wlan.c:2025 +#: src/transport/plugin_transport_wlan.c:1140 #, fuzzy -msgid "# wlan fragments send" +msgid "# fragments received via WLAN" msgstr "# fragmentos descartados" -#: src/transport/plugin_transport_wlan.c:2161 -#, c-format -msgid "Wlan Address len %d is wrong\n" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:2295 -#: src/transport/plugin_transport_wlan.c:2919 -#: src/transport/plugin_transport_wlan.c:3145 -msgid "# wlan mac endpoints" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1150 +#, fuzzy +msgid "# ACKs received via WLAN" +msgstr "# bytes recibidos por TCP" -#: src/transport/plugin_transport_wlan.c:2517 +#: src/transport/plugin_transport_wlan.c:1207 #, fuzzy -msgid "# wlan whole messages received" -msgstr "# mensajes PONG encriptados recibidos" +msgid "# WLAN DATA messages discarded due to CRC32 error" +msgstr "# mensajes defragmentados" -#: src/transport/plugin_transport_wlan.c:2708 +#: src/transport/plugin_transport_wlan.c:1306 #, fuzzy -msgid "# wlan hello messages received" +msgid "# DATA messages received via WLAN" msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/plugin_transport_wlan.c:2742 +#: src/transport/plugin_transport_wlan.c:1341 #, fuzzy -msgid "# wlan fragments received" -msgstr "# fragmentos descartados" +msgid "# WLAN DATA messages processed" +msgstr "# mensajes PONG encriptados recibidos" -#: src/transport/plugin_transport_wlan.c:2790 +#: src/transport/plugin_transport_wlan.c:1402 #, fuzzy -msgid "# wlan acks received" -msgstr "# mensajes PONG encriptados recibidos" +msgid "# HELLO beacons sent via WLAN" +msgstr "# bytes enviados vĂ­a UDP" -#: src/transport/plugin_transport_wlan.c:2879 -msgid "# wlan mac endpoints timeouts" +#: src/transport/plugin_transport_wlan.c:1511 +msgid "WLAN address with invalid size encountered\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:2903 -#, fuzzy -msgid "# wlan mac endpoints created" -msgstr "# mensajes PONG encriptados recibidos" +#: src/transport/plugin_transport_wlan.c:1668 +#, fuzzy, c-format +msgid "Invalid configuration option `%s' in section `%s'\n" +msgstr "Fichero de configuraciĂłn '%s' creado.\n" -#: src/transport/plugin_transport_wlan.c:2956 -msgid "# wlan WLAN_HELPER_DATA received" +#: src/transport/plugin_transport_wlan.c:1677 +#, c-format +msgid "Helper binary `%s' not SUID, cannot run WLAN transport\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:3010 -#, fuzzy -msgid "# wlan messages for this client received" -msgstr "# mensajes PONG encriptados recibidos" - -#: src/transport/plugin_transport_wlan.c:3021 -#, fuzzy -msgid "# wlan messages inside WLAN_HELPER_DATA received" -msgstr "# mensajes PONG encriptados recibidos" +#: src/transport/plugin_transport_wlan.c:1687 +#, fuzzy, c-format +msgid "Missing configuration option `%s' in section `%s'\n" +msgstr "Fichero de configuraciĂłn '%s' creado.\n" -#: src/transport/transport_api.c:588 +#: src/transport/transport_api.c:570 #, fuzzy, c-format msgid "Received unexpected message of type %u in %s:%u\n" msgstr "Recibido mensaje corrupto del par '%s' en %s:%d.\n" @@ -4995,137 +5261,130 @@ msgstr "" msgid "Metadata `%s' failed to deserialize" msgstr "" -#: src/util/client.c:304 +#: src/util/client.c:359 #, c-format msgid "" "Could not determine valid hostname and port for service `%s' from " "configuration.\n" msgstr "" -#: src/util/client.c:312 +#: src/util/client.c:367 #, c-format msgid "Need a non-empty hostname for service `%s'.\n" msgstr "" -#: src/util/client.c:657 +#: src/util/client.c:685 msgid "Failure to transmit TEST request.\n" msgstr "" -#: src/util/client.c:717 src/util/service.c:919 +#: src/util/client.c:740 src/util/service.c:970 #, c-format msgid "UNIXPATH `%s' too long, maximum length is %llu\n" msgstr "" -#: src/util/client.c:859 +#: src/util/client.c:882 #, fuzzy, c-format msgid "Could not connect to service `%s', must not be running.\n" msgstr "Imposible conectar con gnunetd.\n" -#: src/util/client.c:875 +#: src/util/client.c:896 #, fuzzy, c-format msgid "Failure to transmit request to service `%s'\n" msgstr "FallĂł al mandar la peticiĂłn HTTP al host '%s': %s\n" -#: src/util/client.c:1143 +#: src/util/client.c:1149 msgid "Could not submit request, not expecting to receive a response.\n" msgstr "" -#: src/util/common_logging.c:239 src/util/common_logging.c:889 +#: src/util/common_logging.c:239 src/util/common_logging.c:890 msgid "DEBUG" msgstr "DEPURACIÓN" -#: src/util/common_logging.c:241 src/util/common_logging.c:887 +#: src/util/common_logging.c:241 src/util/common_logging.c:888 msgid "INFO" msgstr "INFORMACIÓN" -#: src/util/common_logging.c:243 src/util/common_logging.c:885 +#: src/util/common_logging.c:243 src/util/common_logging.c:886 msgid "WARNING" msgstr "PELIGRO" -#: src/util/common_logging.c:245 src/util/common_logging.c:883 +#: src/util/common_logging.c:245 src/util/common_logging.c:884 msgid "ERROR" msgstr "ERROR" -#: src/util/common_logging.c:247 src/util/common_logging.c:891 +#: src/util/common_logging.c:247 src/util/common_logging.c:892 msgid "NONE" msgstr "" -#: src/util/common_logging.c:609 +#: src/util/common_logging.c:610 #, fuzzy, c-format msgid "Failed to create or access directory for log file `%s'\n" msgstr "Imposible pasar el fichero de configuraciĂłn '%s'.\n" -#: src/util/common_logging.c:724 +#: src/util/common_logging.c:725 #, c-format msgid "Message `%.*s' repeated %u times in the last %s\n" msgstr "" -#: src/util/common_logging.c:892 +#: src/util/common_logging.c:893 msgid "INVALID" msgstr "" -#: src/util/common_logging.c:991 +#: src/util/common_logging.c:992 #, fuzzy msgid "unknown address" msgstr "desconocido" -#: src/util/common_logging.c:1029 +#: src/util/common_logging.c:1030 #, fuzzy msgid "invalid address" msgstr "Argumentos invĂĄlidos: " -#: src/util/configuration.c:245 +#: src/util/configuration.c:244 #, fuzzy, c-format msgid "Syntax error in configuration file `%s' at line %u.\n" msgstr "" "Error de sintaxis en el fichero de configuraciĂłn '%s' en la linea %d.\n" -#: src/util/configuration.c:817 +#: src/util/configuration.c:816 #, c-format msgid "" "Configuration value '%s' for '%s' in section '%s' is not in set of legal " "choices\n" msgstr "" -#: src/util/connection.c:460 +#: src/util/connection.c:420 #, fuzzy, c-format msgid "Access denied to `%s'\n" msgstr "Permiso denegado para '%s' en %s:%d.\n" -#: src/util/connection.c:475 +#: src/util/connection.c:435 #, c-format msgid "Accepting connection from `%s': %p\n" msgstr "" -#: src/util/connection.c:629 +#: src/util/connection.c:550 #, fuzzy, c-format msgid "" "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n" msgstr "Se produjo un error estableciendo conexiĂłn con gnunetd.\n" -#: src/util/connection.c:821 src/util/connection.c:992 +#: src/util/connection.c:739 src/util/connection.c:909 #, fuzzy, c-format msgid "Trying to connect to `%s' (%p)\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/util/connection.c:830 +#: src/util/connection.c:748 #, fuzzy, c-format msgid "Failed to connect to `%s' (%p)\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/util/connection.c:983 +#: src/util/connection.c:900 #, fuzzy, c-format msgid "Attempt to connect to `%s' failed\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/util/connection.c:1465 -#, c-format -msgid "" -"Could not satisfy pending transmission request, socket closed or connect " -"failed (%p).\n" -msgstr "" - -#: src/util/container_bloomfilter.c:507 +#: src/util/container_bloomfilter.c:510 #, c-format msgid "" "Size of file on disk is incorrect for this Bloom filter (want %llu, have " @@ -5143,134 +5402,134 @@ msgid "libgcrypt has not the expected version (version %s is required).\n" msgstr "" "libgcrypt no estĂĄ en la versiĂłn esperada (se necesita la versiĂłn %s).\n" -#: src/util/crypto_rsa.c:618 src/util/crypto_rsa.c:665 +#: src/util/crypto_rsa.c:661 src/util/crypto_rsa.c:708 #, fuzzy, c-format msgid "Could not aquire lock on file `%s': %s...\n" msgstr "Imposible escribir PID al fichero '%s': %s.\n" -#: src/util/crypto_rsa.c:623 +#: src/util/crypto_rsa.c:666 #, fuzzy msgid "Creating a new private key. This may take a while.\n" msgstr "Creando nueva clave local (esto puede llevar un tiempo).\n" -#: src/util/crypto_rsa.c:641 +#: src/util/crypto_rsa.c:684 #, c-format msgid "I am host `%s'. Stored new private key in `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:669 src/util/crypto_rsa.c:705 +#: src/util/crypto_rsa.c:712 src/util/crypto_rsa.c:748 msgid "This may be ok if someone is currently generating a hostkey.\n" msgstr "" -#: src/util/crypto_rsa.c:700 +#: src/util/crypto_rsa.c:743 #, c-format msgid "" "When trying to read hostkey file `%s' I found %u bytes but I need at least " "%u.\n" msgstr "" -#: src/util/crypto_rsa.c:720 +#: src/util/crypto_rsa.c:763 #, fuzzy, c-format msgid "File `%s' does not contain a valid private key. Deleting it.\n" msgstr "El fichero '%s' no contiene un pseudĂłnimo.\n" -#: src/util/crypto_rsa.c:738 +#: src/util/crypto_rsa.c:781 #, fuzzy, c-format msgid "I am host `%s'. Read private key from `%s'.\n" msgstr "Llamada a '%s' con la clave '%s'.\n" -#: src/util/crypto_rsa.c:959 +#: src/util/crypto_rsa.c:1032 #, c-format msgid "RSA signature verification failed at %s:%d: %s\n" msgstr "La verificaciĂłn de la firma RSA fallo en %s: %d: %s\n" -#: src/util/disk.c:479 +#: src/util/disk.c:498 #, fuzzy, c-format msgid "`%s' failed for drive `%S': %u\n" msgstr "'%s' fallĂł para la unidad %s: %u\n" -#: src/util/disk.c:1087 +#: src/util/disk.c:1062 #, fuzzy, c-format msgid "Expected `%s' to be a directory!\n" msgstr "ÂĄ'%s' se esperaba que '%s' fuera un directorio!\n" -#: src/util/disk.c:1441 src/util/service.c:1580 +#: src/util/disk.c:1416 src/util/service.c:1650 #, fuzzy, c-format msgid "Cannot obtain information about user `%s': %s\n" msgstr "Imposible guardar el fichero de configuraciĂłn '%s': %s.\n" -#: src/util/disk.c:1759 +#: src/util/disk.c:1734 #, fuzzy, c-format msgid "No `%s' specified for service `%s' in configuration.\n" msgstr "ÂĄNinguna aplicaciĂłn definida en la configuraciĂłn!\n" -#: src/util/getopt.c:672 +#: src/util/getopt.c:669 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "%s: la opciĂłn '%s' es ambigua\n" -#: src/util/getopt.c:696 +#: src/util/getopt.c:693 #, c-format msgid "%s: option `--%s' does not allow an argument\n" msgstr "%s: la opciĂłn '--%s' no permite un argumento\n" -#: src/util/getopt.c:701 +#: src/util/getopt.c:698 #, c-format msgid "%s: option `%c%s' does not allow an argument\n" msgstr "%s: la opciĂłn '%c%s' no permite un argumento\n" -#: src/util/getopt.c:718 src/util/getopt.c:886 +#: src/util/getopt.c:715 src/util/getopt.c:883 #, c-format msgid "%s: option `%s' requires an argument\n" msgstr "%s: la opciĂłn '%s' requiere un argumento\n" -#: src/util/getopt.c:747 +#: src/util/getopt.c:744 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "%s: opciĂłn no reconocida '--%s'\n" -#: src/util/getopt.c:751 +#: src/util/getopt.c:748 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "%s: opciĂłn no reconocida '%c%s'\n" -#: src/util/getopt.c:776 +#: src/util/getopt.c:773 #, c-format msgid "%s: illegal option -- %c\n" msgstr "%s: opciĂłn ilegal -- %c\n" -#: src/util/getopt.c:778 +#: src/util/getopt.c:775 #, c-format msgid "%s: invalid option -- %c\n" msgstr "%s: opciĂłn no vĂĄlida -- %c\n" -#: src/util/getopt.c:806 src/util/getopt.c:934 +#: src/util/getopt.c:803 src/util/getopt.c:931 #, c-format msgid "%s: option requires an argument -- %c\n" msgstr "%s: la opciĂłn requiere un argumento --%c\n" -#: src/util/getopt.c:854 +#: src/util/getopt.c:851 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "%s: la opciĂłn '-W %s' es ambigua\n" -#: src/util/getopt.c:872 +#: src/util/getopt.c:869 #, c-format msgid "%s: option `-W %s' does not allow an argument\n" msgstr "%s: la opciĂłn '-W %s' no permite un argumento\n" -#: src/util/getopt.c:1038 +#: src/util/getopt.c:1035 #, fuzzy, c-format msgid "Use %s to get a list of options.\n" msgstr "Usar --help para obtener una lista de opciones.\n" -#: src/util/getopt_helpers.c:84 +#: src/util/getopt_helpers.c:86 #, c-format msgid "" "Arguments mandatory for long options are also mandatory for short options.\n" msgstr "" -#: src/util/getopt_helpers.c:255 src/util/getopt_helpers.c:283 +#: src/util/getopt_helpers.c:258 src/util/getopt_helpers.c:286 #, c-format msgid "You must pass a number to the `%s' option.\n" msgstr "Tienes que introducir un nĂşmero en la opciĂłn '%s'.\n" @@ -5283,6 +5542,27 @@ msgstr "" msgid "Use build-in GNUnet stub resolver" msgstr "" +#: src/util/gnunet-rsa.c:64 +#, c-format +msgid "No hostkey file specified on command line\n" +msgstr "" + +#: src/util/gnunet-rsa.c:112 +msgid "print the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:115 +msgid "print the hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:118 +msgid "print the short hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:124 +msgid "Manipulate GNUnet private RSA key files" +msgstr "" + #: src/util/gnunet-service-resolver.c:288 #, fuzzy, c-format msgid "Could not resolve `%s' (%s): %s\n" @@ -5294,42 +5574,37 @@ msgstr "Imposible resolver '%s': %s\n" msgid "Could not find IP of host `%s': %s\n" msgstr "Imposible encontrar la IP del host '%s': %s\n" -#: src/util/gnunet-service-resolver.c:494 -#, c-format -msgid "Resolver asked to look up `%s'.\n" -msgstr "" - -#: src/util/gnunet-service-resolver.c:529 -#, c-format -msgid "Resolver asked to look up IP address `%s'.\n" -msgstr "" - -#: src/util/helper.c:239 +#: src/util/helper.c:244 #, fuzzy, c-format msgid "Error reading from `%s': %s\n" msgstr "Error creando usuario" -#: src/util/helper.c:254 +#: src/util/helper.c:259 #, c-format msgid "Got 0 bytes from helper `%s' (EOF)\n" msgstr "" -#: src/util/helper.c:264 +#: src/util/helper.c:269 #, fuzzy, c-format msgid "Got %u bytes from helper `%s'\n" msgstr "GAP recibido contenido no vĂĄlido de '%s'\n" -#: src/util/helper.c:273 +#: src/util/helper.c:278 #, fuzzy, c-format msgid "Failed to parse inbound message from helper `%s'\n" msgstr "FallĂł al pasar los datos de la interfaz de '%s' de %s:%d.\n" -#: src/util/helper.c:432 +#: src/util/helper.c:310 +#, fuzzy, c-format +msgid "Starting HELPER process `%s'\n" +msgstr "Iniciada colecciĂłn '%s'.\n" + +#: src/util/helper.c:440 #, fuzzy, c-format msgid "Error writing to `%s': %s\n" msgstr "Error creando usuario" -#: src/util/network.c:1196 +#: src/util/network.c:1200 #, c-format msgid "" "Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n" @@ -5357,12 +5632,12 @@ msgstr "'%s' %s fallĂł: %s\n" msgid "stat (%s) failed: %s\n" msgstr "'%s' %s fallĂł: %s\n" -#: src/util/os_priority.c:304 +#: src/util/os_priority.c:305 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for reading: %s\n" msgstr "Fichero almacenado en '%s'.\n" -#: src/util/os_priority.c:305 +#: src/util/os_priority.c:306 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for writing: %s\n" msgstr "Fichero almacenado en '%s'.\n" @@ -5387,12 +5662,12 @@ msgstr "'%s' fallĂł en la biblioteca '%s' en %s:%d con un error: %s\n" msgid "Could not determine plugin installation path.\n" msgstr "Imposible determinar mi direcciĂłn IPv6 pĂşblica.\n" -#: src/util/pseudonym.c:273 +#: src/util/pseudonym.c:276 #, fuzzy, c-format msgid "Failed to parse metadata about pseudonym from file `%s': %s\n" msgstr "FallĂł al pasar los datos de la interfaz de '%s' de %s:%d.\n" -#: src/util/pseudonym.c:338 +#: src/util/pseudonym.c:407 src/util/pseudonym.c:433 #, fuzzy msgid "no-name" msgstr "Mostrar el nombre" @@ -5410,189 +5685,169 @@ msgstr "" "Debes especificar un nĂşmero positivo para '%s' en la configuraciĂłn en la " "secciĂłn '%s'.\n" -#: src/util/resolver_api.c:351 +#: src/util/resolver_api.c:347 #, fuzzy, c-format msgid "Timeout trying to resolve IP address `%s'.\n" msgstr "GNUnet usa ahora la direcciĂłn IP %u.%u.%u.%u.\n" -#: src/util/resolver_api.c:355 +#: src/util/resolver_api.c:351 #, c-format msgid "Timeout trying to resolve hostname `%s'.\n" msgstr "" -#: src/util/resolver_api.c:426 -#, c-format -msgid "Resolver returns `%s' for IP `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:807 -#, c-format -msgid "Resolver returns `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:901 -#, c-format -msgid "Resolving our FQDN `%s'\n" -msgstr "" - -#: src/util/resolver_api.c:906 +#: src/util/resolver_api.c:890 #, fuzzy, c-format msgid "Could not resolve our FQDN : %s\n" msgstr "Imposible resolver '%s': %s\n" -#: src/util/resolver_api.c:938 -#, c-format -msgid "Resolving our hostname `%s'\n" -msgstr "" - -#: src/util/scheduler.c:866 +#: src/util/scheduler.c:786 msgid "Looks like we're busy waiting...\n" msgstr "" -#: src/util/scheduler.c:996 +#: src/util/scheduler.c:916 #, c-format msgid "Attempt to cancel dead task %llu!\n" msgstr "" -#: src/util/server.c:397 +#: src/util/server.c:483 #, fuzzy, c-format msgid "`%s' failed for port %d (%s).\n" msgstr "'%s' fallĂł para la unidad %s: %u\n" -#: src/util/server.c:406 +#: src/util/server.c:492 #, fuzzy, c-format msgid "`%s' failed for port %d (%s): address already in use\n" msgstr "" "'%s' fallĂł para el puerto %d: %s. ÂżEstĂĄ gnunet ejecutandose actualmente?\n" -#: src/util/server.c:411 +#: src/util/server.c:497 #, fuzzy, c-format msgid "`%s' failed for `%s': address already in use\n" msgstr "" "'%s' fallĂł para el puerto %d: %s. ÂżEstĂĄ gnunet ejecutandose actualmente?\n" -#: src/util/server.c:640 +#: src/util/server.c:827 #, c-format msgid "" "Processing code for message of type %u did not call " "GNUNET_SERVER_receive_done after %llums\n" msgstr "" -#: src/util/service.c:117 src/util/service.c:143 src/util/service.c:186 -#: src/util/service.c:207 src/util/service.c:214 +#: src/util/service.c:135 src/util/service.c:161 src/util/service.c:204 +#: src/util/service.c:225 src/util/service.c:232 #, c-format msgid "Invalid format for IP: `%s'\n" msgstr "Formato no vĂĄlido para la IP: '%s'\n" -#: src/util/service.c:170 +#: src/util/service.c:188 #, c-format msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)." msgstr "NotaciĂłn de red no vĂĄlida ('/%d' no es vĂĄlido en IPv4 CIDR)." -#: src/util/service.c:263 +#: src/util/service.c:281 #, c-format msgid "Invalid network notation (does not end with ';': `%s')\n" msgstr "NotaciĂłn de red no vĂĄlida (no termina con ';': '%s')\n" -#: src/util/service.c:296 +#: src/util/service.c:313 #, fuzzy, c-format msgid "Wrong format `%s' for netmask\n" msgstr "Formato '%s' errĂłneo para la mĂĄscara de red: %s\n" -#: src/util/service.c:326 +#: src/util/service.c:343 #, fuzzy, c-format msgid "Wrong format `%s' for network\n" msgstr "Formato '%s' errĂłneo para la red: %s\n" -#: src/util/service.c:668 +#: src/util/service.c:698 #, c-format msgid "Access denied to UID %d / GID %d\n" msgstr "" -#: src/util/service.c:673 +#: src/util/service.c:703 #, fuzzy, c-format msgid "Unknown address family %d\n" msgstr "OperaciĂłn desconocida '%s'\n" -#: src/util/service.c:680 +#: src/util/service.c:710 #, c-format msgid "Access from `%s' denied to service `%s'\n" msgstr "" -#: src/util/service.c:724 +#: src/util/service.c:765 #, c-format msgid "Could not parse IPv4 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:752 +#: src/util/service.c:802 #, c-format msgid "Could not parse IPv6 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:869 +#: src/util/service.c:920 #, c-format msgid "" "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n" msgstr "" -#: src/util/service.c:939 +#: src/util/service.c:990 #, c-format msgid "" "Disabling UNIX domain socket support for service `%s', failed to create UNIX " "domain socket: %s\n" msgstr "" -#: src/util/service.c:956 +#: src/util/service.c:1007 #, c-format msgid "Have neither PORT nor UNIXPATH for service `%s', but one is required\n" msgstr "" -#: src/util/service.c:1191 +#: src/util/service.c:1241 msgid "Could not access a pre-bound socket, will try to bind myself\n" msgstr "" -#: src/util/service.c:1242 src/util/service.c:1260 +#: src/util/service.c:1292 src/util/service.c:1310 #, c-format msgid "Specified value for `%s' of service `%s' is invalid\n" msgstr "" -#: src/util/service.c:1287 +#: src/util/service.c:1337 #, c-format msgid "Could not access pre-bound socket %u, will try to bind myself\n" msgstr "" -#: src/util/service.c:1442 +#: src/util/service.c:1506 #, fuzzy, c-format msgid "Failed to start `%s' at `%s'\n" msgstr "Fallo al conectar a gnunetd.\n" -#: src/util/service.c:1475 +#: src/util/service.c:1539 #, fuzzy, c-format msgid "Service `%s' runs at %s\n" msgstr "Par '%s' con credibilidad %8u y direcciĂłn '%s'\n" -#: src/util/service.c:1521 +#: src/util/service.c:1588 msgid "Service process failed to initialize\n" msgstr "" -#: src/util/service.c:1525 +#: src/util/service.c:1592 msgid "Service process could not initialize server function\n" msgstr "" -#: src/util/service.c:1529 +#: src/util/service.c:1596 msgid "Service process failed to report status\n" msgstr "" -#: src/util/service.c:1581 +#: src/util/service.c:1651 msgid "No such user" msgstr "" -#: src/util/service.c:1594 +#: src/util/service.c:1664 #, c-format msgid "Cannot change user/group to `%s': %s\n" msgstr "Imposible cambiar el usuario/grupo a '%s': %s\n" -#: src/util/service.c:1657 +#: src/util/service.c:1729 msgid "do daemonize (detach from terminal)" msgstr "" @@ -5601,55 +5856,76 @@ msgstr "" msgid "signal (%d, %p) returned %d.\n" msgstr "La llamada a '%s' devuelve %d.\n" -#: src/util/strings.c:143 +#: src/util/strings.c:144 msgid "b" msgstr "b" -#: src/util/strings.c:354 +#: src/util/strings.c:334 #, c-format msgid "Character sets requested were `%s'->`%s'\n" msgstr "" -#: src/util/strings.c:462 +#: src/util/strings.c:481 msgid "Failed to expand `$HOME': environment variable `HOME' not set" msgstr "" -#: src/util/strings.c:554 +#: src/util/strings.c:573 msgid "ms" msgstr "ms" -#: src/util/strings.c:559 +#: src/util/strings.c:578 msgid "eternity" msgstr "" -#: src/util/strings.c:563 +#: src/util/strings.c:582 msgid "s" msgstr "s" -#: src/util/strings.c:567 +#: src/util/strings.c:586 msgid "m" msgstr "m" -#: src/util/strings.c:571 +#: src/util/strings.c:590 msgid "h" msgstr "h" -#: src/util/strings.c:575 +#: src/util/strings.c:594 msgid " days" msgstr " dĂ­as" -#: src/util/strings.c:599 +#: src/util/strings.c:618 msgid "end of time" msgstr "" -#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1065 +#: src/util/strings.c:1012 +msgid "IPv6 address did not start with `['\n" +msgstr "" + +#: src/util/strings.c:1020 +msgid "IPv6 address did contain ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1026 +msgid "IPv6 address did contain ']' before ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1033 +msgid "IPv6 address did contain a valid port number after the last ':'\n" +msgstr "" + +#: src/util/strings.c:1042 +#, fuzzy, c-format +msgid "Invalid IPv6 address `%s': %s\n" +msgstr "Argumento no vĂĄlido: '%s'\n" + +#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1071 #, fuzzy msgid "# Active tunnels" msgstr "ConfiguraciĂłn de GNUnet" #: src/vpn/gnunet-service-vpn.c:608 src/vpn/gnunet-service-vpn.c:645 #, fuzzy -msgid "# Peers connected to mesh tunnels" +msgid "# peers connected to mesh tunnels" msgstr "# de pares conectados" #: src/vpn/gnunet-service-vpn.c:699 @@ -5672,76 +5948,76 @@ msgstr "# mensajes PONG encriptados recibidos" msgid "Failed to setup mesh tunnel!\n" msgstr "Fallo en las estadĂ­sticas del trĂĄfico.\n" -#: src/vpn/gnunet-service-vpn.c:967 +#: src/vpn/gnunet-service-vpn.c:973 #, c-format msgid "Protocol %u not supported, dropping\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1285 +#: src/vpn/gnunet-service-vpn.c:1291 msgid "# ICMPv4 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1306 +#: src/vpn/gnunet-service-vpn.c:1312 msgid "# ICMPv6 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1511 +#: src/vpn/gnunet-service-vpn.c:1517 #, fuzzy msgid "# Packets received from TUN interface" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/vpn/gnunet-service-vpn.c:1549 src/vpn/gnunet-service-vpn.c:1590 +#: src/vpn/gnunet-service-vpn.c:1555 src/vpn/gnunet-service-vpn.c:1596 #, c-format msgid "Packet received for unmapped destination `%s' (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1600 +#: src/vpn/gnunet-service-vpn.c:1606 msgid "Received IPv4 packet with options (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1614 +#: src/vpn/gnunet-service-vpn.c:1620 #, c-format msgid "Received packet of unknown protocol %d from TUN (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1697 +#: src/vpn/gnunet-service-vpn.c:1704 #, fuzzy msgid "# ICMP packets received from mesh" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/vpn/gnunet-service-vpn.c:2038 +#: src/vpn/gnunet-service-vpn.c:2045 #, fuzzy msgid "# UDP packets received from mesh" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/vpn/gnunet-service-vpn.c:2196 +#: src/vpn/gnunet-service-vpn.c:2203 #, fuzzy msgid "# TCP packets received from mesh" msgstr "El mensaje recibido del cliente es invĂĄlido\n" -#: src/vpn/gnunet-service-vpn.c:2347 +#: src/vpn/gnunet-service-vpn.c:2354 msgid "Failed to find unallocated IPv4 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2402 +#: src/vpn/gnunet-service-vpn.c:2409 #, fuzzy msgid "Failed to find unallocated IPv6 address in VPN's range\n" msgstr "ÂĄFallĂł al obtener mi direcciĂłn IPv6 (externa)!\n" -#: src/vpn/gnunet-service-vpn.c:2441 src/vpn/gnunet-service-vpn.c:2624 +#: src/vpn/gnunet-service-vpn.c:2448 src/vpn/gnunet-service-vpn.c:2661 #, fuzzy msgid "# Active destinations" msgstr "ConfiguraciĂłn de GNUnet" -#: src/vpn/gnunet-service-vpn.c:2726 +#: src/vpn/gnunet-service-vpn.c:2734 msgid "Failed to allocate IP address for new destination\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3133 +#: src/vpn/gnunet-service-vpn.c:3141 msgid "IPv6 support disabled as this system does not support IPv6\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3165 +#: src/vpn/gnunet-service-vpn.c:3173 msgid "IPv4 support disabled as this system does not support IPv4\n" msgstr "" @@ -5817,22 +6093,162 @@ msgstr "# bytes recibidos vĂ­a UDP" msgid "Setup tunnels via VPN." msgstr "" -#: src/include/gnunet_common.h:479 src/include/gnunet_common.h:484 -#: src/include/gnunet_common.h:490 +#: src/include/gnunet_common.h:497 src/include/gnunet_common.h:502 +#: src/include/gnunet_common.h:508 #, fuzzy, c-format msgid "Assertion failed at %s:%d.\n" msgstr "La verificaciĂłn de la firma RSA fallo en %s: %d: %s\n" -#: src/include/gnunet_common.h:500 +#: src/include/gnunet_common.h:518 #, fuzzy, c-format msgid "External protocol violation detected at %s:%d.\n" msgstr "La verificaciĂłn de la firma RSA fallo en %s: %d: %s\n" -#: src/include/gnunet_common.h:521 src/include/gnunet_common.h:528 +#: src/include/gnunet_common.h:539 src/include/gnunet_common.h:546 #, fuzzy, c-format msgid "`%s' failed on file `%s' at %s:%d with error: %s\n" msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" +#, fuzzy +#~ msgid "Received malformed message via %s. Ignored.\n" +#~ msgstr "Recibido el mensaje '%s' con un mal formato. Omitiendo.\n" + +#, fuzzy +#~ msgid "SMTP: `%s' failed: %s.\n" +#~ msgstr "'%s' %s fallĂł: %s\n" + +#, fuzzy +#~ msgid "# bytes received via SMTP" +#~ msgstr "# bytes recibidos por TCP" + +#, fuzzy +#~ msgid "# bytes sent via SMTP" +#~ msgstr "# bytes enviados por TCP" + +#, fuzzy +#~ msgid "# bytes dropped by SMTP (outgoing)" +#~ msgstr "# bytes omitidos por TCP (salientes)" + +#, fuzzy +#~ msgid "# Peers connected" +#~ msgstr "# de pares conectados" + +#, fuzzy +#~ msgid "%s failed for `%s' at %s:%d: `%s'\n" +#~ msgstr "'%s' fallĂł en %s: %d con error: '%s'.\n" + +#, fuzzy +#~ msgid "Failed to transmit shutdown ACK.\n" +#~ msgstr "FallĂł al comenzar la recolecciĂłn.\n" + +#, fuzzy +#~ msgid "Unable to initialize Postgres with configuration `%s': %s" +#~ msgstr "Imposible guardar el fichero de configuraciĂłn '%s':" + +#, fuzzy +#~ msgid "Failed to transmit message to `%s' service.\n" +#~ msgstr "FallĂł al inicializar el servicio '%s'.\n" + +#, fuzzy +#~ msgid "Target is %d connections per peer." +#~ msgstr "Se produjo un error estableciendo conexiĂłn con gnunetd.\n" + +#, fuzzy +#~ msgid "Copying file with RENAME (%s,%s)\n" +#~ msgstr "'%s' fallĂł con el cĂłdigo de error %s: %s" + +#, fuzzy +#~ msgid "Copying file with command scp %s %s\n" +#~ msgstr "'%s' fallĂł con el cĂłdigo de error %s: %s" + +#, fuzzy +#~ msgid "Finished copying all blacklist files!\n" +#~ msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" + +#, fuzzy +#~ msgid "Offering HELLO of peer %s to peer %s\n" +#~ msgstr "Imposible conectar a %u.%u.%u.%u:%u: %s\n" + +#, fuzzy +#~ msgid "Failed during blacklist file copying!\n" +#~ msgstr "FallĂł al pasar los datos de la interfaz de '%s' de %s:%d.\n" + +#, fuzzy +#~ msgid "# bytes payload received for other peers" +#~ msgstr "# bytes recibidos por TCP" + +#, fuzzy +#~ msgid "# fast reconnects failed" +#~ msgstr "# de pares conectados" + +#, fuzzy +#~ msgid "# peers disconnected due to timeout" +#~ msgstr "# de pares conectados" + +#, fuzzy +#~ msgid "# peers disconnected due to global disconnect" +#~ msgstr "# Anuncios de los pares recibidos" + +#, fuzzy +#~ msgid "# messages not sent (no such peer or not connected)" +#~ msgstr "# mensajes defragmentados" + +#, fuzzy +#~ msgid "# unexpected CONNECT_ACK messages" +#~ msgstr "envia COUNT mensajes" + +#, fuzzy +#~ msgid "# wlan session timeouts" +#~ msgstr "# claves de la sesiĂłn aceptadas" + +#, fuzzy +#~ msgid "# wlan session created" +#~ msgstr "# claves de la sesiĂłn aceptadas" + +#, fuzzy +#~ msgid "# wlan pending fragments" +#~ msgstr "# fragmentos descartados" + +#, fuzzy +#~ msgid "# wlan fragments send" +#~ msgstr "# fragmentos descartados" + +#, fuzzy +#~ msgid "# wlan whole messages received" +#~ msgstr "# mensajes PONG encriptados recibidos" + +#, fuzzy +#~ msgid "# wlan hello messages received" +#~ msgstr "# mensajes PONG encriptados recibidos" + +#, fuzzy +#~ msgid "# wlan fragments received" +#~ msgstr "# fragmentos descartados" + +#, fuzzy +#~ msgid "# wlan acks received" +#~ msgstr "# mensajes PONG encriptados recibidos" + +#, fuzzy +#~ msgid "# wlan messages for this client received" +#~ msgstr "# mensajes PONG encriptados recibidos" + +#, fuzzy +#~ msgid "# wlan messages inside WLAN_HELPER_DATA received" +#~ msgstr "# mensajes PONG encriptados recibidos" + +#, fuzzy +#~ msgid "Unknown user `%s'\n" +#~ msgstr "OperaciĂłn desconocida '%s'\n" + +#, fuzzy +#~ msgid "Namespace `%s' unknown.\n" +#~ msgstr "El espacio '%s' ha sido valorado con un %d.\n" + +#, fuzzy +#~ msgid "Failed to connect to statistics service!\n" +#~ msgstr "Fallo al conectar a gnunetd.\n" + #, fuzzy #~ msgid "Failed to send to `%s': %s\n" #~ msgstr "Fichero almacenado en '%s'.\n" @@ -5895,10 +6311,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Unable to accept connection for service `%s': %s\n" #~ msgstr "Imposible guardar el fichero de configuraciĂłn '%s':" -#, fuzzy -#~ msgid "Service `%s' started\n" -#~ msgstr "Servicio eliminado.\n" - #, fuzzy #~ msgid "Peer `%s' plugin: `%s' address `%s'\n" #~ msgstr "Par '%s' con credibilidad %8u y direcciĂłn '%s'\n" @@ -5931,14 +6343,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Failed to load dhtlog plugin for `%s'\n" #~ msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" -#, fuzzy -#~ msgid "Failed to get full path for `%s'\n" -#~ msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" - -#, fuzzy -#~ msgid "Failed to create file for dhtlog.\n" -#~ msgstr "Error en el formato del fichero (Âżno es un directorio de GNUnet?)\n" - #, fuzzy #~ msgid "Found peer `%s'\n" #~ msgstr "Yo soy el par '%s'.\n" @@ -5951,10 +6355,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Loading udp transport plugin\n" #~ msgstr "Probando transporte(s) %s\n" -#, fuzzy -#~ msgid "Failed to load transport plugin for udp\n" -#~ msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" - #, fuzzy #~ msgid "# SET QUOTA messages received" #~ msgstr "# mensajes PONG encriptados recibidos" @@ -5999,10 +6399,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Misconfigured address to bind to in configuration!\n" #~ msgstr "ÂĄNinguna aplicaciĂłn definida en la configuraciĂłn!\n" -#, fuzzy -#~ msgid "Loading HTTP transport plugin `%s'\n" -#~ msgstr "Probando transporte(s) %s\n" - #, fuzzy #~ msgid "Failed to load transport plugin for http\n" #~ msgstr "Imposible inicializar la aplicaciĂłn '%s'\n" @@ -6070,9 +6466,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Ok" #~ msgstr "k" -#~ msgid "GNUnet configuration" -#~ msgstr "ConfiguraciĂłn de GNUnet" - #~ msgid "" #~ "Welcome to GNUnet!\n" #~ "\n" @@ -6326,9 +6719,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ "Your configuration changes were NOT saved.\n" #~ msgstr "Fichero de configuraciĂłn '%s' creado.\n" -#~ msgid "GNUnet service installed successfully.\n" -#~ msgstr "Servicio de GNUnet instalado satisfactoriamente.\n" - #~ msgid "This version of Windows doesn't support services.\n" #~ msgstr "Esta versiĂłn de Windows no soporta servicios.\n" @@ -6526,10 +6916,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "`%s' failed with error code %d: %s\n" #~ msgstr "'%s' fallĂł con el cĂłdigo de error %d: %s" -#, fuzzy -#~ msgid "Invalid argument for `%s'.\n" -#~ msgstr "Argumento no vĂĄlido: '%s'\n" - #~ msgid "Availability test failed for `%s' at %s:%d.\n" #~ msgstr "Test de disponibilidad fallido para '%s' en %s:%d.\n" @@ -6746,9 +7132,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Command `%s' requires two arguments (`%s' and `%s').\n" #~ msgstr "El comando '%s' requiere dos argumentos ('%s' y '%s').\n" -#~ msgid "Unsupported command `%s'. Aborting.\n" -#~ msgstr "Comando inesperado '%s'. Abortando.\n" - #, fuzzy #~ msgid "# dht put requests received" #~ msgstr "# bytes recibidos por TCP" @@ -7065,10 +7448,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Downloading %d files from directory `%s'.\n" #~ msgstr "Descarga los ficheros de GNUnet" -#, fuzzy -#~ msgid "Did not find any files in directory `%s'\n" -#~ msgstr "FallĂł al actualizar los datos del mĂłdulo '%s'\n" - #~ msgid "File stored as `%s'.\n" #~ msgstr "Fichero almacenado en '%s'.\n" @@ -7176,10 +7555,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Friend list of %s:%d\n" #~ msgstr "Fallo al conectar a gnunetd.\n" -#, fuzzy -#~ msgid "set number of daemons to start" -#~ msgstr "nĂşmero de mensajes a usar por iteraciĂłn" - #, fuzzy #~ msgid "Waiting for peers to connect" #~ msgstr "Esperando a los pares para conectar (%u ciclos restantes)...\n" @@ -8578,9 +8953,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ "Solo se puede arrancar wizard para configurar gnunetd.\n" #~ "ÂżTe olvidaste de la opciĂłn %s'?\n" -#~ msgid "%s: symbol value `%s' invalid for %s\n" -#~ msgstr "%s: valor del sĂ­mbolo '%s' no vĂĄlido para %s\n" - #~ msgid "Gtk GNUnet Configurator" #~ msgstr "Configurador Gtk de GNUnet" @@ -8752,9 +9124,6 @@ msgstr "'%s' fallĂł en el fichero '%s' en %s: %d con el error: %s\n" #~ msgid "Invalid LOGLEVEL `%s' specified.\n" #~ msgstr "LOGLEVEL invĂĄlido '%s' especificado.\n" -#~ msgid "Failure at %s:%d.\n" -#~ msgstr "Fallo en %s:%d.\n" - #~ msgid "" #~ "Cannot determine port of gnunetd server. Define in configuration file in " #~ "section `%s' under `%s'.\n" diff --git a/po/gnunet.pot b/po/gnunet.pot index 9dcff6a..652e579 100644 --- a/po/gnunet.pot +++ b/po/gnunet.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2012-02-28 18:30+0100\n" +"POT-Creation-Date: 2012-06-05 15:47+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,249 +17,262 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: src/arm/arm_api.c:187 +#: src/arm/arm_api.c:165 msgid "Failed to transmit shutdown request to client.\n" msgstr "" -#: src/arm/arm_api.c:378 +#: src/arm/arm_api.c:349 #, c-format msgid "Configuration failes to specify option `%s' in section `%s'!\n" msgstr "" -#: src/arm/arm_api.c:392 +#: src/arm/arm_api.c:363 #, c-format msgid "Configuration fails to specify option `%s' in section `%s'!\n" msgstr "" -#: src/arm/arm_api.c:467 +#: src/arm/arm_api.c:432 #, c-format msgid "Error receiving response to `%s' request from ARM for service `%s'\n" msgstr "" -#: src/arm/arm_api.c:523 +#: src/arm/arm_api.c:485 #, c-format msgid "Requesting start of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:524 +#: src/arm/arm_api.c:486 #, c-format msgid "Requesting termination of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:546 +#: src/arm/arm_api.c:507 #, c-format msgid "Error while trying to transmit request to start `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:548 +#: src/arm/arm_api.c:508 #, c-format msgid "Error while trying to transmit request to stop `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:581 +#: src/arm/arm_api.c:540 #, c-format msgid "Asked to start service `%s' within %llu ms\n" msgstr "" -#: src/arm/arm_api.c:654 +#: src/arm/arm_api.c:612 #, c-format msgid "Stopping service `%s' within %llu ms\n" msgstr "" -#: src/arm/gnunet-arm.c:149 +#: src/arm/gnunet-arm.c:159 #, c-format msgid "Service `%s' is unknown to ARM.\n" msgstr "" -#: src/arm/gnunet-arm.c:154 +#: src/arm/gnunet-arm.c:164 #, c-format msgid "Service `%s' has been stopped.\n" msgstr "" -#: src/arm/gnunet-arm.c:157 +#: src/arm/gnunet-arm.c:167 #, c-format msgid "Service `%s' was already running.\n" msgstr "" -#: src/arm/gnunet-arm.c:162 +#: src/arm/gnunet-arm.c:172 #, c-format msgid "Service `%s' has been started.\n" msgstr "" -#: src/arm/gnunet-arm.c:165 +#: src/arm/gnunet-arm.c:175 #, c-format msgid "Service `%s' was already being stopped.\n" msgstr "" -#: src/arm/gnunet-arm.c:169 +#: src/arm/gnunet-arm.c:179 #, c-format msgid "Service `%s' was already not running.\n" msgstr "" -#: src/arm/gnunet-arm.c:173 +#: src/arm/gnunet-arm.c:183 msgid "Request ignored as ARM is shutting down.\n" msgstr "" -#: src/arm/gnunet-arm.c:177 +#: src/arm/gnunet-arm.c:187 msgid "Error communicating with ARM service.\n" msgstr "" -#: src/arm/gnunet-arm.c:181 +#: src/arm/gnunet-arm.c:191 msgid "Timeout communicating with ARM service.\n" msgstr "" -#: src/arm/gnunet-arm.c:185 +#: src/arm/gnunet-arm.c:195 msgid "Operation failed.\n" msgstr "" -#: src/arm/gnunet-arm.c:189 +#: src/arm/gnunet-arm.c:199 msgid "Unknown response code from ARM.\n" msgstr "" -#: src/arm/gnunet-arm.c:216 +#: src/arm/gnunet-arm.c:222 +msgid "Error communicating with ARM. ARM not running?\n" +msgstr "" + +#: src/arm/gnunet-arm.c:225 +msgid "Running services:\n" +msgstr "" + +#: src/arm/gnunet-arm.c:249 #, c-format msgid "Fatal configuration error: `%s' option in section `%s' missing.\n" msgstr "" -#: src/arm/gnunet-arm.c:224 src/arm/gnunet-arm.c:324 +#: src/arm/gnunet-arm.c:257 src/arm/gnunet-arm.c:357 src/arm/gnunet-arm.c:373 msgid "Fatal error initializing ARM API.\n" msgstr "" -#: src/arm/gnunet-arm.c:247 +#: src/arm/gnunet-arm.c:280 #, c-format msgid "Failed to remove configuration file %s\n" msgstr "" -#: src/arm/gnunet-arm.c:253 +#: src/arm/gnunet-arm.c:286 #, c-format msgid "Failed to remove servicehome directory %s\n" msgstr "" -#: src/arm/gnunet-arm.c:355 +#: src/arm/gnunet-arm.c:407 msgid "stop all GNUnet services" msgstr "" -#: src/arm/gnunet-arm.c:357 +#: src/arm/gnunet-arm.c:409 msgid "start a particular service" msgstr "" -#: src/arm/gnunet-arm.c:359 +#: src/arm/gnunet-arm.c:411 msgid "stop a particular service" msgstr "" -#: src/arm/gnunet-arm.c:361 +#: src/arm/gnunet-arm.c:413 msgid "start all GNUnet default services" msgstr "" -#: src/arm/gnunet-arm.c:364 +#: src/arm/gnunet-arm.c:416 msgid "stop and start all GNUnet default services" msgstr "" -#: src/arm/gnunet-arm.c:367 +#: src/arm/gnunet-arm.c:419 msgid "delete config file and directory on exit" msgstr "" -#: src/arm/gnunet-arm.c:369 +#: src/arm/gnunet-arm.c:421 msgid "don't print status messages" msgstr "" -#: src/arm/gnunet-arm.c:372 +#: src/arm/gnunet-arm.c:424 msgid "timeout for completing current operation" msgstr "" -#: src/arm/gnunet-arm.c:383 +#: src/arm/gnunet-arm.c:426 +msgid "List currently running services" +msgstr "" + +#: src/arm/gnunet-arm.c:437 msgid "Control services and the Automated Restart Manager (ARM)" msgstr "" -#: src/arm/gnunet-service-arm.c:328 +#: src/arm/gnunet-service-arm.c:332 #, c-format msgid "Failed to start service `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:331 +#: src/arm/gnunet-service-arm.c:335 #, c-format msgid "Starting service `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:357 +#: src/arm/gnunet-service-arm.c:361 msgid "Could not send status result to client\n" msgstr "" -#: src/arm/gnunet-service-arm.c:484 +#: src/arm/gnunet-service-arm.c:393 +msgid "Could not send list result to client\n" +msgstr "" + +#: src/arm/gnunet-service-arm.c:523 #, c-format msgid "Unable to create socket for service `%s': %s\n" msgstr "" -#: src/arm/gnunet-service-arm.c:506 +#: src/arm/gnunet-service-arm.c:545 #, c-format msgid "Unable to bind listening socket for service `%s' to address `%s': %s\n" msgstr "" -#: src/arm/gnunet-service-arm.c:520 +#: src/arm/gnunet-service-arm.c:559 #, c-format msgid "ARM now monitors connections to service `%s' at `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:628 +#: src/arm/gnunet-service-arm.c:667 #, c-format msgid "Preparing to stop `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:782 +#: src/arm/gnunet-service-arm.c:878 #, c-format msgid "Restarting service `%s'.\n" msgstr "" -#: src/arm/gnunet-service-arm.c:877 +#: src/arm/gnunet-service-arm.c:970 msgid "exit" msgstr "" -#: src/arm/gnunet-service-arm.c:882 +#: src/arm/gnunet-service-arm.c:975 msgid "signal" msgstr "" -#: src/arm/gnunet-service-arm.c:887 +#: src/arm/gnunet-service-arm.c:980 msgid "unknown" msgstr "" -#: src/arm/gnunet-service-arm.c:921 +#: src/arm/gnunet-service-arm.c:986 #, c-format -msgid "Service `%s' terminated with status %s/%d, will restart in %llu ms\n" +msgid "Service `%s' took %llu ms to terminate\n" msgstr "" -#: src/arm/gnunet-service-arm.c:967 src/arm/mockup-service.c:41 -msgid "Failed to transmit shutdown ACK.\n" +#: src/arm/gnunet-service-arm.c:1021 +#, c-format +msgid "Service `%s' terminated with status %s/%d, will restart in %llu ms\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1067 +#: src/arm/gnunet-service-arm.c:1127 #, c-format msgid "Configuration file `%s' for service `%s' not valid: %s\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1069 +#: src/arm/gnunet-service-arm.c:1129 msgid "option missing" msgstr "" -#: src/arm/gnunet-service-arm.c:1152 +#: src/arm/gnunet-service-arm.c:1213 #, c-format msgid "Starting default services `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1163 +#: src/arm/gnunet-service-arm.c:1224 #, c-format msgid "Default service `%s' not configured correctly!\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1177 +#: src/arm/gnunet-service-arm.c:1238 msgid "" "No default services configured, GNUnet will not really start right now.\n" msgstr "" -#: src/arm/mockup-service.c:46 -msgid "Transmitting shutdown ACK.\n" -msgstr "" - -#: src/arm/mockup-service.c:69 +#: src/arm/mockup-service.c:44 msgid "Initiating shutdown as requested by client.\n" msgstr "" @@ -316,193 +329,196 @@ msgstr "" msgid "Undefined mandatory parameter: memberCallback\n" msgstr "" -#: src/chat/gnunet-chat.c:92 +#: src/chat/gnunet-chat.c:93 msgid "Joined\n" msgstr "" -#: src/chat/gnunet-chat.c:124 +#: src/chat/gnunet-chat.c:125 src/chat/gnunet-chat.c:133 +#: src/chat/gnunet-chat.c:213 src/chat/gnunet-chat.c:253 +#: src/chat/gnunet-chat.c:329 src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:400 src/chat/gnunet-chat.c:700 msgid "anonymous" msgstr "" -#: src/chat/gnunet-chat.c:130 +#: src/chat/gnunet-chat.c:144 #, c-format msgid "(%s) `%s' said: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:133 src/chat/gnunet-chat.c:136 +#: src/chat/gnunet-chat.c:147 src/chat/gnunet-chat.c:150 #, c-format msgid "(%s) `%s' said to you: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:139 +#: src/chat/gnunet-chat.c:153 #, c-format msgid "(%s) `%s' said for sure: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:142 +#: src/chat/gnunet-chat.c:156 #, c-format msgid "(%s) `%s' said to you for sure: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:145 +#: src/chat/gnunet-chat.c:159 #, c-format msgid "(%s) `%s' was confirmed that you received: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:148 +#: src/chat/gnunet-chat.c:162 #, c-format msgid "(%s) `%s' was confirmed that you and only you received: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:151 +#: src/chat/gnunet-chat.c:165 #, c-format msgid "(%s) `%s' was confirmed that you received from him or her: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:156 +#: src/chat/gnunet-chat.c:170 #, c-format msgid "" "(%s) `%s' was confirmed that you and only you received from him or her: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:159 +#: src/chat/gnunet-chat.c:173 #, c-format msgid "(%s) `%s' said off the record: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:162 +#: src/chat/gnunet-chat.c:176 #, c-format msgid "(%s) <%s> said using an unknown message type: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:193 +#: src/chat/gnunet-chat.c:217 #, c-format msgid "'%s' acknowledged message #%d\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' entered the room\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' left the room\n" msgstr "" -#: src/chat/gnunet-chat.c:284 src/chat/gnunet-chat.c:316 +#: src/chat/gnunet-chat.c:321 src/chat/gnunet-chat.c:363 msgid "Could not change username\n" msgstr "" -#: src/chat/gnunet-chat.c:288 src/chat/gnunet-chat.c:630 +#: src/chat/gnunet-chat.c:334 src/chat/gnunet-chat.c:702 #, c-format msgid "Joining room `%s' as user `%s'...\n" msgstr "" -#: src/chat/gnunet-chat.c:320 +#: src/chat/gnunet-chat.c:373 #, c-format msgid "Changed username to `%s'\n" msgstr "" -#: src/chat/gnunet-chat.c:333 +#: src/chat/gnunet-chat.c:388 #, c-format msgid "Users in room `%s': " msgstr "" -#: src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:434 msgid "Syntax: /msg USERNAME MESSAGE" msgstr "" -#: src/chat/gnunet-chat.c:379 +#: src/chat/gnunet-chat.c:443 #, c-format -msgid "Unknown user `%s'\n" +msgid "Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n" msgstr "" -#: src/chat/gnunet-chat.c:395 +#: src/chat/gnunet-chat.c:460 #, c-format msgid "User `%s' is currently not in the room!\n" msgstr "" -#: src/chat/gnunet-chat.c:448 +#: src/chat/gnunet-chat.c:513 #, c-format msgid "Unknown command `%s'\n" msgstr "" -#: src/chat/gnunet-chat.c:459 +#: src/chat/gnunet-chat.c:524 msgid "" "Use `/join #roomname' to join a chat room. Joining a room will cause you to " "leave the current room" msgstr "" -#: src/chat/gnunet-chat.c:463 +#: src/chat/gnunet-chat.c:528 msgid "" "Use `/nick nickname' to change your nickname. This will cause you to leave " "the current room and immediately rejoin it with the new name." msgstr "" -#: src/chat/gnunet-chat.c:467 +#: src/chat/gnunet-chat.c:532 msgid "" "Use `/msg nickname message' to send a private message to the specified user" msgstr "" -#: src/chat/gnunet-chat.c:470 +#: src/chat/gnunet-chat.c:535 msgid "The `/notice' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:472 +#: src/chat/gnunet-chat.c:537 msgid "The `/query' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:474 +#: src/chat/gnunet-chat.c:539 msgid "Use `/sig message' to send a signed public message" msgstr "" -#: src/chat/gnunet-chat.c:477 +#: src/chat/gnunet-chat.c:542 msgid "Use `/ack message' to require signed acknowledgment of the message" msgstr "" -#: src/chat/gnunet-chat.c:480 +#: src/chat/gnunet-chat.c:545 msgid "Use `/anonymous message' to send a public anonymous message" msgstr "" -#: src/chat/gnunet-chat.c:482 +#: src/chat/gnunet-chat.c:547 msgid "The `/anon' command is an alias for `/anonymous'" msgstr "" -#: src/chat/gnunet-chat.c:484 +#: src/chat/gnunet-chat.c:549 msgid "Use `/quit' to terminate gnunet-chat" msgstr "" -#: src/chat/gnunet-chat.c:486 +#: src/chat/gnunet-chat.c:551 msgid "The `/leave' command is an alias for `/quit'" msgstr "" -#: src/chat/gnunet-chat.c:489 +#: src/chat/gnunet-chat.c:554 msgid "Use `/names' to list all of the current members in the chat room" msgstr "" -#: src/chat/gnunet-chat.c:491 +#: src/chat/gnunet-chat.c:556 msgid "Use `/help command' to get help for a specific command" msgstr "" -#: src/chat/gnunet-chat.c:606 +#: src/chat/gnunet-chat.c:672 msgid "You must specify a nickname\n" msgstr "" -#: src/chat/gnunet-chat.c:622 +#: src/chat/gnunet-chat.c:688 #, c-format msgid "Failed to join room `%s'\n" msgstr "" -#: src/chat/gnunet-chat.c:655 +#: src/chat/gnunet-chat.c:727 msgid "set the nickname to use (required)" msgstr "" -#: src/chat/gnunet-chat.c:658 +#: src/chat/gnunet-chat.c:730 msgid "set the chat room to join" msgstr "" -#: src/chat/gnunet-chat.c:670 +#: src/chat/gnunet-chat.c:742 msgid "Join a chat on GNUnet." msgstr "" @@ -522,165 +538,166 @@ msgstr "" msgid "Failed to queue a leave notification\n" msgstr "" -#: src/core/core_api.c:798 +#: src/core/core_api.c:786 msgid "Client was disconnected from core service, trying to reconnect.\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:77 -#: src/peerinfo-tool/gnunet-peerinfo.c:60 +#: src/core/gnunet-core.c:54 src/peerinfo-tool/gnunet-peerinfo.c:286 #, c-format msgid "Peer `%s'\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:175 -#: src/peerinfo-tool/gnunet-peerinfo.c:194 +#: src/core/gnunet-core.c:72 src/peerinfo-tool/gnunet-peerinfo.c:817 #, c-format msgid "Invalid command line argument `%s'\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:196 -#: src/peerinfo-tool/gnunet-peerinfo.c:252 -msgid "don't resolve host names" -msgstr "" - -#: src/core/gnunet-core-list-connections.c:203 +#: src/core/gnunet-core.c:95 msgid "Print information about connected peers." msgstr "" -#: src/core/gnunet-service-core.c:99 +#: src/core/gnunet-service-core.c:97 #, c-format msgid "Core service of `%4s' ready.\n" msgstr "" -#: src/core/gnunet-service-core_clients.c:360 +#: src/core/gnunet-service-core_clients.c:370 msgid "# send requests dropped (disconnected)" msgstr "" -#: src/core/gnunet-service-core_clients.c:465 +#: src/core/gnunet-service-core_clients.c:475 msgid "# messages discarded (session disconnected)" msgstr "" -#: src/core/gnunet-service-core_clients.c:801 +#: src/core/gnunet-service-core_clients.c:818 #, c-format msgid "# bytes of messages of type %u received" msgstr "" -#: src/core/gnunet-service-core_kx.c:493 +#: src/core/gnunet-service-core_kx.c:565 msgid "# bytes encrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:543 +#: src/core/gnunet-service-core_kx.c:617 msgid "# bytes decrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:604 src/dv/gnunet-service-dv.c:3002 -#: src/hostlist/hostlist-server.c:436 src/peerinfo-tool/gnunet-peerinfo.c:151 +#: src/core/gnunet-service-core_kx.c:681 src/dv/gnunet-service-dv.c:3003 msgid "Error in communication with PEERINFO service\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:623 +#: src/core/gnunet-service-core_kx.c:700 msgid "# Delayed connecting due to lack of public key" msgstr "" -#: src/core/gnunet-service-core_kx.c:673 +#: src/core/gnunet-service-core_kx.c:753 msgid "# key exchanges initiated" msgstr "" -#: src/core/gnunet-service-core_kx.c:694 +#: src/core/gnunet-service-core_kx.c:775 msgid "# key exchanges stopped" msgstr "" -#: src/core/gnunet-service-core_kx.c:746 +#: src/core/gnunet-service-core_kx.c:828 msgid "# session keys received" msgstr "" -#: src/core/gnunet-service-core_kx.c:765 +#: src/core/gnunet-service-core_kx.c:845 #, c-format msgid "`%s' is for `%s', not for me. Ignoring.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:803 +#: src/core/gnunet-service-core_kx.c:890 msgid "# SET_KEY messages decrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:883 -#: src/transport/gnunet-service-transport_validation.c:803 +#: src/core/gnunet-service-core_kx.c:977 +#: src/transport/gnunet-service-transport_validation.c:810 msgid "# PING messages received" msgstr "" -#: src/core/gnunet-service-core_kx.c:917 +#: src/core/gnunet-service-core_kx.c:1010 #, c-format msgid "" "Received PING from `%s' for different identity: I am `%s', PONG identity: `" "%s'\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:938 +#: src/core/gnunet-service-core_kx.c:1029 msgid "# PONG messages created" msgstr "" -#: src/core/gnunet-service-core_kx.c:1026 +#: src/core/gnunet-service-core_kx.c:1125 msgid "# sessions terminated by timeout" msgstr "" -#: src/core/gnunet-service-core_kx.c:1037 +#: src/core/gnunet-service-core_kx.c:1135 msgid "# keepalive messages sent" msgstr "" -#: src/core/gnunet-service-core_kx.c:1095 -#: src/transport/gnunet-service-transport_validation.c:1026 +#: src/core/gnunet-service-core_kx.c:1236 +#: src/transport/gnunet-service-transport_validation.c:1031 msgid "# PONG messages received" msgstr "" -#: src/core/gnunet-service-core_kx.c:1125 +#: src/core/gnunet-service-core_kx.c:1275 msgid "# PONG messages decrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:1157 +#: src/core/gnunet-service-core_kx.c:1303 msgid "# session keys confirmed via PONG" msgstr "" -#: src/core/gnunet-service-core_kx.c:1223 +#: src/core/gnunet-service-core_kx.c:1329 +msgid "# rekey operations confirmed via PONG" +msgstr "" + +#: src/core/gnunet-service-core_kx.c:1381 +#: src/core/gnunet-service-core_kx.c:1398 msgid "# SET_KEY and PING messages created" msgstr "" -#: src/core/gnunet-service-core_kx.c:1364 +#: src/core/gnunet-service-core_kx.c:1402 +msgid "# REKEY operations performed" +msgstr "" + +#: src/core/gnunet-service-core_kx.c:1537 msgid "# failed to decrypt message (no session key)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1406 -#: src/core/gnunet-service-core_kx.c:1431 +#: src/core/gnunet-service-core_kx.c:1577 +#: src/core/gnunet-service-core_kx.c:1602 msgid "# bytes dropped (duplicates)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1418 +#: src/core/gnunet-service-core_kx.c:1589 msgid "# bytes dropped (out of sequence)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1455 +#: src/core/gnunet-service-core_kx.c:1626 #, c-format msgid "Message received far too old (%llu ms). Content ignored.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1459 +#: src/core/gnunet-service-core_kx.c:1630 msgid "# bytes dropped (ancient message)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1467 +#: src/core/gnunet-service-core_kx.c:1638 msgid "# bytes of payload decrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:1528 +#: src/core/gnunet-service-core_kx.c:1700 msgid "Core service is lacking HOSTKEY configuration setting. Exiting.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1536 +#: src/core/gnunet-service-core_kx.c:1708 msgid "Core service could not access hostkey. Exiting.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1546 src/hostlist/hostlist-server.c:555 -#: src/peerinfo-tool/gnunet-peerinfo.c:202 -#: src/transport/gnunet-service-transport.c:595 +#: src/core/gnunet-service-core_kx.c:1718 src/hostlist/hostlist-server.c:551 +#: src/peerinfo-tool/gnunet-peerinfo.c:823 +#: src/transport/gnunet-service-transport.c:611 msgid "Could not access PEERINFO service. Exiting.\n" msgstr "" @@ -689,29 +706,39 @@ msgid "# sessions terminated by transport disconnect" msgstr "" #: src/core/gnunet-service-core_neighbours.c:180 -#: src/core/gnunet-service-core_neighbours.c:342 +#: src/core/gnunet-service-core_neighbours.c:334 msgid "# neighbour entries allocated" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:251 +#: src/core/gnunet-service-core_neighbours.c:247 msgid "# encrypted bytes given to transport" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:430 +#: src/core/gnunet-service-core_neighbours.c:418 #, c-format msgid "Unsupported message of type %u (%u bytes) received from peer `%s'\n" msgstr "" -#: src/core/gnunet-service-core_sessions.c:208 -#: src/core/gnunet-service-core_sessions.c:273 -msgid "# entries in session map" +#: src/core/gnunet-service-core_sessions.c:206 +#: src/core/gnunet-service-core_sessions.c:269 +#: src/dht/gnunet-service-dht_neighbours.c:625 +#: src/dht/gnunet-service-dht_neighbours.c:683 +#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 +#: src/topology/gnunet-daemon-topology.c:709 +#: src/topology/gnunet-daemon-topology.c:810 +#: src/transport/gnunet-service-transport_neighbours.c:874 +#: src/transport/gnunet-service-transport_neighbours.c:1080 +#: src/transport/gnunet-service-transport_neighbours.c:1089 +#: src/transport/gnunet-service-transport_neighbours.c:2568 +#: src/transport/gnunet-service-transport_neighbours.c:2814 +msgid "# peers connected" msgstr "" -#: src/core/gnunet-service-core_sessions.c:238 +#: src/core/gnunet-service-core_sessions.c:236 msgid "# type map refreshes sent" msgstr "" -#: src/core/gnunet-service-core_sessions.c:414 +#: src/core/gnunet-service-core_sessions.c:406 msgid "# messages discarded (expired prior to transmission)" msgstr "" @@ -724,398 +751,374 @@ msgstr "" msgid "# updates to my type map" msgstr "" -#: src/datacache/datacache.c:118 src/datacache/datacache.c:255 -#: src/datastore/gnunet-service-datastore.c:854 +#: src/datacache/datacache.c:115 src/datacache/datacache.c:250 +#: src/datastore/gnunet-service-datastore.c:834 msgid "# bytes stored" msgstr "" -#: src/datacache/datacache.c:144 src/datacache/datacache.c:151 -#: src/datastore/gnunet-service-datastore.c:1531 -#: src/datastore/gnunet-service-datastore.c:1542 +#: src/datacache/datacache.c:141 src/datacache/datacache.c:148 +#: src/datastore/gnunet-service-datastore.c:1483 +#: src/datastore/gnunet-service-datastore.c:1494 #, c-format msgid "No `%s' specified for `%s' in configuration!\n" msgstr "" -#: src/datacache/datacache.c:183 +#: src/datacache/datacache.c:180 #, c-format msgid "Loading `%s' datacache plugin\n" msgstr "" -#: src/datacache/datacache.c:191 +#: src/datacache/datacache.c:188 #, c-format msgid "Failed to load datacache plugin for `%s'\n" msgstr "" -#: src/datacache/datacache.c:281 +#: src/datacache/datacache.c:276 msgid "# requests received" msgstr "" -#: src/datacache/datacache.c:291 +#: src/datacache/datacache.c:284 msgid "# requests filtered by bloom filter" msgstr "" -#: src/datacache/plugin_datacache_mysql.c:103 -#: src/datacache/plugin_datacache_mysql.c:110 -#: src/datacache/plugin_datacache_mysql.c:517 -#: src/datacache/plugin_datacache_mysql.c:526 -#: src/datacache/plugin_datacache_mysql.c:598 -#: src/datacache/plugin_datacache_mysql.c:614 -#: src/datacache/plugin_datacache_sqlite.c:71 -#: src/datacache/plugin_datacache_sqlite.c:74 -#: src/datastore/plugin_datastore_mysql.c:139 -#: src/datastore/plugin_datastore_mysql.c:146 -#: src/datastore/plugin_datastore_mysql.c:613 -#: src/datastore/plugin_datastore_mysql.c:673 -#: src/datastore/plugin_datastore_mysql.c:685 -#: src/datastore/plugin_datastore_mysql.c:1362 -#: src/datastore/plugin_datastore_mysql.c:1376 -#: src/datastore/plugin_datastore_sqlite.c:61 -#: src/namestore/plugin_namestore_sqlite.c:49 src/util/crypto_ksk.c:49 -#: src/util/crypto_rsa.c:92 src/include/gnunet_common.h:507 -#: src/include/gnunet_common.h:514 +#: src/datacache/plugin_datacache_mysql.c:97 +#: src/datacache/plugin_datacache_mysql.c:104 +#: src/datacache/plugin_datacache_sqlite.c:69 +#: src/datacache/plugin_datacache_sqlite.c:72 +#: src/datastore/plugin_datastore_mysql.c:803 +#: src/datastore/plugin_datastore_mysql.c:817 +#: src/datastore/plugin_datastore_sqlite.c:57 src/mysql/mysql.c:41 +#: src/mysql/mysql.c:48 src/mysql/mysql.c:522 src/mysql/mysql.c:531 +#: src/mysql/mysql.c:591 src/mysql/mysql.c:607 +#: src/namestore/plugin_namestore_sqlite.c:51 src/util/crypto_ksk.c:49 +#: src/util/crypto_rsa.c:67 src/include/gnunet_common.h:525 +#: src/include/gnunet_common.h:532 #, c-format msgid "`%s' failed at %s:%d with error: %s\n" msgstr "" -#: src/datacache/plugin_datacache_mysql.c:224 -#: src/datastore/plugin_datastore_mysql.c:316 -#, c-format -msgid "Trying to use file `%s' for MySQL configuration.\n" -msgstr "" - -#: src/datacache/plugin_datacache_mysql.c:230 -#: src/datastore/plugin_datastore_mysql.c:322 -#, c-format -msgid "Could not access file `%s': %s\n" -msgstr "" - -#: src/datacache/plugin_datacache_mysql.c:979 +#: src/datacache/plugin_datacache_mysql.c:450 msgid "MySQL datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_postgres.c:79 -#: src/datastore/plugin_datastore_postgres.c:93 -#, c-format -msgid "`%s:%s' failed at %s:%d with error: %s" -msgstr "" - -#: src/datacache/plugin_datacache_postgres.c:149 -#, c-format -msgid "Unable to initialize Postgres: %s" -msgstr "" - -#: src/datacache/plugin_datacache_postgres.c:499 +#: src/datacache/plugin_datacache_postgres.c:367 msgid "Postgres datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:424 +#: src/datacache/plugin_datacache_sqlite.c:410 msgid "Sqlite datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:457 -#: src/datastore/plugin_datastore_sqlite.c:414 -#: src/namestore/plugin_namestore_sqlite.c:381 +#: src/datacache/plugin_datacache_sqlite.c:443 +#: src/datastore/plugin_datastore_sqlite.c:408 +#: src/namestore/plugin_namestore_sqlite.c:370 msgid "Tried to close sqlite without finalizing all prepared statements.\n" msgstr "" +#: src/datacache/plugin_datacache_sqlite.c:450 +#, c-format +msgid "Failed to close statement %p: %d\n" +msgstr "" + #: src/datacache/plugin_datacache_template.c:121 msgid "Template datacache running\n" msgstr "" -#: src/datastore/datastore_api.c:289 +#: src/datastore/datastore_api.c:305 msgid "Failed to transmit request to drop database.\n" msgstr "" -#: src/datastore/datastore_api.c:372 +#: src/datastore/datastore_api.c:388 msgid "# queue entry timeouts" msgstr "" -#: src/datastore/datastore_api.c:418 +#: src/datastore/datastore_api.c:432 msgid "# queue overflows" msgstr "" -#: src/datastore/datastore_api.c:445 +#: src/datastore/datastore_api.c:459 msgid "# queue entries created" msgstr "" -#: src/datastore/datastore_api.c:465 +#: src/datastore/datastore_api.c:477 msgid "# Requests dropped from datastore queue" msgstr "" -#: src/datastore/datastore_api.c:513 +#: src/datastore/datastore_api.c:525 msgid "# datastore connections (re)created" msgstr "" -#: src/datastore/datastore_api.c:540 +#: src/datastore/datastore_api.c:548 msgid "# reconnected to DATASTORE" msgstr "" -#: src/datastore/datastore_api.c:608 +#: src/datastore/datastore_api.c:612 msgid "# transmission request failures" msgstr "" -#: src/datastore/datastore_api.c:631 +#: src/datastore/datastore_api.c:633 msgid "# bytes sent to datastore" msgstr "" -#: src/datastore/datastore_api.c:772 +#: src/datastore/datastore_api.c:764 msgid "Failed to receive status response from database." msgstr "" -#: src/datastore/datastore_api.c:786 +#: src/datastore/datastore_api.c:778 msgid "Error reading response from datastore service" msgstr "" -#: src/datastore/datastore_api.c:798 src/datastore/datastore_api.c:804 +#: src/datastore/datastore_api.c:790 src/datastore/datastore_api.c:796 msgid "Invalid error message received from datastore service" msgstr "" -#: src/datastore/datastore_api.c:810 +#: src/datastore/datastore_api.c:800 msgid "# status messages received" msgstr "" -#: src/datastore/datastore_api.c:883 +#: src/datastore/datastore_api.c:869 msgid "# PUT requests executed" msgstr "" -#: src/datastore/datastore_api.c:954 +#: src/datastore/datastore_api.c:936 msgid "# RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1019 +#: src/datastore/datastore_api.c:997 msgid "# RELEASE RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1080 +#: src/datastore/datastore_api.c:1054 msgid "# UPDATE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1148 +#: src/datastore/datastore_api.c:1118 msgid "# REMOVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1193 +#: src/datastore/datastore_api.c:1163 msgid "Failed to receive response from database.\n" msgstr "" -#: src/datastore/datastore_api.c:1253 +#: src/datastore/datastore_api.c:1221 msgid "# Results received" msgstr "" -#: src/datastore/datastore_api.c:1324 +#: src/datastore/datastore_api.c:1286 msgid "# GET REPLICATION requests executed" msgstr "" -#: src/datastore/datastore_api.c:1391 +#: src/datastore/datastore_api.c:1349 msgid "# GET ZERO ANONYMITY requests executed" msgstr "" -#: src/datastore/datastore_api.c:1455 +#: src/datastore/datastore_api.c:1409 msgid "# GET requests executed" msgstr "" -#: src/datastore/gnunet-service-datastore.c:351 +#: src/datastore/gnunet-service-datastore.c:349 msgid "# bytes expired" msgstr "" -#: src/datastore/gnunet-service-datastore.c:426 +#: src/datastore/gnunet-service-datastore.c:422 msgid "# bytes purged (low-priority)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:486 +#: src/datastore/gnunet-service-datastore.c:480 msgid "Transmission to client failed!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:640 +#: src/datastore/gnunet-service-datastore.c:511 +msgid "Shutdown in progress, aborting transmission.\n" +msgstr "" + +#: src/datastore/gnunet-service-datastore.c:626 msgid "# results found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:685 +#: src/datastore/gnunet-service-datastore.c:669 #, c-format msgid "" "Insufficient space (%llu bytes are available) to satisfy `%s' request for " "%llu bytes\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:696 +#: src/datastore/gnunet-service-datastore.c:680 #, c-format msgid "" "The requested amount (%llu bytes) is larger than the cache size (%llu " "bytes)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:700 +#: src/datastore/gnunet-service-datastore.c:684 msgid "" "Insufficient space to satisfy request and requested amount is larger than " "cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:706 +#: src/datastore/gnunet-service-datastore.c:690 msgid "Insufficient space to satisfy request" msgstr "" -#: src/datastore/gnunet-service-datastore.c:711 -#: src/datastore/gnunet-service-datastore.c:765 -#: src/datastore/gnunet-service-datastore.c:986 -#: src/datastore/gnunet-service-datastore.c:1465 +#: src/datastore/gnunet-service-datastore.c:695 +#: src/datastore/gnunet-service-datastore.c:747 +#: src/datastore/gnunet-service-datastore.c:960 +#: src/datastore/gnunet-service-datastore.c:1417 msgid "# reserved" msgstr "" -#: src/datastore/gnunet-service-datastore.c:780 +#: src/datastore/gnunet-service-datastore.c:760 msgid "Could not find matching reservation" msgstr "" -#: src/datastore/gnunet-service-datastore.c:868 +#: src/datastore/gnunet-service-datastore.c:846 #, c-format msgid "Need %llu bytes more space (%llu allowed, using %llu)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1034 +#: src/datastore/gnunet-service-datastore.c:1006 msgid "# GET requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1048 +#: src/datastore/gnunet-service-datastore.c:1018 msgid "# requests filtered by bloomfilter" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1076 +#: src/datastore/gnunet-service-datastore.c:1046 msgid "# UPDATE requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1110 +#: src/datastore/gnunet-service-datastore.c:1076 msgid "# GET REPLICATION requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1145 +#: src/datastore/gnunet-service-datastore.c:1109 msgid "# GET ZERO ANONYMITY requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1172 +#: src/datastore/gnunet-service-datastore.c:1134 msgid "Content not found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1182 +#: src/datastore/gnunet-service-datastore.c:1142 msgid "# bytes removed (explicit request)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1216 +#: src/datastore/gnunet-service-datastore.c:1174 msgid "# REMOVE requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1260 +#: src/datastore/gnunet-service-datastore.c:1216 #, c-format msgid "Datastore payload inaccurate (%lld < %lld). Trying to fix.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1323 +#: src/datastore/gnunet-service-datastore.c:1277 #, c-format msgid "Loading `%s' datastore plugin\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1332 +#: src/datastore/gnunet-service-datastore.c:1286 #, c-format msgid "Failed to load datastore plugin for `%s'\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1536 +#: src/datastore/gnunet-service-datastore.c:1488 #, c-format msgid "# bytes used in file-sharing datastore `%s'" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1547 +#: src/datastore/gnunet-service-datastore.c:1499 msgid "# quota" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1549 +#: src/datastore/gnunet-service-datastore.c:1501 msgid "# cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1562 +#: src/datastore/gnunet-service-datastore.c:1514 #, c-format msgid "Could not use specified filename `%s' for bloomfilter.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1580 -#: src/datastore/gnunet-service-datastore.c:1596 +#: src/datastore/gnunet-service-datastore.c:1532 +#: src/datastore/gnunet-service-datastore.c:1548 #, c-format msgid "Failed to remove bogus bloomfilter file `%s'\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1626 +#: src/datastore/gnunet-service-datastore.c:1578 msgid "Failed to initialize bloomfilter.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1655 +#: src/datastore/gnunet-service-datastore.c:1607 msgid "Rebuilding bloomfilter. Please be patient.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1660 +#: src/datastore/gnunet-service-datastore.c:1612 msgid "Plugin does not support get_keys function. Please fix!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1663 +#: src/datastore/gnunet-service-datastore.c:1615 msgid "Bloomfilter construction complete.\n" msgstr "" -#: src/datastore/plugin_datastore_mysql.c:529 -#: src/datastore/plugin_datastore_mysql.c:1336 +#: src/datastore/plugin_datastore_mysql.c:780 #, c-format msgid "Failed to prepare statement `%s'\n" msgstr "" -#: src/datastore/plugin_datastore_mysql.c:622 -#: src/datastore/plugin_datastore_mysql.c:1346 +#: src/datastore/plugin_datastore_mysql.c:788 #, c-format msgid "`%s' for `%s' failed at %s:%d with error: %s\n" msgstr "" -#: src/datastore/plugin_datastore_mysql.c:1581 +#: src/datastore/plugin_datastore_mysql.c:1019 msgid "Mysql database running\n" msgstr "" -#: src/datastore/plugin_datastore_postgres.c:173 -#, c-format -msgid "Unable to initialize Postgres with configuration `%s': %s" +#: src/datastore/plugin_datastore_postgres.c:824 +msgid "Failed to drop table from database.\n" msgstr "" -#: src/datastore/plugin_datastore_postgres.c:1017 +#: src/datastore/plugin_datastore_postgres.c:860 msgid "Postgres database running\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:61 +#: src/datastore/plugin_datastore_sqlite.c:57 #, c-format msgid "`%s' failed at %s:%u with error: %s" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:239 -#: src/namestore/plugin_namestore_sqlite.c:223 +#: src/datastore/plugin_datastore_sqlite.c:233 +#: src/namestore/plugin_namestore_sqlite.c:204 #, c-format msgid "Option `%s' in section `%s' missing in configuration!\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:266 -#: src/namestore/plugin_namestore_sqlite.c:248 +#: src/datastore/plugin_datastore_sqlite.c:260 +#: src/namestore/plugin_namestore_sqlite.c:229 #, c-format msgid "Unable to initialize SQLite: %s.\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:669 +#: src/datastore/plugin_datastore_sqlite.c:655 msgid "Invalid data in database. Trying to fix (by deletion).\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1159 +#: src/datastore/plugin_datastore_sqlite.c:1139 msgid "sqlite version to old to determine size, assuming zero\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1178 +#: src/datastore/plugin_datastore_sqlite.c:1158 #, c-format msgid "" "Using sqlite page utilization to estimate payload (%llu pages of size %llu " "bytes)\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1218 -#: src/namestore/plugin_namestore_sqlite.c:779 +#: src/datastore/plugin_datastore_sqlite.c:1198 +#: src/namestore/plugin_namestore_sqlite.c:829 msgid "Sqlite database running\n" msgstr "" @@ -1123,32 +1126,31 @@ msgstr "" msgid "Template database running\n" msgstr "" -#: src/dht/dht_api.c:280 +#: src/dht/dht_api.c:348 msgid "Failed to connect to the DHT service!\n" msgstr "" -#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-put.c:172 -#: src/gns/gnunet-gns-lookup.c:179 +#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-monitor.c:293 +#: src/dht/gnunet-dht-put.c:192 msgid "the query key" msgstr "" -#: src/dht/gnunet-dht-get.c:204 src/gns/gnunet-gns-lookup.c:182 +#: src/dht/gnunet-dht-get.c:204 msgid "how many parallel requests (replicas) to create" msgstr "" -#: src/dht/gnunet-dht-get.c:207 src/gns/gnunet-gns-lookup.c:185 +#: src/dht/gnunet-dht-get.c:207 src/dht/gnunet-dht-monitor.c:296 msgid "the type of data to look for" msgstr "" -#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:181 -#: src/gns/gnunet-gns-lookup.c:188 +#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:201 msgid "how long to execute this query before giving up?" msgstr "" -#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-put.c:184 -#: src/fs/gnunet-download.c:270 src/fs/gnunet-publish.c:725 -#: src/fs/gnunet-search.c:297 src/fs/gnunet-unindex.c:169 -#: src/gns/gnunet-gns-lookup.c:191 src/nse/gnunet-nse-profiler.c:908 +#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-monitor.c:302 +#: src/dht/gnunet-dht-put.c:204 src/fs/gnunet-download.c:271 +#: src/fs/gnunet-publish.c:731 src/fs/gnunet-search.c:297 +#: src/fs/gnunet-unindex.c:169 src/nse/gnunet-nse-profiler.c:910 msgid "be verbose (print progress information)" msgstr "" @@ -1156,93 +1158,109 @@ msgstr "" msgid "Issue a GET request to the GNUnet DHT, prints results." msgstr "" -#: src/dht/gnunet-dht-put.c:100 +#: src/dht/gnunet-dht-monitor.c:299 +msgid "how long to execute? 0 = forever" +msgstr "" + +#: src/dht/gnunet-dht-monitor.c:321 +msgid "Prints all packets that go through the DHT." +msgstr "" + +#: src/dht/gnunet-dht-put.c:108 msgid "PUT request sent!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:124 +#: src/dht/gnunet-dht-put.c:111 +msgid "Timeout sending PUT request!\n" +msgstr "" + +#: src/dht/gnunet-dht-put.c:114 +msgid "PUT request not confirmed!\n" +msgstr "" + +#: src/dht/gnunet-dht-put.c:144 msgid "Must provide KEY and DATA for DHT put!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:132 +#: src/dht/gnunet-dht-put.c:152 #, c-format msgid "Could not connect to %s service!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:137 +#: src/dht/gnunet-dht-put.c:157 #, c-format msgid "Connected to %s service!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:152 +#: src/dht/gnunet-dht-put.c:172 #, c-format msgid "Issuing put request for `%s' with data `%s'!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:166 +#: src/dht/gnunet-dht-put.c:186 msgid "the data to insert under the key" msgstr "" -#: src/dht/gnunet-dht-put.c:169 +#: src/dht/gnunet-dht-put.c:189 msgid "how long to store this entry in the dht (in seconds)" msgstr "" -#: src/dht/gnunet-dht-put.c:175 +#: src/dht/gnunet-dht-put.c:195 msgid "how many replicas to create" msgstr "" -#: src/dht/gnunet-dht-put.c:178 +#: src/dht/gnunet-dht-put.c:198 msgid "the type to insert data as" msgstr "" -#: src/dht/gnunet-dht-put.c:203 +#: src/dht/gnunet-dht-put.c:223 msgid "Issue a PUT request to the GNUnet DHT insert DATA under KEY." msgstr "" -#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:556 -#: src/testing/testing.c:1979 src/testing/testing.c:2009 +#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:544 +#: src/testing/testing.c:1968 src/testing/testing.c:1998 msgid "Failed to connect to transport service!\n" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:371 +#: src/dht/gnunet-service-dht_clients.c:407 msgid "# GET requests from clients injected" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:462 +#: src/dht/gnunet-service-dht_clients.c:500 msgid "# PUT requests received from clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:529 +#: src/dht/gnunet-service-dht_clients.c:584 msgid "# GET requests received from clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:624 +#: src/dht/gnunet-service-dht_clients.c:682 msgid "# GET STOP requests received from clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:854 +#: src/dht/gnunet-service-dht_clients.c:919 msgid "# Key match, type mismatches in REPLY to CLIENT" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:869 +#: src/dht/gnunet-service-dht_clients.c:932 msgid "# Duplicate REPLIES to CLIENT request dropped" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:906 +#: src/dht/gnunet-service-dht_clients.c:967 #, c-format msgid "Unsupported block type (%u) in request!\n" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:928 +#: src/dht/gnunet-service-dht_clients.c:989 msgid "# RESULTS queued for clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:979 -#: src/dht/gnunet-service-dht_clients.c:1022 +#: src/dht/gnunet-service-dht_clients.c:1038 +#: src/dht/gnunet-service-dht_clients.c:1081 msgid "# REPLIES ignored for CLIENTS (no match)" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:989 +#: src/dht/gnunet-service-dht_clients.c:1048 msgid "Could not pass reply to client, message too big!\n" msgstr "" @@ -1255,28 +1273,28 @@ msgstr "" msgid "# ITEMS stored in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:209 +#: src/dht/gnunet-service-dht_datacache.c:207 msgid "# Good RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:220 +#: src/dht/gnunet-service-dht_datacache.c:218 msgid "# Duplicate RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:226 +#: src/dht/gnunet-service-dht_datacache.c:224 msgid "# Invalid RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:238 +#: src/dht/gnunet-service-dht_datacache.c:236 msgid "# Unsupported RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:241 +#: src/dht/gnunet-service-dht_datacache.c:239 #, c-format msgid "Unsupported block type (%u) in local response!\n" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:271 +#: src/dht/gnunet-service-dht_datacache.c:269 msgid "# GET requests given to datacache" msgstr "" @@ -1288,82 +1306,77 @@ msgstr "" msgid "# Preference updates given to core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:573 +#: src/dht/gnunet-service-dht_neighbours.c:571 msgid "# FIND PEER messages initiated" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:629 -#: src/dht/gnunet-service-dht_neighbours.c:689 -msgid "# Peers connected" -msgstr "" - -#: src/dht/gnunet-service-dht_neighbours.c:723 +#: src/dht/gnunet-service-dht_neighbours.c:717 msgid "# Queued messages discarded (peer disconnected)" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:778 +#: src/dht/gnunet-service-dht_neighbours.c:772 msgid "# Bytes transmitted to other peers" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:816 +#: src/dht/gnunet-service-dht_neighbours.c:810 msgid "# Bytes of bandwdith requested from core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1040 -#: src/dht/gnunet-service-dht_neighbours.c:1068 +#: src/dht/gnunet-service-dht_neighbours.c:1032 +#: src/dht/gnunet-service-dht_neighbours.c:1060 msgid "# Peers excluded from routing due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1049 -#: src/dht/gnunet-service-dht_neighbours.c:1085 +#: src/dht/gnunet-service-dht_neighbours.c:1041 +#: src/dht/gnunet-service-dht_neighbours.c:1075 msgid "# Peer selection failed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1221 +#: src/dht/gnunet-service-dht_neighbours.c:1207 msgid "# PUT requests routed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1252 +#: src/dht/gnunet-service-dht_neighbours.c:1236 msgid "# PUT messages queued for transmission" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1333 +#: src/dht/gnunet-service-dht_neighbours.c:1315 msgid "# GET requests routed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1364 +#: src/dht/gnunet-service-dht_neighbours.c:1342 msgid "# GET messages queued for transmission" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1467 +#: src/dht/gnunet-service-dht_neighbours.c:1443 msgid "# RESULT messages queued for transmission" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1555 +#: src/dht/gnunet-service-dht_neighbours.c:1531 msgid "# P2P PUT requests received" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1668 +#: src/dht/gnunet-service-dht_neighbours.c:1647 msgid "# FIND PEER requests ignored due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1676 +#: src/dht/gnunet-service-dht_neighbours.c:1655 msgid "# FIND PEER requests ignored due to lack of HELLO" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1767 +#: src/dht/gnunet-service-dht_neighbours.c:1746 msgid "# P2P GET requests received" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1811 +#: src/dht/gnunet-service-dht_neighbours.c:1788 msgid "# P2P FIND PEER requests processed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1825 +#: src/dht/gnunet-service-dht_neighbours.c:1802 msgid "# P2P GET requests ONLY routed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1895 +#: src/dht/gnunet-service-dht_neighbours.c:1876 msgid "# P2P RESULTS received" msgstr "" @@ -1383,29 +1396,28 @@ msgstr "" msgid "# Invalid REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:236 +#: src/dht/gnunet-service-dht_routing.c:238 msgid "# Unsupported REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:314 -#: src/dht/gnunet-service-dht_routing.c:368 +#: src/dht/gnunet-service-dht_routing.c:311 msgid "# Entries removed from routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:324 +#: src/dht/gnunet-service-dht_routing.c:352 msgid "# Entries added to routing table" msgstr "" -#: src/dht/plugin_block_dht.c:124 +#: src/dht/plugin_block_dht.c:136 #, c-format msgid "Block not of type %u\n" msgstr "" -#: src/dht/plugin_block_dht.c:131 +#: src/dht/plugin_block_dht.c:143 msgid "Size mismatch for block\n" msgstr "" -#: src/dht/plugin_block_dht.c:140 +#: src/dht/plugin_block_dht.c:152 #, c-format msgid "Block of type %u is malformed\n" msgstr "" @@ -1434,67 +1446,68 @@ msgstr "" msgid "Change DNS replies to point elsewhere." msgstr "" -#: src/dns/gnunet-service-dns.c:480 +#: src/dns/gnunet-service-dns.c:485 #, c-format msgid "Could not bind to any port: %s\n" msgstr "" -#: src/dns/gnunet-service-dns.c:634 +#: src/dns/gnunet-service-dns.c:639 msgid "# DNS requests answered via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:818 +#: src/dns/gnunet-service-dns.c:822 msgid "# DNS exit failed (failed to open socket)" msgstr "" -#: src/dns/gnunet-service-dns.c:1001 +#: src/dns/gnunet-service-dns.c:1005 #, c-format msgid "Received DNS response that is too small (%u bytes)" msgstr "" -#: src/dns/gnunet-service-dns.c:1046 +#: src/dns/gnunet-service-dns.c:1050 msgid "# External DNS response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1165 +#: src/dns/gnunet-service-dns.c:1168 msgid "# Client response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1198 -msgid "Changing DNS reply according to client specifications\n" -msgstr "" - -#: src/dns/gnunet-service-dns.c:1279 +#: src/dns/gnunet-service-dns.c:1281 msgid "Received malformed IPv4-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1294 +#: src/dns/gnunet-service-dns.c:1297 msgid "Received malformed IPv6-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1303 +#: src/dns/gnunet-service-dns.c:1306 #, c-format msgid "Got non-IP packet with %u bytes and protocol %u from TUN\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1312 +#: src/dns/gnunet-service-dns.c:1315 msgid "# Non-DNS UDP packet received via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:1377 +#: src/dns/gnunet-service-dns.c:1380 msgid "# DNS requests received via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:1461 +#: src/dns/gnunet-service-dns.c:1465 #, c-format msgid "Configured DNS exit `%s' is not working / valid.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1493 src/exit/gnunet-daemon-exit.c:2673 +#: src/dns/gnunet-service-dns.c:1497 src/exit/gnunet-daemon-exit.c:2674 msgid "# Inbound MESH tunnels created" msgstr "" -#: src/dns/gnunet-service-dns.c:1567 +#: src/dns/gnunet-service-dns.c:1561 src/exit/gnunet-daemon-exit.c:3032 +#, c-format +msgid "`%s' must be installed SUID, refusing to run\n" +msgstr "" + +#: src/dns/gnunet-service-dns.c:1581 msgid "Configured to provide DNS exit, but no valid DNS server configured!\n" msgstr "" @@ -1516,15 +1529,15 @@ msgstr "" msgid "# Bytes transmitted via mesh tunnels" msgstr "" -#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2068 -#: src/exit/gnunet-daemon-exit.c:2318 src/vpn/gnunet-service-vpn.c:1388 -#: src/vpn/gnunet-service-vpn.c:1788 src/vpn/gnunet-service-vpn.c:1951 +#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2069 +#: src/exit/gnunet-daemon-exit.c:2319 src/vpn/gnunet-service-vpn.c:1394 +#: src/vpn/gnunet-service-vpn.c:1795 src/vpn/gnunet-service-vpn.c:1958 msgid "# ICMPv4 packets dropped (type not allowed)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2127 -#: src/exit/gnunet-daemon-exit.c:2377 src/vpn/gnunet-service-vpn.c:1444 -#: src/vpn/gnunet-service-vpn.c:1847 src/vpn/gnunet-service-vpn.c:1984 +#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2128 +#: src/exit/gnunet-daemon-exit.c:2378 src/vpn/gnunet-service-vpn.c:1450 +#: src/vpn/gnunet-service-vpn.c:1854 src/vpn/gnunet-service-vpn.c:1991 msgid "# ICMPv6 packets dropped (type not allowed)" msgstr "" @@ -1571,124 +1584,124 @@ msgstr "" msgid "Packet from unknown protocol %u received. Ignored.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1470 +#: src/exit/gnunet-daemon-exit.c:1471 msgid "# TCP packets sent via TUN" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1570 +#: src/exit/gnunet-daemon-exit.c:1571 msgid "# TCP service creation requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1573 src/exit/gnunet-daemon-exit.c:1652 -#: src/exit/gnunet-daemon-exit.c:1762 src/exit/gnunet-daemon-exit.c:1992 -#: src/exit/gnunet-daemon-exit.c:2234 src/exit/gnunet-daemon-exit.c:2515 -#: src/exit/gnunet-daemon-exit.c:2615 +#: src/exit/gnunet-daemon-exit.c:1574 src/exit/gnunet-daemon-exit.c:1653 +#: src/exit/gnunet-daemon-exit.c:1763 src/exit/gnunet-daemon-exit.c:1993 +#: src/exit/gnunet-daemon-exit.c:2235 src/exit/gnunet-daemon-exit.c:2516 +#: src/exit/gnunet-daemon-exit.c:2616 msgid "# Bytes received from MESH" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1606 src/exit/gnunet-daemon-exit.c:2637 +#: src/exit/gnunet-daemon-exit.c:1607 src/exit/gnunet-daemon-exit.c:2638 #, c-format msgid "No service found for %s on port %d!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1610 +#: src/exit/gnunet-daemon-exit.c:1611 msgid "# TCP requests dropped (no such service)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1655 +#: src/exit/gnunet-daemon-exit.c:1656 msgid "# TCP IP-exit creation requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1765 +#: src/exit/gnunet-daemon-exit.c:1766 msgid "# TCP data requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1779 +#: src/exit/gnunet-daemon-exit.c:1780 msgid "# TCP DATA requests dropped (no session)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1829 +#: src/exit/gnunet-daemon-exit.c:1830 msgid "# ICMP packets sent via TUN" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1995 +#: src/exit/gnunet-daemon-exit.c:1996 msgid "# ICMP IP-exit requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2237 +#: src/exit/gnunet-daemon-exit.c:2238 msgid "# ICMP service requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2303 src/vpn/gnunet-service-vpn.c:1378 -#: src/vpn/gnunet-service-vpn.c:1945 +#: src/exit/gnunet-daemon-exit.c:2304 src/vpn/gnunet-service-vpn.c:1384 +#: src/vpn/gnunet-service-vpn.c:1952 msgid "# ICMPv4 packets dropped (impossible PT to v6)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2362 src/vpn/gnunet-service-vpn.c:1414 -#: src/vpn/gnunet-service-vpn.c:1426 src/vpn/gnunet-service-vpn.c:1835 +#: src/exit/gnunet-daemon-exit.c:2363 src/vpn/gnunet-service-vpn.c:1420 +#: src/vpn/gnunet-service-vpn.c:1432 src/vpn/gnunet-service-vpn.c:1842 msgid "# ICMPv6 packets dropped (impossible PT to v4)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2412 +#: src/exit/gnunet-daemon-exit.c:2413 msgid "# UDP packets sent via TUN" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2518 +#: src/exit/gnunet-daemon-exit.c:2519 msgid "# UDP IP-exit requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2618 +#: src/exit/gnunet-daemon-exit.c:2619 msgid "# UDP service requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2641 +#: src/exit/gnunet-daemon-exit.c:2642 msgid "# UDP requests dropped (no such service)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2881 +#: src/exit/gnunet-daemon-exit.c:2882 #, c-format msgid "No addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2895 src/exit/gnunet-daemon-exit.c:2907 +#: src/exit/gnunet-daemon-exit.c:2896 src/exit/gnunet-daemon-exit.c:2908 #, c-format msgid "Service `%s' configured for IPv4, but IPv4 is disabled!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2918 +#: src/exit/gnunet-daemon-exit.c:2919 #, c-format msgid "No IP addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3047 +#: src/exit/gnunet-daemon-exit.c:3048 msgid "" "This system does not support IPv4, will disable IPv4 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3055 +#: src/exit/gnunet-daemon-exit.c:3056 msgid "" "This system does not support IPv6, will disable IPv6 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3062 +#: src/exit/gnunet-daemon-exit.c:3063 msgid "" "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use " "ENABLE_IPv4=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3068 +#: src/exit/gnunet-daemon-exit.c:3069 msgid "" "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use " "ENABLE_IPv6=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3074 src/pt/gnunet-daemon-pt.c:884 +#: src/exit/gnunet-daemon-exit.c:3075 src/pt/gnunet-daemon-pt.c:884 msgid "No useful service enabled. Exiting.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3235 +#: src/exit/gnunet-daemon-exit.c:3236 msgid "Daemon to run to provide an IP exit node for the VPN" msgstr "" @@ -1696,116 +1709,120 @@ msgstr "" msgid "# acknowledgements sent for fragment" msgstr "" -#: src/fragmentation/defragmentation.c:454 +#: src/fragmentation/defragmentation.c:456 msgid "# fragments received" msgstr "" -#: src/fragmentation/defragmentation.c:513 +#: src/fragmentation/defragmentation.c:521 msgid "# duplicate fragments received" msgstr "" -#: src/fragmentation/defragmentation.c:526 +#: src/fragmentation/defragmentation.c:534 msgid "# messages defragmented" msgstr "" -#: src/fragmentation/fragmentation.c:188 +#: src/fragmentation/fragmentation.c:203 msgid "# fragments transmitted" msgstr "" -#: src/fragmentation/fragmentation.c:191 +#: src/fragmentation/fragmentation.c:206 msgid "# fragments retransmitted" msgstr "" -#: src/fragmentation/fragmentation.c:255 +#: src/fragmentation/fragmentation.c:232 +msgid "# fragments wrap arounds" +msgstr "" + +#: src/fragmentation/fragmentation.c:273 msgid "# messages fragmented" msgstr "" -#: src/fragmentation/fragmentation.c:258 +#: src/fragmentation/fragmentation.c:276 msgid "# total size of fragmented messages" msgstr "" -#: src/fragmentation/fragmentation.c:343 +#: src/fragmentation/fragmentation.c:363 msgid "# fragment acknowledgements received" msgstr "" -#: src/fragmentation/fragmentation.c:349 +#: src/fragmentation/fragmentation.c:369 msgid "# bits removed from fragmentation ACKs" msgstr "" -#: src/fragmentation/fragmentation.c:373 +#: src/fragmentation/fragmentation.c:393 msgid "# fragmentation transmissions completed" msgstr "" -#: src/fs/fs_api.c:284 +#: src/fs/fs_api.c:339 #, c-format msgid "Could not open file `%s': %s" msgstr "" -#: src/fs/fs_api.c:293 +#: src/fs/fs_api.c:348 #, c-format msgid "Could not read file `%s': %s" msgstr "" -#: src/fs/fs_api.c:299 +#: src/fs/fs_api.c:354 #, c-format msgid "Short read reading from file `%s'!" msgstr "" -#: src/fs/fs_api.c:877 +#: src/fs/fs_api.c:938 #, c-format msgid "Failed to resume publishing information `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:1334 +#: src/fs/fs_api.c:1395 #, c-format msgid "Failed to recover namespace `%s', cannot resume publishing operation.\n" msgstr "" -#: src/fs/fs_api.c:1376 +#: src/fs/fs_api.c:1437 #, c-format msgid "Failure while resuming publishing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:1392 +#: src/fs/fs_api.c:1453 #, c-format msgid "Failed to resume publishing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2004 +#: src/fs/fs_api.c:2106 #, c-format msgid "Failure while resuming unindexing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2014 +#: src/fs/fs_api.c:2116 #, c-format msgid "Failed to resume unindexing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2139 src/fs/fs_api.c:2378 +#: src/fs/fs_api.c:2241 src/fs/fs_api.c:2480 #, c-format msgid "Failed to resume sub-download `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2156 +#: src/fs/fs_api.c:2258 #, c-format msgid "Failed to resume sub-search `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2168 src/fs/fs_api.c:2187 src/fs/fs_api.c:2671 +#: src/fs/fs_api.c:2270 src/fs/fs_api.c:2289 src/fs/fs_api.c:2773 #, c-format msgid "Failure while resuming search operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2369 +#: src/fs/fs_api.c:2471 #, c-format msgid "Failed to resume sub-download `%s': could not open file `%s'\n" msgstr "" -#: src/fs/fs_api.c:2615 +#: src/fs/fs_api.c:2717 msgid "Could not resume running search, will resume as paused search\n" msgstr "" -#: src/fs/fs_api.c:2709 +#: src/fs/fs_api.c:2811 #, c-format msgid "Failure while resuming download operation `%s': %s\n" msgstr "" @@ -1814,53 +1831,57 @@ msgstr "" msgid "MAGIC mismatch. This is not a GNUnet directory.\n" msgstr "" -#: src/fs/fs_download.c:310 +#: src/fs/fs_download.c:311 msgid "" "Recursive downloads of directories larger than 4 GB are not supported on 32-" "bit systems\n" msgstr "" -#: src/fs/fs_download.c:330 +#: src/fs/fs_download.c:331 msgid "Directory too large for system address space\n" msgstr "" -#: src/fs/fs_download.c:488 src/fs/fs_download.c:500 +#: src/fs/fs_download.c:497 src/fs/fs_download.c:509 #, c-format msgid "Failed to open file `%s' for writing" msgstr "" -#: src/fs/fs_download.c:870 +#: src/fs/fs_download.c:878 #, c-format msgid "Failed to create directory for recursive download of `%s'\n" msgstr "" -#: src/fs/fs_download.c:951 +#: src/fs/fs_download.c:960 #, c-format msgid "" "Internal error or bogus download URI (expected %u bytes at depth %u and " -"offset %llu/%llu, got %u bytes)\n" +"offset %llu/%llu, got %u bytes)" msgstr "" -#: src/fs/fs_download.c:977 +#: src/fs/fs_download.c:986 msgid "internal error decrypting content" msgstr "" -#: src/fs/fs_download.c:1000 +#: src/fs/fs_download.c:1009 #, c-format -msgid "Download failed: could not open file `%s': %s\n" +msgid "Download failed: could not open file `%s': %s" msgstr "" -#: src/fs/fs_download.c:1010 +#: src/fs/fs_download.c:1019 #, c-format -msgid "Failed to seek to offset %llu in file `%s': %s\n" +msgid "Failed to seek to offset %llu in file `%s': %s" msgstr "" -#: src/fs/fs_download.c:1019 +#: src/fs/fs_download.c:1028 #, c-format -msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s\n" +msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s" +msgstr "" + +#: src/fs/fs_download.c:1125 +msgid "internal error decoding tree" msgstr "" -#: src/fs/fs_download.c:1835 +#: src/fs/fs_download.c:1888 msgid "Invalid URI" msgstr "" @@ -1936,62 +1957,62 @@ msgstr "" msgid "Failed to connect to datastore." msgstr "" -#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:395 +#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:397 #, c-format msgid "Publishing failed: %s" msgstr "" -#: src/fs/fs_publish.c:616 src/fs/fs_publish.c:633 src/fs/fs_publish.c:672 -#: src/fs/fs_publish.c:692 src/fs/fs_publish.c:717 src/fs/fs_publish.c:857 +#: src/fs/fs_publish.c:621 src/fs/fs_publish.c:638 src/fs/fs_publish.c:677 +#: src/fs/fs_publish.c:697 src/fs/fs_publish.c:722 src/fs/fs_publish.c:862 #, c-format msgid "Can not index file `%s': %s. Will try to insert instead.\n" msgstr "" -#: src/fs/fs_publish.c:618 +#: src/fs/fs_publish.c:623 msgid "timeout on index-start request to `fs' service" msgstr "" -#: src/fs/fs_publish.c:630 +#: src/fs/fs_publish.c:635 msgid "unknown error" msgstr "" -#: src/fs/fs_publish.c:673 +#: src/fs/fs_publish.c:678 msgid "failed to compute hash" msgstr "" -#: src/fs/fs_publish.c:693 +#: src/fs/fs_publish.c:698 msgid "filename too long" msgstr "" -#: src/fs/fs_publish.c:718 +#: src/fs/fs_publish.c:723 msgid "could not connect to `fs' service" msgstr "" -#: src/fs/fs_publish.c:741 +#: src/fs/fs_publish.c:746 #, c-format msgid "Failed to get file identifiers for `%s'\n" msgstr "" -#: src/fs/fs_publish.c:806 +#: src/fs/fs_publish.c:811 #, c-format msgid "Recursive upload failed at `%s': %s" msgstr "" -#: src/fs/fs_publish.c:812 +#: src/fs/fs_publish.c:817 #, c-format msgid "Recursive upload failed: %s" msgstr "" -#: src/fs/fs_publish.c:858 +#: src/fs/fs_publish.c:863 msgid "needs to be an actual file" msgstr "" -#: src/fs/fs_publish.c:1067 +#: src/fs/fs_publish.c:1071 #, c-format msgid "Insufficient space for publishing: %s" msgstr "" -#: src/fs/fs_publish.c:1138 +#: src/fs/fs_publish.c:1142 #, c-format msgid "Reserving space for %u entries and %llu bytes for publication\n" msgstr "" @@ -2000,7 +2021,7 @@ msgstr "" msgid "Could not connect to datastore." msgstr "" -#: src/fs/fs_search.c:810 +#: src/fs/fs_search.c:829 #, c-format msgid "Got result with unknown block type `%d', ignoring" msgstr "" @@ -2010,39 +2031,58 @@ msgstr "" msgid "Failed to start daemon: %s\n" msgstr "" -#: src/fs/fs_unindex.c:57 +#: src/fs/fs_unindex.c:58 msgid "Failed to find given position in file" msgstr "" -#: src/fs/fs_unindex.c:62 +#: src/fs/fs_unindex.c:63 msgid "Failed to read file" msgstr "" -#: src/fs/fs_unindex.c:231 +#: src/fs/fs_unindex.c:233 msgid "Unexpected time for a response from `fs' service." msgstr "" -#: src/fs/fs_unindex.c:239 +#: src/fs/fs_unindex.c:241 msgid "Timeout waiting for `fs' service." msgstr "" -#: src/fs/fs_unindex.c:247 +#: src/fs/fs_unindex.c:249 msgid "Invalid response from `fs' service." msgstr "" -#: src/fs/fs_unindex.c:292 +#: src/fs/fs_unindex.c:293 msgid "Failed to connect to FS service for unindexing." msgstr "" -#: src/fs/fs_unindex.c:325 +#: src/fs/fs_unindex.c:344 +msgid "Failed to get KSKs from directory scan." +msgstr "" + +#: src/fs/fs_unindex.c:356 +#, c-format +msgid "Internal error scanning `%s'.\n" +msgstr "" + +#: src/fs/fs_unindex.c:411 +#, c-format +msgid "Failed to remove KBlock: %s\n" +msgstr "" + +#: src/fs/fs_unindex.c:501 +#, c-format +msgid "Failed to parse URI `%s' from KBlock!\n" +msgstr "" + +#: src/fs/fs_unindex.c:553 src/fs/fs_unindex.c:618 msgid "Failed to connect to `datastore' service." msgstr "" -#: src/fs/fs_unindex.c:338 +#: src/fs/fs_unindex.c:631 msgid "Failed to open file for unindexing." msgstr "" -#: src/fs/fs_unindex.c:372 +#: src/fs/fs_unindex.c:665 msgid "Failed to compute hash of file." msgstr "" @@ -2150,90 +2190,90 @@ msgstr "" msgid "Display contents of a GNUnet directory" msgstr "" -#: src/fs/gnunet-download.c:100 +#: src/fs/gnunet-download.c:101 #, c-format msgid "Starting download `%s'.\n" msgstr "" -#: src/fs/gnunet-download.c:109 +#: src/fs/gnunet-download.c:110 msgid "" msgstr "" -#: src/fs/gnunet-download.c:118 +#: src/fs/gnunet-download.c:119 #, c-format msgid "" "Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to " "download\n" msgstr "" -#: src/fs/gnunet-download.c:128 +#: src/fs/gnunet-download.c:129 #, c-format msgid "Error downloading: %s.\n" msgstr "" -#: src/fs/gnunet-download.c:136 +#: src/fs/gnunet-download.c:137 #, c-format msgid "Downloading `%s' done (%s/s).\n" msgstr "" -#: src/fs/gnunet-download.c:151 src/fs/gnunet-publish.c:190 +#: src/fs/gnunet-download.c:152 src/fs/gnunet-publish.c:190 #: src/fs/gnunet-search.c:190 src/fs/gnunet-unindex.c:109 #, c-format msgid "Unexpected status: %d\n" msgstr "" -#: src/fs/gnunet-download.c:176 +#: src/fs/gnunet-download.c:177 msgid "You need to specify a URI argument.\n" msgstr "" -#: src/fs/gnunet-download.c:182 src/fs/gnunet-publish.c:618 +#: src/fs/gnunet-download.c:183 src/fs/gnunet-publish.c:624 #, c-format msgid "Failed to parse URI: %s\n" msgstr "" -#: src/fs/gnunet-download.c:189 +#: src/fs/gnunet-download.c:190 msgid "Only CHK or LOC URIs supported.\n" msgstr "" -#: src/fs/gnunet-download.c:196 +#: src/fs/gnunet-download.c:197 msgid "Target filename must be specified.\n" msgstr "" -#: src/fs/gnunet-download.c:210 src/fs/gnunet-publish.c:596 +#: src/fs/gnunet-download.c:211 src/fs/gnunet-publish.c:602 #: src/fs/gnunet-search.c:241 src/fs/gnunet-unindex.c:141 #, c-format msgid "Could not initialize `%s' subsystem.\n" msgstr "" -#: src/fs/gnunet-download.c:247 src/fs/gnunet-search.c:285 +#: src/fs/gnunet-download.c:248 src/fs/gnunet-search.c:285 msgid "set the desired LEVEL of receiver-anonymity" msgstr "" -#: src/fs/gnunet-download.c:250 +#: src/fs/gnunet-download.c:251 msgid "delete incomplete downloads (when aborted with CTRL-C)" msgstr "" -#: src/fs/gnunet-download.c:253 src/fs/gnunet-search.c:288 +#: src/fs/gnunet-download.c:254 src/fs/gnunet-search.c:288 msgid "only search the local peer (no P2P network search)" msgstr "" -#: src/fs/gnunet-download.c:256 +#: src/fs/gnunet-download.c:257 msgid "write the file to FILENAME" msgstr "" -#: src/fs/gnunet-download.c:260 +#: src/fs/gnunet-download.c:261 msgid "set the maximum number of parallel downloads that is allowed" msgstr "" -#: src/fs/gnunet-download.c:264 +#: src/fs/gnunet-download.c:265 msgid "set the maximum number of parallel requests for blocks that is allowed" msgstr "" -#: src/fs/gnunet-download.c:267 +#: src/fs/gnunet-download.c:268 msgid "download a GNUnet directory recursively" msgstr "" -#: src/fs/gnunet-download.c:277 +#: src/fs/gnunet-download.c:278 msgid "" "Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/" "chk/...)" @@ -2247,69 +2287,64 @@ msgstr "" msgid "Special file-sharing operations" msgstr "" -#: src/fs/gnunet-pseudonym.c:151 src/statistics/gnunet-statistics.c:126 +#: src/fs/gnunet-pseudonym.c:160 src/statistics/gnunet-statistics.c:167 #, c-format msgid "Invalid argument `%s'\n" msgstr "" -#: src/fs/gnunet-pseudonym.c:165 -#, c-format -msgid "Namespace `%s' unknown.\n" -msgstr "" - -#: src/fs/gnunet-pseudonym.c:240 src/fs/gnunet-pseudonym.c:247 -#: src/fs/gnunet-pseudonym.c:249 +#: src/fs/gnunet-pseudonym.c:250 src/fs/gnunet-pseudonym.c:257 +#: src/fs/gnunet-pseudonym.c:259 #, c-format msgid "Option `%s' ignored\n" msgstr "" -#: src/fs/gnunet-pseudonym.c:269 src/fs/gnunet-publish.c:672 +#: src/fs/gnunet-pseudonym.c:279 src/fs/gnunet-publish.c:678 msgid "set the desired LEVEL of sender-anonymity" msgstr "" -#: src/fs/gnunet-pseudonym.c:272 +#: src/fs/gnunet-pseudonym.c:282 msgid "create or advertise namespace NAME" msgstr "" -#: src/fs/gnunet-pseudonym.c:275 +#: src/fs/gnunet-pseudonym.c:285 msgid "delete namespace NAME " msgstr "" -#: src/fs/gnunet-pseudonym.c:278 +#: src/fs/gnunet-pseudonym.c:288 msgid "" "add an additional keyword for the advertisment (this option can be specified " "multiple times)" msgstr "" -#: src/fs/gnunet-pseudonym.c:282 src/fs/gnunet-publish.c:691 +#: src/fs/gnunet-pseudonym.c:292 src/fs/gnunet-publish.c:697 msgid "set the meta-data for the given TYPE to the given VALUE" msgstr "" -#: src/fs/gnunet-pseudonym.c:285 +#: src/fs/gnunet-pseudonym.c:295 msgid "print names of local namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:288 +#: src/fs/gnunet-pseudonym.c:298 msgid "use the given PRIORITY for the advertisments" msgstr "" -#: src/fs/gnunet-pseudonym.c:291 +#: src/fs/gnunet-pseudonym.c:301 msgid "do not print names of remote namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:294 src/fs/gnunet-publish.c:710 +#: src/fs/gnunet-pseudonym.c:304 src/fs/gnunet-publish.c:716 msgid "set the desired replication LEVEL" msgstr "" -#: src/fs/gnunet-pseudonym.c:297 +#: src/fs/gnunet-pseudonym.c:307 msgid "specify ID of the root of the namespace" msgstr "" -#: src/fs/gnunet-pseudonym.c:300 +#: src/fs/gnunet-pseudonym.c:310 msgid "change rating of namespace ID by VALUE" msgstr "" -#: src/fs/gnunet-pseudonym.c:308 +#: src/fs/gnunet-pseudonym.c:318 msgid "Manage GNUnet pseudonyms." msgstr "" @@ -2337,161 +2372,161 @@ msgstr "" msgid "Cleanup after abort complete.\n" msgstr "" -#: src/fs/gnunet-publish.c:299 +#: src/fs/gnunet-publish.c:305 #, c-format msgid "Meta data for file `%s' (%s)\n" msgstr "" -#: src/fs/gnunet-publish.c:301 +#: src/fs/gnunet-publish.c:307 #, c-format msgid "Keywords for file `%s' (%s)\n" msgstr "" -#: src/fs/gnunet-publish.c:352 +#: src/fs/gnunet-publish.c:358 #, c-format msgid "Failed to create namespace `%s'\n" msgstr "" -#: src/fs/gnunet-publish.c:427 +#: src/fs/gnunet-publish.c:433 msgid "Could not publish\n" msgstr "" -#: src/fs/gnunet-publish.c:454 +#: src/fs/gnunet-publish.c:460 msgid "Could not start publishing.\n" msgstr "" -#: src/fs/gnunet-publish.c:485 +#: src/fs/gnunet-publish.c:491 #, c-format msgid "Scanning directory `%s'.\n" msgstr "" -#: src/fs/gnunet-publish.c:487 +#: src/fs/gnunet-publish.c:493 #, c-format msgid "Scanning file `%s'.\n" msgstr "" -#: src/fs/gnunet-publish.c:492 +#: src/fs/gnunet-publish.c:498 #, c-format msgid "There was trouble processing file `%s', skipping it.\n" msgstr "" -#: src/fs/gnunet-publish.c:497 +#: src/fs/gnunet-publish.c:503 msgid "Preprocessing complete.\n" msgstr "" -#: src/fs/gnunet-publish.c:501 +#: src/fs/gnunet-publish.c:507 #, c-format msgid "Extracting meta data from file `%s' complete.\n" msgstr "" -#: src/fs/gnunet-publish.c:505 +#: src/fs/gnunet-publish.c:511 msgid "Meta data extraction has finished.\n" msgstr "" -#: src/fs/gnunet-publish.c:512 +#: src/fs/gnunet-publish.c:518 msgid "Internal error scanning directory.\n" msgstr "" -#: src/fs/gnunet-publish.c:546 +#: src/fs/gnunet-publish.c:552 #, c-format msgid "Cannot extract metadata from a URI!\n" msgstr "" -#: src/fs/gnunet-publish.c:553 +#: src/fs/gnunet-publish.c:559 #, c-format msgid "You must specify one and only one filename for insertion.\n" msgstr "" -#: src/fs/gnunet-publish.c:559 +#: src/fs/gnunet-publish.c:565 #, c-format msgid "You must NOT specify an URI and a filename.\n" msgstr "" -#: src/fs/gnunet-publish.c:567 src/vpn/gnunet-vpn.c:214 +#: src/fs/gnunet-publish.c:573 src/vpn/gnunet-vpn.c:214 #, c-format msgid "Option `%s' is required when using option `%s'.\n" msgstr "" -#: src/fs/gnunet-publish.c:577 src/fs/gnunet-publish.c:584 -#: src/transport/gnunet-transport.c:530 +#: src/fs/gnunet-publish.c:583 src/fs/gnunet-publish.c:590 +#: src/transport/gnunet-transport.c:560 #, c-format msgid "Option `%s' makes no sense without option `%s'.\n" msgstr "" -#: src/fs/gnunet-publish.c:606 +#: src/fs/gnunet-publish.c:612 #, c-format msgid "Could not create namespace `%s'\n" msgstr "" -#: src/fs/gnunet-publish.c:639 +#: src/fs/gnunet-publish.c:645 #, c-format msgid "Failed to access `%s': %s\n" msgstr "" -#: src/fs/gnunet-publish.c:651 +#: src/fs/gnunet-publish.c:657 msgid "" "Failed to start meta directory scanner. Is gnunet-helper-publish-fs " "installed?\n" msgstr "" -#: src/fs/gnunet-publish.c:676 +#: src/fs/gnunet-publish.c:682 msgid "disable adding the creation time to the metadata of the uploaded file" msgstr "" -#: src/fs/gnunet-publish.c:679 +#: src/fs/gnunet-publish.c:685 msgid "do not use libextractor to add keywords or metadata" msgstr "" -#: src/fs/gnunet-publish.c:683 +#: src/fs/gnunet-publish.c:689 msgid "" "print list of extracted keywords that would be used, but do not perform " "upload" msgstr "" -#: src/fs/gnunet-publish.c:687 +#: src/fs/gnunet-publish.c:693 msgid "" "add an additional keyword for the top-level file or directory (this option " "can be specified multiple times)" msgstr "" -#: src/fs/gnunet-publish.c:694 +#: src/fs/gnunet-publish.c:700 msgid "" "do not index, perform full insertion (stores entire file in encrypted form " "in GNUnet database)" msgstr "" -#: src/fs/gnunet-publish.c:699 +#: src/fs/gnunet-publish.c:705 msgid "" "specify ID of an updated version to be published in the future (for " "namespace insertions only)" msgstr "" -#: src/fs/gnunet-publish.c:703 +#: src/fs/gnunet-publish.c:709 msgid "specify the priority of the content" msgstr "" -#: src/fs/gnunet-publish.c:707 +#: src/fs/gnunet-publish.c:713 msgid "publish the files under the pseudonym NAME (place file into namespace)" msgstr "" -#: src/fs/gnunet-publish.c:713 +#: src/fs/gnunet-publish.c:719 msgid "" "only simulate the process but do not do any actual publishing (useful to " "compute URIs)" msgstr "" -#: src/fs/gnunet-publish.c:717 +#: src/fs/gnunet-publish.c:723 msgid "" "set the ID of this version of the publication (for namespace insertions only)" msgstr "" -#: src/fs/gnunet-publish.c:721 +#: src/fs/gnunet-publish.c:727 msgid "" "URI to be published (can be used instead of passing a file to add keywords " "to the file with the respective URI)" msgstr "" -#: src/fs/gnunet-publish.c:736 +#: src/fs/gnunet-publish.c:742 msgid "Publish a file or directory on GNUnet" msgstr "" @@ -2538,23 +2573,12 @@ msgid "# Loopback routes suppressed" msgstr "" #: src/fs/gnunet-service-fs.c:581 src/hostlist/gnunet-daemon-hostlist.c:297 -#: src/topology/gnunet-daemon-topology.c:1290 -#: src/topology/gnunet-daemon-topology.c:1297 +#: src/topology/gnunet-daemon-topology.c:1330 +#: src/topology/gnunet-daemon-topology.c:1337 #, c-format msgid "Failed to connect to `%s' service.\n" msgstr "" -#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 -#: src/topology/gnunet-daemon-topology.c:654 -#: src/topology/gnunet-daemon-topology.c:756 -#: src/transport/gnunet-service-transport_neighbours.c:960 -#: src/transport/gnunet-service-transport_neighbours.c:1289 -#: src/transport/gnunet-service-transport_neighbours.c:1841 -#: src/transport/gnunet-service-transport_neighbours.c:2499 -#: src/transport/gnunet-service-transport_neighbours.c:2566 -msgid "# peers connected" -msgstr "" - #: src/fs/gnunet-service-fs_cp.c:696 msgid "# migration stop messages received" msgstr "" @@ -2877,12 +2901,125 @@ msgstr "" msgid "Reply mismatched in terms of namespace. Discarded.\n" msgstr "" -#: src/gns/gns_api.c:221 -msgid "Failed to connect to the GNS service!\n" +#: src/gns/gnunet-gns.c:191 +msgid "Failed to connect to GNS\n" +msgstr "" + +#: src/gns/gnunet-gns.c:232 +msgid "try to shorten a given GNS name" +msgstr "" + +#: src/gns/gnunet-gns.c:235 +msgid "Lookup a record using GNS (NOT IMPLEMENTED)" +msgstr "" + +#: src/gns/gnunet-gns.c:238 +msgid "Get the authority of a particular name" +msgstr "" + +#: src/gns/gnunet-gns.c:241 +msgid "Specify the type of the record lookup" +msgstr "" + +#: src/gns/gnunet-gns.c:244 +msgid "No unneeded output" +msgstr "" + +#: src/gns/gnunet-gns.c:255 +msgid "GNUnet GNS access tool" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:280 +#, c-format +msgid "Unsupported form value `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:333 +#, c-format +msgid "Failed to create record for domain `%s': %s\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:377 +#, c-format +msgid "Found existing name `%s' for the given key\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:439 +#, c-format +msgid "Found %u existing records for domain `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:498 +#, c-format +msgid "Failed to create page for `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:514 +#, c-format +msgid "Failed to setup post processor for `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:725 src/gns/gnunet-gns-fcfsd.c:737 +#, c-format +msgid "Option `%s' not specified in configuration section `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:747 src/namestore/gnunet-namestore.c:299 +msgid "Failed to read or create private zone key\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:757 src/namestore/gnunet-namestore.c:310 +msgid "Failed to connect to namestore\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:773 src/gns/gnunet-gns-proxy.c:525 +msgid "Failed to start HTTP server\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:804 +msgid "GNUnet GNS first come first serve registration service" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:800 +msgid "listen on specified port" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:811 +msgid "GNUnet GNS proxy" +msgstr "" + +#: src/hello/gnunet-hello.c:122 +msgid "Call with name of HELLO file to modify.\n" +msgstr "" + +#: src/hello/gnunet-hello.c:128 +#, c-format +msgid "Error accessing file `%s': %s\n" +msgstr "" + +#: src/hello/gnunet-hello.c:136 +#, c-format +msgid "File `%s' is too big to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:143 +#, c-format +msgid "File `%s' is too small to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:153 src/hello/gnunet-hello.c:181 +#, c-format +msgid "Error opening file `%s': %s\n" +msgstr "" + +#: src/hello/gnunet-hello.c:169 +#, c-format +msgid "Did not find well-formed HELLO in file `%s'\n" msgstr "" -#: src/gns/gnunet-gns-lookup.c:210 -msgid "Issue a request to the GNUnet Naming System, prints results." +#: src/hello/gnunet-hello.c:193 +#, c-format +msgid "Error writing HELLO to file `%s': %s\n" msgstr "" #: src/hostlist/gnunet-daemon-hostlist.c:264 @@ -2913,190 +3050,190 @@ msgstr "" msgid "GNUnet hostlist server and client" msgstr "" -#: src/hostlist/hostlist-client.c:286 +#: src/hostlist/hostlist-client.c:289 msgid "# bytes downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:307 src/hostlist/hostlist-client.c:339 +#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:340 msgid "# invalid HELLOs downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:342 +#: src/hostlist/hostlist-client.c:313 src/hostlist/hostlist-client.c:343 #, c-format msgid "Invalid `%s' message received from hostlist at `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:330 +#: src/hostlist/hostlist-client.c:331 msgid "# valid HELLOs downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:374 src/hostlist/hostlist-client.c:395 +#: src/hostlist/hostlist-client.c:375 src/hostlist/hostlist-client.c:396 #, c-format msgid "No `%s' specified in `%s' configuration, will not bootstrap.\n" msgstr "" -#: src/hostlist/hostlist-client.c:472 src/hostlist/hostlist-client.c:682 -#: src/hostlist/hostlist-client.c:688 src/hostlist/hostlist-client.c:740 -#: src/hostlist/hostlist-client.c:749 src/hostlist/hostlist-client.c:877 -#: src/hostlist/hostlist-client.c:967 src/hostlist/hostlist-client.c:972 -#: src/transport/plugin_transport_http_client.c:108 -#: src/transport/plugin_transport_http_client.c:123 +#: src/hostlist/hostlist-client.c:473 src/hostlist/hostlist-client.c:683 +#: src/hostlist/hostlist-client.c:689 src/hostlist/hostlist-client.c:741 +#: src/hostlist/hostlist-client.c:750 src/hostlist/hostlist-client.c:871 +#: src/hostlist/hostlist-client.c:961 src/hostlist/hostlist-client.c:966 +#: src/transport/plugin_transport_http_client.c:110 +#: src/transport/plugin_transport_http_client.c:125 #, c-format msgid "%s failed at %s:%d: `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:592 src/hostlist/hostlist-client.c:1342 +#: src/hostlist/hostlist-client.c:593 src/hostlist/hostlist-client.c:1331 msgid "# advertised hostlist URIs" msgstr "" -#: src/hostlist/hostlist-client.c:622 +#: src/hostlist/hostlist-client.c:623 #, c-format msgid "# advertised URI `%s' downloaded" msgstr "" -#: src/hostlist/hostlist-client.c:663 +#: src/hostlist/hostlist-client.c:664 #, c-format msgid "" "Advertised hostlist with URI `%s' could not be downloaded. Advertised URI " "gets dismissed.\n" msgstr "" -#: src/hostlist/hostlist-client.c:805 +#: src/hostlist/hostlist-client.c:802 #, c-format msgid "Timeout trying to download hostlist from `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:822 +#: src/hostlist/hostlist-client.c:816 #, c-format msgid "Download limit of %u bytes exceeded, stopping download\n" msgstr "" -#: src/hostlist/hostlist-client.c:842 +#: src/hostlist/hostlist-client.c:836 #, c-format -msgid "%s failed for `%s' at %s:%d: `%s'\n" +msgid "Download of hostlist from `%s' failed: `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:848 +#: src/hostlist/hostlist-client.c:842 #, c-format msgid "Download of hostlist `%s' completed.\n" msgstr "" -#: src/hostlist/hostlist-client.c:856 +#: src/hostlist/hostlist-client.c:850 #, c-format msgid "Adding successfully tested hostlist `%s' datastore.\n" msgstr "" -#: src/hostlist/hostlist-client.c:909 +#: src/hostlist/hostlist-client.c:903 #, c-format msgid "Bootstrapping using hostlist at `%s'.\n" msgstr "" -#: src/hostlist/hostlist-client.c:917 +#: src/hostlist/hostlist-client.c:911 msgid "# hostlist downloads initiated" msgstr "" -#: src/hostlist/hostlist-client.c:1045 src/hostlist/hostlist-client.c:1515 +#: src/hostlist/hostlist-client.c:1037 src/hostlist/hostlist-client.c:1505 msgid "# milliseconds between hostlist downloads" msgstr "" -#: src/hostlist/hostlist-client.c:1054 +#: src/hostlist/hostlist-client.c:1046 #, c-format msgid "Have %u/%u connections. Will consider downloading hostlist in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1092 +#: src/hostlist/hostlist-client.c:1084 msgid "Scheduled saving of hostlists\n" msgstr "" -#: src/hostlist/hostlist-client.c:1096 +#: src/hostlist/hostlist-client.c:1088 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1119 src/hostlist/hostlist-client.c:1135 +#: src/hostlist/hostlist-client.c:1111 src/hostlist/hostlist-client.c:1127 msgid "# active connections" msgstr "" -#: src/hostlist/hostlist-client.c:1253 +#: src/hostlist/hostlist-client.c:1242 #, c-format msgid "Initial time between hostlist downloads is %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1284 +#: src/hostlist/hostlist-client.c:1273 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot load hostlists from file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1290 +#: src/hostlist/hostlist-client.c:1279 #, c-format msgid "Loading saved hostlist entries from file `%s' \n" msgstr "" -#: src/hostlist/hostlist-client.c:1294 +#: src/hostlist/hostlist-client.c:1283 #, c-format msgid "Hostlist file `%s' is not existing\n" msgstr "" -#: src/hostlist/hostlist-client.c:1305 +#: src/hostlist/hostlist-client.c:1294 #, c-format msgid "Could not open file `%s' for reading to load hostlists: %s\n" msgstr "" -#: src/hostlist/hostlist-client.c:1338 +#: src/hostlist/hostlist-client.c:1327 #, c-format msgid "%u hostlist URIs loaded from file\n" msgstr "" -#: src/hostlist/hostlist-client.c:1340 +#: src/hostlist/hostlist-client.c:1329 msgid "# hostlist URIs read from file" msgstr "" -#: src/hostlist/hostlist-client.c:1373 +#: src/hostlist/hostlist-client.c:1362 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot save hostlists to file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1387 +#: src/hostlist/hostlist-client.c:1376 #, c-format msgid "Could not open file `%s' for writing to save hostlists: %s\n" msgstr "" -#: src/hostlist/hostlist-client.c:1392 +#: src/hostlist/hostlist-client.c:1381 #, c-format msgid "Writing %u hostlist URIs to `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:1416 src/hostlist/hostlist-client.c:1433 +#: src/hostlist/hostlist-client.c:1405 src/hostlist/hostlist-client.c:1422 #, c-format msgid "Error writing hostlist URIs to file `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:1428 +#: src/hostlist/hostlist-client.c:1417 msgid "# hostlist URIs written to file" msgstr "" -#: src/hostlist/hostlist-client.c:1480 +#: src/hostlist/hostlist-client.c:1470 msgid "Learning is enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1483 +#: src/hostlist/hostlist-client.c:1473 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1492 +#: src/hostlist/hostlist-client.c:1482 msgid "Learning is not enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1504 +#: src/hostlist/hostlist-client.c:1494 #, c-format msgid "" "Since learning is not enabled on this peer, hostlist file `%s' was removed\n" msgstr "" -#: src/hostlist/hostlist-client.c:1508 +#: src/hostlist/hostlist-client.c:1498 #, c-format msgid "Hostlist file `%s' could not be removed\n" msgstr "" @@ -3109,8 +3246,10 @@ msgstr "" msgid "expired addresses encountered" msgstr "" -#: src/hostlist/hostlist-server.c:184 -#: src/topology/gnunet-daemon-topology.c:875 +#: src/hostlist/hostlist-server.c:184 src/hostlist/hostlist-server.c:425 +#: src/peerinfo-tool/gnunet-peerinfo.c:403 +#: src/peerinfo-tool/gnunet-peerinfo.c:519 +#: src/topology/gnunet-daemon-topology.c:927 #, c-format msgid "Error in communication with PEERINFO service: %s\n" msgstr "" @@ -3119,266 +3258,563 @@ msgstr "" msgid "HELLOs without addresses encountered (ignored)" msgstr "" -#: src/hostlist/hostlist-server.c:221 +#: src/hostlist/hostlist-server.c:219 msgid "bytes not included in hostlist (size limit)" msgstr "" -#: src/hostlist/hostlist-server.c:269 +#: src/hostlist/hostlist-server.c:263 #, c-format msgid "Refusing `%s' request to hostlist server\n" msgstr "" -#: src/hostlist/hostlist-server.c:272 +#: src/hostlist/hostlist-server.c:266 msgid "hostlist requests refused (not HTTP GET)" msgstr "" -#: src/hostlist/hostlist-server.c:280 +#: src/hostlist/hostlist-server.c:273 msgid "Sending 100 CONTINUE reply\n" msgstr "" -#: src/hostlist/hostlist-server.c:287 +#: src/hostlist/hostlist-server.c:279 #, c-format msgid "Refusing `%s' request with %llu bytes of upload data\n" msgstr "" -#: src/hostlist/hostlist-server.c:291 +#: src/hostlist/hostlist-server.c:283 msgid "hostlist requests refused (upload data)" msgstr "" -#: src/hostlist/hostlist-server.c:299 +#: src/hostlist/hostlist-server.c:291 msgid "Could not handle hostlist request since I do not have a response yet\n" msgstr "" -#: src/hostlist/hostlist-server.c:302 +#: src/hostlist/hostlist-server.c:294 msgid "hostlist requests refused (not ready)" msgstr "" -#: src/hostlist/hostlist-server.c:306 +#: src/hostlist/hostlist-server.c:298 msgid "Received request for our hostlist\n" msgstr "" -#: src/hostlist/hostlist-server.c:307 +#: src/hostlist/hostlist-server.c:299 msgid "hostlist requests processed" msgstr "" -#: src/hostlist/hostlist-server.c:350 +#: src/hostlist/hostlist-server.c:341 msgid "# hostlist advertisements send" msgstr "" -#: src/hostlist/hostlist-server.c:397 +#: src/hostlist/hostlist-server.c:388 msgid "Advertisement message could not be queued by core\n" msgstr "" -#: src/hostlist/hostlist-server.c:565 +#: src/hostlist/hostlist-server.c:561 #, c-format msgid "Invalid port number %llu. Exiting.\n" msgstr "" -#: src/hostlist/hostlist-server.c:574 +#: src/hostlist/hostlist-server.c:570 #, c-format msgid "Hostlist service starts on %s:%llu\n" msgstr "" -#: src/hostlist/hostlist-server.c:588 +#: src/hostlist/hostlist-server.c:584 #, c-format msgid "Address to obtain hostlist: `%s'\n" msgstr "" -#: src/hostlist/hostlist-server.c:626 +#: src/hostlist/hostlist-server.c:624 +#, c-format +msgid "`%s' is not a valid IP address! Ignoring BINDTOIP.\n" +msgstr "" + +#: src/hostlist/hostlist-server.c:666 #, c-format msgid "Could not start hostlist HTTP server on port %u\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4595 +#: src/integration-tests/connection_watchdog.c:997 +#, c-format +msgid "Transport plugin: `%s' port %llu\n" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1030 +#, c-format +msgid "Found %u transport plugins: `%s'\n" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1089 +msgid "Send ping messages to test connectivity (default == NO)" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1095 +#: src/template/gnunet-template.c:68 +msgid "help text" +msgstr "" + +#: src/mesh/gnunet-service-mesh.c:4590 msgid "Wrong CORE service\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4789 +#: src/mesh/gnunet-service-mesh.c:4784 msgid "Mesh service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4798 +#: src/mesh/gnunet-service-mesh.c:4793 msgid "Mesh service could not access hostkey. Exiting.\n" msgstr "" -#: src/namestore/namestore_api.c:272 src/namestore/namestore_api.c:313 -msgid "Namestore added record successfully" +#: src/mysql/mysql.c:174 +#, c-format +msgid "Trying to use file `%s' for MySQL configuration.\n" msgstr "" -#: src/namestore/namestore_api.c:281 src/namestore/namestore_api.c:322 -msgid "Namestore failed to add record" +#: src/mysql/mysql.c:181 +#, c-format +msgid "Could not access file `%s': %s\n" msgstr "" -#: src/nat/gnunet-nat-server.c:289 +#: src/namestore/gnunet-namestore.c:157 #, c-format -msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgid "Adding record failed: %s\n" msgstr "" -#: src/nat/gnunet-nat-server.c:328 -msgid "GNUnet NAT traversal test helper daemon" +#: src/namestore/gnunet-namestore.c:183 +#, c-format +msgid "Deleting record failed: %s\n" msgstr "" -#: src/nat/nat.c:803 +#: src/namestore/gnunet-namestore.c:239 #, c-format -msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgid "\tCorrupt or unsupported record of type %u\n" msgstr "" -#: src/nat/nat.c:852 +#: src/namestore/gnunet-namestore.c:276 #, c-format -msgid "Failed to start %s\n" +msgid "Option `%s' not given, but I need a zone key file!\n" msgstr "" -#: src/nat/nat.c:1121 +#: src/namestore/gnunet-namestore.c:281 #, c-format -msgid "Malformed %s `%s' given in configuration!\n" +msgid "Using default zone file `%s'\n" msgstr "" -#: src/nat/nat.c:1187 src/nat/nat.c:1197 +#: src/namestore/gnunet-namestore.c:291 #, c-format -msgid "" -"Configuration requires `%s', but binary is not installed properly (SUID bit " -"not set). Option disabled.\n" +msgid "No options given\n" msgstr "" -#: src/nat/nat.c:1329 -msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" +#: src/namestore/gnunet-namestore.c:321 +#, c-format +msgid "Unsupported type `%s'\n" msgstr "" -#: src/nat/nat.c:1341 +#: src/namestore/gnunet-namestore.c:328 src/namestore/gnunet-namestore.c:350 +#: src/namestore/gnunet-namestore.c:374 src/namestore/gnunet-namestore.c:384 +#: src/namestore/gnunet-namestore.c:409 #, c-format -msgid "Running gnunet-helper-nat-client %s %s %u\n" +msgid "Missing option `%s' for operation `%s'\n" msgstr "" -#: src/nat/nat_test.c:348 -msgid "Failed to connect to `gnunet-nat-server'\n" +#: src/namestore/gnunet-namestore.c:329 src/namestore/gnunet-namestore.c:351 +msgid "add/del" msgstr "" -#: src/nat/nat_test.c:418 +#: src/namestore/gnunet-namestore.c:341 #, c-format -msgid "Failed to create listen socket bound to `%s' for NAT test: %s\n" -msgstr "" - -#: src/nse/gnunet-nse-profiler.c:926 -msgid "Measure quality and performance of the NSE service." +msgid "Value `%s' invalid for record type `%s'\n" msgstr "" -#: src/nse/gnunet-service-nse.c:936 +#: src/namestore/gnunet-namestore.c:366 #, c-format -msgid "Proof of work invalid: %llu!\n" +msgid "Invalid time format `%s'\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1391 src/nse/gnunet-service-nse.c:1410 -#: src/nse/gnunet-service-nse.c:1431 -msgid "NSE service is lacking key configuration settings. Exiting.\n" +#: src/namestore/gnunet-namestore.c:375 src/namestore/gnunet-namestore.c:385 +msgid "add" msgstr "" -#: src/nse/gnunet-service-nse.c:1398 -msgid "Invalid work requirement for NSE service. Exiting.\n" +#: src/namestore/gnunet-namestore.c:410 +msgid "del" msgstr "" -#: src/nse/gnunet-service-nse.c:1419 -msgid "NSE service could not access hostkey. Exiting.\n" +#: src/namestore/gnunet-namestore.c:462 +msgid "add record" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:133 -#, c-format -msgid "Removing expired address of transport `%s'\n" +#: src/namestore/gnunet-namestore.c:465 +msgid "delete record" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:195 -msgid "# peers known" +#: src/namestore/gnunet-namestore.c:468 +msgid "display records" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:239 -#, c-format +#: src/namestore/gnunet-namestore.c:471 msgid "" -"File `%s' in directory `%s' does not match naming convention. Removed.\n" +"expiration time for record to use (for adding only), \"never\" is possible" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:305 -#, c-format -msgid "Still no peers found in `%s'!\n" +#: src/namestore/gnunet-namestore.c:474 +msgid "name of the record to add/delete/display" msgstr "" -#: src/peerinfo/peerinfo_api.c:279 -#, c-format -msgid "Failed to transmit message to `%s' service.\n" +#: src/namestore/gnunet-namestore.c:477 +msgid "type of the record to add/delete/display" msgstr "" -#: src/peerinfo/peerinfo_api.c:435 -msgid "Failed to receive response from `PEERINFO' service." +#: src/namestore/gnunet-namestore.c:480 +msgid "value of the record to add/delete" +msgstr "" + +#: src/namestore/gnunet-namestore.c:483 +msgid "create or list public record" msgstr "" -#: src/peerinfo/peerinfo_api.c:463 src/peerinfo/peerinfo_api.c:481 -msgid "Received invalid message from `PEERINFO' service.\n" +#: src/namestore/gnunet-namestore.c:486 +msgid "create or list non-authority record" msgstr "" -#: src/peerinfo/peerinfo_api.c:523 -msgid "Failed to transmit iteration request to `PEERINFO' service\n" +#: src/namestore/gnunet-namestore.c:489 +msgid "filename with the zone key" msgstr "" -#: src/peerinfo/peerinfo_api.c:557 -msgid "Timeout transmitting iteration request to `PEERINFO' service.\n" +#: src/namestore/gnunet-namestore.c:500 +msgid "GNUnet zone manipulation tool" msgstr "" -#: src/peerinfo/peerinfo_api_notify.c:258 +#: src/namestore/gnunet-service-namestore.c:143 #, c-format -msgid "Could not connect to `%s' service.\n" +msgid "File zone `%s' but corrupt content already exists, failed to write! \n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:216 +#: src/namestore/gnunet-service-namestore.c:154 #, c-format -msgid "Could not find option `%s:%s' in configuration.\n" +msgid "File zone `%s' containing this key already exists\n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:223 +#: src/namestore/gnunet-service-namestore.c:160 #, c-format -msgid "Loading hostkey from `%s' failed.\n" +msgid "" +"File zone `%s' but different zone key already exists, failed to write! \n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:235 +#: src/namestore/gnunet-service-namestore.c:198 #, c-format -msgid "I am peer `%s'.\n" +msgid "Stored zonekey for zone `%s' in file `%s'\n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:255 -msgid "output only the identity strings" +#: src/namestore/gnunet-service-namestore.c:1909 +msgid "No directory to load zonefiles specified in configuration\n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:258 -msgid "output our own identity only" +#: src/namestore/gnunet-service-namestore.c:1918 +#, c-format +msgid "Creating directory `%s' for zone files failed!\n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:264 -msgid "Print information about peers." +#: src/namestore/namestore_api.c:315 src/namestore/namestore_api.c:353 +msgid "Namestore added record successfully" msgstr "" -#: src/pt/gnunet-daemon-pt.c:264 -msgid "Failed to pack DNS request. Dropping.\n" +#: src/namestore/namestore_api.c:323 +msgid "Namestore failed to add record" msgstr "" -#: src/pt/gnunet-daemon-pt.c:270 -msgid "# DNS requests mapped to VPN" +#: src/namestore/namestore_api.c:361 +msgid "Namestore record already existed" msgstr "" -#: src/pt/gnunet-daemon-pt.c:323 -msgid "# DNS records modified" +#: src/namestore/namestore_api.c:368 +msgid "Namestore failed to add record\n" msgstr "" -#: src/pt/gnunet-daemon-pt.c:500 -msgid "# DNS replies intercepted" +#: src/namestore/namestore_api.c:401 +msgid "Namestore removed record successfully" msgstr "" -#: src/pt/gnunet-daemon-pt.c:506 -msgid "Failed to parse DNS request. Dropping.\n" +#: src/namestore/namestore_api.c:408 +msgid "No records for entry" msgstr "" -#: src/pt/gnunet-daemon-pt.c:602 -msgid "# DNS requests dropped (timeout)" +#: src/namestore/namestore_api.c:415 +msgid "Could not find record to remove" msgstr "" -#: src/pt/gnunet-daemon-pt.c:632 -msgid "# DNS requests intercepted" +#: src/namestore/namestore_api.c:422 +msgid "Failed to create new signature" +msgstr "" + +#: src/namestore/namestore_api.c:429 +msgid "Failed to put new set of records in database" +msgstr "" + +#: src/nat/gnunet-nat-server.c:279 +#, c-format +msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgstr "" + +#: src/nat/gnunet-nat-server.c:318 +msgid "GNUnet NAT traversal test helper daemon" +msgstr "" + +#: src/nat/nat.c:799 +#, c-format +msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgstr "" + +#: src/nat/nat.c:844 +#, c-format +msgid "Failed to start %s\n" +msgstr "" + +#: src/nat/nat.c:1111 +#, c-format +msgid "Malformed %s `%s' given in configuration!\n" +msgstr "" + +#: src/nat/nat.c:1177 src/nat/nat.c:1187 +#, c-format +msgid "" +"Configuration requires `%s', but binary is not installed properly (SUID bit " +"not set). Option disabled.\n" +msgstr "" + +#: src/nat/nat.c:1321 +msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" +msgstr "" + +#: src/nat/nat.c:1332 +#, c-format +msgid "Running gnunet-helper-nat-client %s %s %u\n" +msgstr "" + +#: src/nat/nat_test.c:341 +msgid "Failed to connect to `gnunet-nat-server'\n" +msgstr "" + +#: src/nat/nat_test.c:411 +#, c-format +msgid "Failed to create listen socket bound to `%s' for NAT test: %s\n" +msgstr "" + +#: src/nse/gnunet-nse-profiler.c:928 +msgid "Measure quality and performance of the NSE service." +msgstr "" + +#: src/nse/gnunet-service-nse.c:925 +#, c-format +msgid "Proof of work invalid: %llu!\n" +msgstr "" + +#: src/nse/gnunet-service-nse.c:1381 src/nse/gnunet-service-nse.c:1400 +#: src/nse/gnunet-service-nse.c:1421 +msgid "NSE service is lacking key configuration settings. Exiting.\n" +msgstr "" + +#: src/nse/gnunet-service-nse.c:1388 +msgid "Invalid work requirement for NSE service. Exiting.\n" +msgstr "" + +#: src/nse/gnunet-service-nse.c:1409 +msgid "NSE service could not access hostkey. Exiting.\n" +msgstr "" + +#: src/peerinfo/gnunet-service-peerinfo.c:134 +#, c-format +msgid "Removing expired address of transport `%s'\n" +msgstr "" + +#: src/peerinfo/gnunet-service-peerinfo.c:203 +#, c-format +msgid "Failed to parse HELLO in file `%s'\n" +msgstr "" + +#: src/peerinfo/gnunet-service-peerinfo.c:229 +msgid "# peers known" +msgstr "" + +#: src/peerinfo/gnunet-service-peerinfo.c:254 +#, c-format +msgid "" +"File `%s' in directory `%s' does not match naming convention. Removed.\n" +msgstr "" + +#: src/peerinfo/gnunet-service-peerinfo.c:353 +#, c-format +msgid "Still no peers found in `%s'!\n" +msgstr "" + +#: src/peerinfo/gnunet-service-peerinfo.c:710 +#, c-format +msgid "Importing HELLOs from `%s'\n" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:238 +msgid "aborted due to explicit disconnect request" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:358 +msgid "failed to transmit request (service down?)" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:505 +msgid "Failed to receive response from `PEERINFO' service." +msgstr "" + +#: src/peerinfo/peerinfo_api.c:531 src/peerinfo/peerinfo_api.c:550 +#: src/peerinfo/peerinfo_api.c:565 src/peerinfo/peerinfo_api.c:576 +#: src/peerinfo/peerinfo_api.c:587 +msgid "Received invalid message from `PEERINFO' service." +msgstr "" + +#: src/peerinfo/peerinfo_api.c:663 +msgid "Timeout transmitting iteration request to `PEERINFO' service." +msgstr "" + +#: src/peerinfo/peerinfo_api_notify.c:256 +#, c-format +msgid "Could not connect to `%s' service.\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:581 +msgid "Failed to parse HELLO message: missing expiration time\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:589 +msgid "Failed to parse HELLO message: invalid expiration time\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:598 +msgid "Failed to parse HELLO message: malformed\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:608 +msgid "Failed to parse HELLO message: missing transport plugin\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:625 +#, c-format +msgid "Plugin `%s' not found\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:634 +#, c-format +msgid "Plugin `%s' does not support URIs yet\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:653 +#, c-format +msgid "Failed to parse `%s' as an address for plugin `%s'\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:685 +#, c-format +msgid "Failure adding HELLO: %s\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:833 +#, c-format +msgid "Could not find option `%s:%s' in configuration.\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:840 +#, c-format +msgid "Loading hostkey from `%s' failed.\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:875 +#, c-format +msgid "Invalid URI `%s'\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:899 +#, c-format +msgid "I am peer `%s'.\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:936 +msgid "don't resolve host names" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:939 +msgid "output only the identity strings" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:942 +msgid "output our own identity only" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:945 +msgid "list all known peers" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:948 +msgid "also output HELLO uri(s)" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:951 +msgid "add given HELLO uri to the database" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:957 +msgid "Print information about peers." +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:105 +#: src/transport/gnunet-service-transport_plugins.c:118 +#, c-format +msgid "Starting transport plugins `%s'\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:109 +#: src/transport/gnunet-service-transport_plugins.c:122 +#, c-format +msgid "Loading `%s' transport plugin\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:129 +#: src/transport/gnunet-service-transport_plugins.c:150 +#, c-format +msgid "Failed to load transport plugin for `%s'\n" +msgstr "" + +#: src/postgres/postgres.c:59 +#, c-format +msgid "`%s:%s' failed at %s:%d with error: %s" +msgstr "" + +#: src/postgres/postgres.c:148 +#, c-format +msgid "Unable to initialize Postgres: %s" +msgstr "" + +#: src/pt/gnunet-daemon-pt.c:264 +msgid "Failed to pack DNS request. Dropping.\n" +msgstr "" + +#: src/pt/gnunet-daemon-pt.c:270 +msgid "# DNS requests mapped to VPN" +msgstr "" + +#: src/pt/gnunet-daemon-pt.c:323 +msgid "# DNS records modified" +msgstr "" + +#: src/pt/gnunet-daemon-pt.c:500 +msgid "# DNS replies intercepted" +msgstr "" + +#: src/pt/gnunet-daemon-pt.c:506 +msgid "Failed to parse DNS request. Dropping.\n" +msgstr "" + +#: src/pt/gnunet-daemon-pt.c:602 +msgid "# DNS requests dropped (timeout)" +msgstr "" + +#: src/pt/gnunet-daemon-pt.c:632 +msgid "# DNS requests intercepted" msgstr "" #: src/pt/gnunet-daemon-pt.c:637 @@ -3411,46 +3847,62 @@ msgstr "" msgid "Daemon to run to perform IP protocol translation to GNUnet" msgstr "" -#: src/statistics/gnunet-service-statistics.c:209 +#: src/statistics/gnunet-service-statistics.c:271 #, c-format msgid "Loading %llu bytes of statistics from `%s'\n" msgstr "" -#: src/statistics/gnunet-service-statistics.c:267 +#: src/statistics/gnunet-service-statistics.c:330 #, c-format msgid "Wrote %llu bytes of statistics to `%s'\n" msgstr "" -#: src/statistics/gnunet-statistics.c:98 +#: src/statistics/gnunet-statistics.c:122 msgid "Failed to obtain statistics.\n" msgstr "" -#: src/statistics/gnunet-statistics.c:164 +#: src/statistics/gnunet-statistics.c:199 +#, c-format +msgid "No subsystem or name given\n" +msgstr "" + +#: src/statistics/gnunet-statistics.c:207 +#, c-format +msgid "Failed to initialize watch routine\n" +msgstr "" + +#: src/statistics/gnunet-statistics.c:227 msgid "limit output to statistics for the given NAME" msgstr "" -#: src/statistics/gnunet-statistics.c:167 +#: src/statistics/gnunet-statistics.c:230 msgid "make the value being set persistent" msgstr "" -#: src/statistics/gnunet-statistics.c:170 +#: src/statistics/gnunet-statistics.c:233 msgid "limit output to the given SUBSYSTEM" msgstr "" -#: src/statistics/gnunet-statistics.c:173 +#: src/statistics/gnunet-statistics.c:236 msgid "just print the statistics value" msgstr "" -#: src/statistics/gnunet-statistics.c:180 +#: src/statistics/gnunet-statistics.c:239 +msgid "watch value continously" +msgstr "" + +#: src/statistics/gnunet-statistics.c:246 msgid "Print statistics about GNUnet operations." msgstr "" -#: src/statistics/statistics_api.c:390 -msgid "Failed to connect to statistics service!\n" +#: src/statistics/statistics_api.c:456 +msgid "Could not save some persistent statistics\n" msgstr "" -#: src/template/gnunet-template.c:68 -msgid "help text" +#: src/statistics/statistics_api.c:999 +msgid "" +"Failed to receive acknowledgement from statistics service, some statistics " +"might have been lost!\n" msgstr "" #: src/testing/gnunet-testing.c:157 @@ -3494,577 +3946,415 @@ msgstr "" msgid "Could not access hostkey.\n" msgstr "" -#: src/testing/testing.c:204 +#: src/testing/testing.c:200 msgid "`scp' does not seem to terminate (timeout copying config).\n" msgstr "" -#: src/testing/testing.c:218 src/testing/testing.c:808 +#: src/testing/testing.c:214 src/testing/testing.c:798 msgid "`scp' did not complete cleanly.\n" msgstr "" -#: src/testing/testing.c:239 +#: src/testing/testing.c:237 msgid "Failed to create pipe for `gnunet-peerinfo' process.\n" msgstr "" -#: src/testing/testing.c:240 +#: src/testing/testing.c:238 msgid "Failed to create pipe for `ssh' process.\n" msgstr "" -#: src/testing/testing.c:292 +#: src/testing/testing.c:286 #, c-format msgid "Could not start `%s' process to create hostkey.\n" msgstr "" -#: src/testing/testing.c:299 +#: src/testing/testing.c:293 msgid "Failed to start `gnunet-peerinfo' process.\n" msgstr "" -#: src/testing/testing.c:300 src/testing/testing.c:488 +#: src/testing/testing.c:294 src/testing/testing.c:471 msgid "Failed to start `ssh' process.\n" msgstr "" -#: src/testing/testing.c:360 +#: src/testing/testing.c:354 #, c-format msgid "Error reading from gnunet-peerinfo: %s\n" msgstr "" -#: src/testing/testing.c:364 +#: src/testing/testing.c:358 msgid "Malformed output from gnunet-peerinfo!\n" msgstr "" -#: src/testing/testing.c:374 +#: src/testing/testing.c:368 msgid "Failed to get hostkey!\n" msgstr "" -#: src/testing/testing.c:406 +#: src/testing/testing.c:400 msgid "`Failed while waiting for topology setup!\n" msgstr "" -#: src/testing/testing.c:480 +#: src/testing/testing.c:463 #, c-format msgid "Could not start `%s' process to start GNUnet.\n" msgstr "" -#: src/testing/testing.c:487 +#: src/testing/testing.c:470 msgid "Failed to start `gnunet-arm' process.\n" msgstr "" -#: src/testing/testing.c:509 src/testing/testing.c:612 +#: src/testing/testing.c:493 src/testing/testing.c:600 msgid "`gnunet-arm' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:510 src/testing/testing.c:613 -#: src/testing/testing.c:633 +#: src/testing/testing.c:494 src/testing/testing.c:601 +#: src/testing/testing.c:621 msgid "`ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:582 +#: src/testing/testing.c:570 msgid "Unable to get HELLO for peer!\n" msgstr "" -#: src/testing/testing.c:632 +#: src/testing/testing.c:620 msgid "`gnunet-arm' terminated with non-zero exit status (or timed out)!\n" msgstr "" -#: src/testing/testing.c:653 src/testing/testing.c:685 +#: src/testing/testing.c:643 src/testing/testing.c:675 msgid "either `gnunet-arm' or `ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:668 src/testing/testing.c:723 +#: src/testing/testing.c:658 src/testing/testing.c:713 msgid "shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n" msgstr "" -#: src/testing/testing.c:796 +#: src/testing/testing.c:786 msgid "`scp' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:966 +#: src/testing/testing.c:948 #, c-format msgid "Starting service %s for peer `%4s'\n" msgstr "" -#: src/testing/testing.c:1237 src/testing/testing_group.c:6278 +#: src/testing/testing.c:1207 src/testing/testing_group.c:6154 #, c-format msgid "Could not start `%s' process to copy configuration directory.\n" msgstr "" -#: src/testing/testing.c:1322 src/testing/testing.c:1397 +#: src/testing/testing.c:1292 src/testing/testing.c:1359 #, c-format msgid "Terminating peer `%4s'\n" msgstr "" -#: src/testing/testing.c:1480 +#: src/testing/testing.c:1448 #, c-format msgid "Setting d->dead on peer `%4s'\n" msgstr "" -#: src/testing/testing.c:1610 +#: src/testing/testing.c:1601 msgid "Peer not yet running, can not change configuration at this point." msgstr "" -#: src/testing/testing.c:1618 +#: src/testing/testing.c:1609 msgid "Failed to write new configuration to disk." msgstr "" -#: src/testing/testing.c:1647 +#: src/testing/testing.c:1636 #, c-format msgid "Could not start `%s' process to copy configuration file.\n" msgstr "" -#: src/testing/testing.c:1650 +#: src/testing/testing.c:1639 msgid "Failed to copy new configuration to remote machine." msgstr "" -#: src/testing/testing.c:1805 +#: src/testing/testing.c:1794 msgid "Peers failed to connect" msgstr "" -#: src/testing/testing.c:1933 +#: src/testing/testing.c:1922 msgid "Failed to connect to core service of first peer!\n" msgstr "" -#: src/testing/testing.c:2156 +#: src/testing/testing.c:2145 msgid "Peers are not fully running yet, can not connect!\n" msgstr "" -#: src/testing/testing_group.c:1910 src/testing/testing_group.c:1922 -#: src/testing/testing_group.c:2023 src/testing/testing_group.c:2082 -#: src/testing/testing_group.c:2171 src/testing/testing_group.c:2191 -#: src/testing/testing_group.c:2328 src/testing/testing_peergroup.c:940 +#: src/testing/testing_group.c:1895 src/testing/testing_group.c:1907 +#: src/testing/testing_group.c:2008 src/testing/testing_group.c:2065 +#: src/testing/testing_group.c:2152 src/testing/testing_group.c:2172 +#: src/testing/testing_group.c:2302 src/testing/testing_peergroup.c:950 #, c-format msgid "Invalid value `%s' for option `%s' in section `%s': expected float\n" msgstr "" -#: src/testing/testing_group.c:1932 -#, c-format -msgid "Target is %d connections per peer." -msgstr "" - -#: src/testing/testing_group.c:2179 +#: src/testing/testing_group.c:2160 #, c-format msgid "" "Invalid value `%s' for option `%s' in section `%s': got %f, needed value " "greater than 0\n" msgstr "" -#: src/testing/testing_group.c:2209 src/testing/testing_group.c:2402 -#, c-format -msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n" -msgstr "" - -#: src/testing/testing_group.c:2246 -#, c-format -msgid "natural log of %d is %d, will run %d iterations\n" -msgstr "" - -#: src/testing/testing_group.c:2249 -#, c-format -msgid "Total connections added thus far: %u!\n" -msgstr "" - -#: src/testing/testing_group.c:2290 -#, c-format -msgid "Total connections added for small world: %d!\n" -msgstr "" - -#: src/testing/testing_group.c:2342 -#, c-format -msgid "rand is %f probability is %f\n" -msgstr "" - -#: src/testing/testing_group.c:2919 src/testing/testing_group.c:3118 +#: src/testing/testing_group.c:2877 src/testing/testing_group.c:3063 #, c-format msgid "" "No `%s' specified in peer configuration in section `%s', cannot copy friends " "file!\n" msgstr "" -#: src/testing/testing_group.c:3020 -msgid "Finished copying all friend files!\n" -msgstr "" - -#: src/testing/testing_group.c:3133 -#, c-format -msgid "Copying file with command cp %s %s\n" +#: src/testing/testing_group.c:3957 +msgid "Creating no allowed topology (all peers can connect at core level)\n" msgstr "" -#: src/testing/testing_group.c:3156 -#, c-format -msgid "Copying file with command scp %s %s\n" +#: src/testing/testing_group.c:5226 +msgid "Unknown topology specification, can't connect peers!\n" msgstr "" -#: src/testing/testing_group.c:3173 -#, c-format -msgid "Checking copy status of file %d\n" +#: src/testing/testing_group.c:5944 src/transport/transport-testing.c:636 +msgid "Could not read hostkeys file!\n" msgstr "" -#: src/testing/testing_group.c:3191 +#: src/testing/testing_group.c:6011 #, c-format -msgid "File %d copied\n" -msgstr "" - -#: src/testing/testing_group.c:3206 -msgid "Finished copying all blacklist files!\n" +msgid "Could not create configuration for peer number %u on `%s'!\n" msgstr "" -#: src/testing/testing_group.c:3586 src/testing/testing_group.c:3723 -#: src/testing/testing_group.c:4884 src/testing/testing_group.c:5025 -msgid "Delaying connect, we have too many outstanding connections!\n" +#: src/testing/testing_new.c:169 +msgid "tmppath cannot be NULL\n" msgstr "" -#: src/testing/testing_group.c:3596 src/testing/testing_group.c:4894 -#: src/testing/testing_group.c:5035 +#: src/testing/testing_new.c:356 #, c-format -msgid "Creating connection, outstanding_connections is %d\n" +msgid "Hostkeys file not found: %s\n" msgstr "" -#: src/testing/testing_group.c:3608 +#: src/testing/testing_new.c:365 #, c-format -msgid "Offering HELLO of peer %s to peer %s\n" +msgid "Could not open hostkeys file: %s\n" msgstr "" -#: src/testing/testing_group.c:3734 +#: src/testing/testing_new.c:380 #, c-format -msgid "Creating connection, outstanding_connections is %d (max %d)\n" -msgstr "" - -#: src/testing/testing_group.c:3988 -msgid "Creating clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:3993 -msgid "Creating small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:3998 -msgid "Creating small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4002 -msgid "Creating ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4006 -msgid "Creating 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4010 -msgid "Creating Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4014 -msgid "Creating InterNAT topology\n" -msgstr "" - -#: src/testing/testing_group.c:4018 -msgid "Creating Scale Free topology\n" -msgstr "" - -#: src/testing/testing_group.c:4023 -msgid "Creating straight line topology\n" -msgstr "" - -#: src/testing/testing_group.c:4027 -msgid "Creating topology from file!\n" -msgstr "" - -#: src/testing/testing_group.c:4043 -msgid "Creating no allowed topology (all peers can connect at core level)\n" -msgstr "" - -#: src/testing/testing_group.c:4058 -msgid "Failed during friend file copying!\n" -msgstr "" - -#: src/testing/testing_group.c:4064 -msgid "Friend files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:4081 -msgid "Blacklisting all but clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:4087 -msgid "Blacklisting all but small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4093 -msgid "Blacklisting all but small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4099 -msgid "Blacklisting all but ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4105 -msgid "Blacklisting all but 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4111 -msgid "Blacklisting all but Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4117 -msgid "Blacklisting all but InterNAT topology\n" -msgstr "" - -#: src/testing/testing_group.c:4152 -msgid "Blacklisting all but Scale Free topology\n" +msgid "Incorrect hostkey file format: %s\n" msgstr "" -#: src/testing/testing_group.c:4158 -msgid "Blacklisting all but straight line topology\n" -msgstr "" - -#: src/testing/testing_group.c:4173 -msgid "Failed during blacklist file copying!\n" -msgstr "" - -#: src/testing/testing_group.c:4179 -msgid "Blacklist files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:5263 -msgid "Creating clique CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5270 -msgid "Creating small world (ring) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5277 -msgid "Creating small world (2d-torus) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5283 -msgid "Creating ring CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5290 -msgid "Creating 2d torus CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5297 -msgid "Creating Erdos-Renyi CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5304 -msgid "Creating InterNAT CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5311 -msgid "Creating Scale Free CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5318 -msgid "Creating straight line CONNECT topology\n" +#: src/testing/testing_new.c:437 +#, c-format +msgid "Key number %u does not exist\n" msgstr "" -#: src/testing/testing_group.c:5324 -msgid "Creating no CONNECT topology\n" +#: src/testing/testing_new.c:446 +#, c-format +msgid "Error while decoding key %u\n" msgstr "" -#: src/testing/testing_group.c:5330 -msgid "Unknown topology specification, can't connect peers!\n" +#: src/testing/testing_new.c:680 +msgid "Failed to create configuration for peer (not enough free ports?)\n" msgstr "" -#: src/testing/testing_group.c:5340 +#: src/testing/testing_new.c:691 #, c-format -msgid "Connecting random subset (%'.2f percent) of possible peers\n" +msgid "" +"You attempted to create a testbed with more than %u hosts. Please " +"precompute more hostkeys first.\n" msgstr "" -#: src/testing/testing_group.c:5348 +#: src/testing/testing_new.c:704 #, c-format -msgid "Connecting a minimum of %u peers each (if possible)\n" +msgid "Failed to initialize hostkey for peer %u\n" msgstr "" -#: src/testing/testing_group.c:5357 +#: src/testing/testing_new.c:734 #, c-format -msgid "Using DFS to connect a minimum of %u peers each (if possible)\n" +msgid "Failed to write hostkey file for peer %u: %s\n" msgstr "" -#: src/testing/testing_group.c:5367 +#: src/testing/testing_new.c:751 #, c-format -msgid "Finding additional %u closest peers each (if possible)\n" +msgid "Failed to write configuration file `%s' for peer %u: %s\n" msgstr "" -#: src/testing/testing_group.c:6062 src/transport/transport-testing.c:650 -msgid "Could not read hostkeys file!\n" +#: src/testing/testing_new.c:791 +#, c-format +msgid "Failed to start `%s': %s\n" msgstr "" -#: src/testing/testing_group.c:6131 +#: src/testing/testing_new.c:959 #, c-format -msgid "Could not create configuration for peer number %u on `%s'!\n" +msgid "Failed to load configuration from %s\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:244 +#: src/topology/gnunet-daemon-topology.c:259 msgid "# peers blacklisted" msgstr "" -#: src/topology/gnunet-daemon-topology.c:380 +#: src/topology/gnunet-daemon-topology.c:392 msgid "# connect requests issued to transport" msgstr "" -#: src/topology/gnunet-daemon-topology.c:675 -#: src/topology/gnunet-daemon-topology.c:761 +#: src/topology/gnunet-daemon-topology.c:730 +#: src/topology/gnunet-daemon-topology.c:815 msgid "# friends connected" msgstr "" -#: src/topology/gnunet-daemon-topology.c:950 +#: src/topology/gnunet-daemon-topology.c:996 msgid "Failed to connect to core service, can not manage topology!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:982 +#: src/topology/gnunet-daemon-topology.c:1026 #, c-format msgid "Option `%s' in section `%s' not specified!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:994 +#: src/topology/gnunet-daemon-topology.c:1039 #, c-format msgid "Could not read friends list `%s'\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1000 +#: src/topology/gnunet-daemon-topology.c:1045 #, c-format msgid "Friends file `%s' is empty.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1009 +#: src/topology/gnunet-daemon-topology.c:1054 #, c-format msgid "Failed to read friends list from `%s': out of memory\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1017 +#: src/topology/gnunet-daemon-topology.c:1062 #, c-format msgid "Failed to read friends list from `%s'\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1037 +#: src/topology/gnunet-daemon-topology.c:1082 #, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1050 +#: src/topology/gnunet-daemon-topology.c:1095 #, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1060 +#: src/topology/gnunet-daemon-topology.c:1105 #, c-format msgid "Found friend `%s' in configuration\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1066 +#: src/topology/gnunet-daemon-topology.c:1111 #, c-format msgid "Found myself `%s' in friend list (useless, ignored)\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1076 +#: src/topology/gnunet-daemon-topology.c:1121 msgid "# friends in configuration" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1082 +#: src/topology/gnunet-daemon-topology.c:1127 msgid "" "Fewer friends specified than required by minimum friend count. Will only " "connect to friends.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1089 +#: src/topology/gnunet-daemon-topology.c:1134 msgid "" "More friendly connections required than target total number of connections.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1126 +#: src/topology/gnunet-daemon-topology.c:1169 msgid "# HELLO messages received" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1183 +#: src/topology/gnunet-daemon-topology.c:1224 msgid "# HELLO messages gossipped" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1323 +#: src/topology/gnunet-daemon-topology.c:1363 msgid "GNUnet topology control (maintaining P2P mesh and F2F constraints)" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:247 +#: src/transport/gnunet-service-transport_blacklist.c:246 #, c-format msgid "Could not read blacklist file `%s'\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:254 +#: src/transport/gnunet-service-transport_blacklist.c:252 #, c-format msgid "Blacklist file `%s' is empty.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:266 +#: src/transport/gnunet-service-transport_blacklist.c:263 #, c-format msgid "Failed to read blacklist from `%s'\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:287 -#: src/transport/gnunet-service-transport_blacklist.c:311 +#: src/transport/gnunet-service-transport_blacklist.c:284 +#: src/transport/gnunet-service-transport_blacklist.c:308 #, c-format msgid "Syntax error in blacklist file at offset %llu, giving up!\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:298 -#: src/transport/gnunet-service-transport_blacklist.c:336 +#: src/transport/gnunet-service-transport_blacklist.c:295 +#: src/transport/gnunet-service-transport_blacklist.c:331 #, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:350 +#: src/transport/gnunet-service-transport_blacklist.c:345 #, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:364 +#: src/transport/gnunet-service-transport_blacklist.c:359 #, c-format msgid "Found myself `%s' in blacklist (useless, ignored)\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:523 -#: src/transport/gnunet-service-transport_blacklist.c:764 +#: src/transport/gnunet-service-transport_blacklist.c:514 +#: src/transport/gnunet-service-transport_blacklist.c:747 msgid "# disconnects due to blacklist" msgstr "" -#: src/transport/gnunet-service-transport.c:158 +#: src/transport/gnunet-service-transport.c:163 msgid "# bytes payload discarded due to not connected peer " msgstr "" -#: src/transport/gnunet-service-transport.c:572 +#: src/transport/gnunet-service-transport.c:237 +msgid "# bytes total received" +msgstr "" + +#: src/transport/gnunet-service-transport.c:284 +msgid "# bytes payload received" +msgstr "" + +#: src/transport/gnunet-service-transport.c:582 msgid "Transport service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport.c:581 +#: src/transport/gnunet-service-transport.c:591 msgid "Transport service could not access hostkey. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:353 +#: src/transport/gnunet-service-transport_clients.c:352 #, c-format msgid "Dropping message of type %u and size %u, have %u/%u messages pending\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:358 +#: src/transport/gnunet-service-transport_clients.c:357 msgid "# messages dropped due to slow client" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:510 +#: src/transport/gnunet-service-transport_clients.c:503 #, c-format msgid "Rejecting control connection from peer `%s', which is not me!\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:628 -msgid "# bytes payload received for other peers" -msgstr "" - -#: src/transport/gnunet-service-transport_clients.c:645 +#: src/transport/gnunet-service-transport_clients.c:631 msgid "# bytes payload dropped (other peer was not connected)" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:696 +#: src/transport/gnunet-service-transport_clients.c:682 msgid "# REQUEST CONNECT messages received" msgstr "" @@ -4072,568 +4362,515 @@ msgstr "" msgid "# refreshed my HELLO" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:482 -msgid "# failed connection attempts due to timeout" +#: src/transport/gnunet-service-transport_neighbours.c:1032 +msgid "# DISCONNECT messages sent" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:883 -msgid "# peers disconnected due to external request" +#: src/transport/gnunet-service-transport_neighbours.c:1148 +#: src/transport/gnunet-service-transport_neighbours.c:1482 +msgid "# bytes in message queue for other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:966 -msgid "# fast reconnects failed" +#: src/transport/gnunet-service-transport_neighbours.c:1153 +msgid "# messages transmitted to other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1022 -msgid "# peers disconnected due to timeout" +#: src/transport/gnunet-service-transport_neighbours.c:1158 +msgid "# transmission failures for messages to other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1047 +#: src/transport/gnunet-service-transport_neighbours.c:1215 +msgid "# messages timed out while in transport queue" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:1254 msgid "# keepalives sent" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1088 -msgid "# peers disconnected due to global disconnect" +#: src/transport/gnunet-service-transport_neighbours.c:1278 +msgid "# KEEPALIVE messages discarded (peer unknown)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1888 -#: src/transport/gnunet-service-transport_neighbours.c:1909 -msgid "# messages not sent (no such peer or not connected)" +#: src/transport/gnunet-service-transport_neighbours.c:1286 +msgid "# KEEPALIVE messages discarded (no session)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1925 -msgid "# bytes in message queue for other peers" +#: src/transport/gnunet-service-transport_neighbours.c:1323 +msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1977 +#: src/transport/gnunet-service-transport_neighbours.c:1332 +msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:1388 msgid "# messages discarded due to lack of neighbour record" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2013 +#: src/transport/gnunet-service-transport_neighbours.c:1422 msgid "# bandwidth quota violations by other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2031 +#: src/transport/gnunet-service-transport_neighbours.c:1438 msgid "# ms throttling suggested" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2060 -msgid "# KEEPALIVE messages discarded (not connected)" +#: src/transport/gnunet-service-transport_neighbours.c:2544 +msgid "# unexpected CONNECT_ACK messages (no peer)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2113 -msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" +#: src/transport/gnunet-service-transport_neighbours.c:2559 +#: src/transport/gnunet-service-transport_neighbours.c:2585 +msgid "# unexpected CONNECT_ACK messages (not ready)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2121 -msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" +#: src/transport/gnunet-service-transport_neighbours.c:2598 +msgid "# unexpected CONNECT_ACK messages (waiting on ATS)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2187 +#: src/transport/gnunet-service-transport_neighbours.c:2627 +msgid "# unexpected CONNECT_ACK messages (disconnecting)" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:2807 +msgid "# unexpected SESSION ACK messages" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:2856 msgid "# SET QUOTA messages ignored (no such peer)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2205 +#: src/transport/gnunet-service-transport_neighbours.c:2870 msgid "# disconnects due to quota of 0" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2323 +#: src/transport/gnunet-service-transport_neighbours.c:2901 msgid "# disconnect messages ignored (old format)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2336 +#: src/transport/gnunet-service-transport_neighbours.c:2912 msgid "# disconnect messages ignored (timestamp)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2411 -msgid "# unexpected CONNECT_ACK messages (no peer)" -msgstr "" - -#: src/transport/gnunet-service-transport_neighbours.c:2453 -msgid "# unexpected CONNECT_ACK messages" +#: src/transport/gnunet-service-transport_neighbours.c:2943 +msgid "# other peer asked to disconnect from us" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2544 -msgid "# unexpected ACK messages" +#: src/transport/gnunet-service-transport_neighbours.c:3020 +msgid "# disconnected from peer upon explicit request" msgstr "" #: src/transport/gnunet-service-transport_plugins.c:111 msgid "Transport service is lacking NEIGHBOUR_LIMIT option.\n" msgstr "" -#: src/transport/gnunet-service-transport_plugins.c:118 -#, c-format -msgid "Starting transport plugins `%s'\n" -msgstr "" - -#: src/transport/gnunet-service-transport_plugins.c:122 -#, c-format -msgid "Loading `%s' transport plugin\n" -msgstr "" - -#: src/transport/gnunet-service-transport_plugins.c:150 -#, c-format -msgid "Failed to load transport plugin for `%s'\n" -msgstr "" - -#: src/transport/gnunet-service-transport_validation.c:410 +#: src/transport/gnunet-service-transport_validation.c:414 msgid "# address records discarded" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:459 +#: src/transport/gnunet-service-transport_validation.c:463 #, c-format msgid "" "Not transmitting `%s' with `%s', message too big (%u bytes!). This should " "not happen.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:508 +#: src/transport/gnunet-service-transport_validation.c:512 msgid "# PING without HELLO messages sent" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:566 +#: src/transport/gnunet-service-transport_validation.c:570 msgid "# address revalidations started" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:798 +#: src/transport/gnunet-service-transport_validation.c:805 msgid "# PING message for different peer received" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:833 +#: src/transport/gnunet-service-transport_validation.c:840 #, c-format msgid "" "Not confirming PING with address `%s' since I cannot confirm having this " "address.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:919 +#: src/transport/gnunet-service-transport_validation.c:924 msgid "# PONGs unicast via reliable transport" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:928 +#: src/transport/gnunet-service-transport_validation.c:933 msgid "# PONGs multicast to all available addresses" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1050 +#: src/transport/gnunet-service-transport_validation.c:1055 msgid "# PONGs dropped, no matching pending validation" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1075 +#: src/transport/gnunet-service-transport_validation.c:1080 msgid "# PONGs dropped, signature expired" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1134 +#: src/transport/gnunet-service-transport_validation.c:1136 #, c-format msgid "Adding `%s' without addresses for peer `%s'\n" msgstr "" -#: src/transport/gnunet-transport.c:256 +#: src/transport/gnunet-transport.c:260 msgid "No transport plugins configured, peer will never communicate\n" msgstr "" -#: src/transport/gnunet-transport.c:269 +#: src/transport/gnunet-transport.c:273 #, c-format msgid "No port configured for plugin `%s', cannot test it\n" msgstr "" -#: src/transport/gnunet-transport.c:319 +#: src/transport/gnunet-transport.c:323 #, c-format msgid "Received %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:326 +#: src/transport/gnunet-transport.c:330 #, c-format msgid "Transmitted %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:359 +#: src/transport/gnunet-transport.c:363 #, c-format msgid "Transmitting %u bytes to %s\n" msgstr "" -#: src/transport/gnunet-transport.c:379 +#: src/transport/gnunet-transport.c:383 #, c-format msgid "Connected to %s\n" msgstr "" -#: src/transport/gnunet-transport.c:410 +#: src/transport/gnunet-transport.c:414 #, c-format msgid "Disconnected from %s\n" msgstr "" -#: src/transport/gnunet-transport.c:439 +#: src/transport/gnunet-transport.c:443 #, c-format msgid "Received %u bytes from %s\n" msgstr "" -#: src/transport/gnunet-transport.c:453 +#: src/transport/gnunet-transport.c:466 #, c-format msgid "Peer `%s': %s %s\n" msgstr "" -#: src/transport/gnunet-transport.c:483 +#: src/transport/gnunet-transport.c:473 +#, c-format +msgid "Peer `%s': %s \n" +msgstr "" + +#: src/transport/gnunet-transport.c:501 #, c-format msgid "Peer `%s' disconnected\n" msgstr "" -#: src/transport/gnunet-transport.c:539 +#: src/transport/gnunet-transport.c:569 #, c-format msgid "Failed to parse peer identity `%s'\n" msgstr "" -#: src/transport/gnunet-transport.c:587 +#: src/transport/gnunet-transport.c:618 msgid "measure how fast we are receiving data (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:590 +#: src/transport/gnunet-transport.c:621 msgid "try to connect to the given peer" msgstr "" -#: src/transport/gnunet-transport.c:593 +#: src/transport/gnunet-transport.c:624 msgid "provide information about all current connections (once)" msgstr "" -#: src/transport/gnunet-transport.c:596 +#: src/transport/gnunet-transport.c:627 msgid "provide information about all current connections (continuously)" msgstr "" -#: src/transport/gnunet-transport.c:599 +#: src/transport/gnunet-transport.c:630 msgid "do not resolve hostnames" msgstr "" -#: src/transport/gnunet-transport.c:603 +#: src/transport/gnunet-transport.c:634 msgid "send data for benchmarking to the other peer (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:606 +#: src/transport/gnunet-transport.c:637 msgid "test transport configuration (involves external server)" msgstr "" -#: src/transport/gnunet-transport.c:614 +#: src/transport/gnunet-transport.c:645 msgid "Direct access to transport service." msgstr "" -#: src/transport/plugin_transport_http.c:981 +#: src/transport/plugin_transport_http.c:1100 msgid "Disabling IPv6 since it is not supported on this system!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1029 +#: src/transport/plugin_transport_http.c:1149 msgid "Require valid port number for service in configuration!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1054 src/util/service.c:986 +#: src/transport/plugin_transport_http.c:1174 src/util/service.c:1036 #, c-format msgid "Failed to resolve `%s': %s\n" msgstr "" -#: src/transport/plugin_transport_http.c:1071 src/util/service.c:1003 +#: src/transport/plugin_transport_http.c:1191 src/util/service.c:1053 #, c-format msgid "Failed to find %saddress for `%s'.\n" msgstr "" -#: src/transport/plugin_transport_http.c:1176 +#: src/transport/plugin_transport_http.c:1296 #, c-format msgid "Found %u addresses to report to NAT service\n" msgstr "" -#: src/transport/plugin_transport_http.c:1189 +#: src/transport/plugin_transport_http.c:1309 #, c-format msgid "FREEING %s\n" msgstr "" -#: src/transport/plugin_transport_http.c:1264 +#: src/transport/plugin_transport_http.c:1386 msgid "Neither IPv4 nor IPv6 are enabled! Fix in configuration\n" msgstr "" -#: src/transport/plugin_transport_http.c:1277 +#: src/transport/plugin_transport_http.c:1399 msgid "Port is required! Fix in configuration\n" msgstr "" -#: src/transport/plugin_transport_http.c:1288 +#: src/transport/plugin_transport_http.c:1410 msgid "Port 0, client only mode\n" msgstr "" -#: src/transport/plugin_transport_http.c:1308 +#: src/transport/plugin_transport_http.c:1430 #, c-format msgid "" "Specific IPv4 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1338 +#: src/transport/plugin_transport_http.c:1460 #, c-format msgid "" "Specific IPv6 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http_client.c:621 +#: src/transport/plugin_transport_http_client.c:624 #, c-format msgid "Could not initialize curl multi handle, failed to start %s plugin!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:189 +#: src/transport/plugin_transport_http_server.c:178 msgid "" "Could not create a new TLS certificate, program `gnunet-transport-" "certificate-creation' could not be started!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:213 +#: src/transport/plugin_transport_http_server.c:202 msgid "No usable TLS certificate found and creating one failed!\n" msgstr "" -#: src/transport/plugin_transport_smtp.c:370 -#, c-format -msgid "Received malformed message via %s. Ignored.\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:457 -msgid "SMTP filter string to invalid, lacks ': '\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:466 -#, c-format -msgid "SMTP filter string to long, capped to `%s'\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:561 -#: src/transport/plugin_transport_smtp.c:571 -#: src/transport/plugin_transport_smtp.c:584 -#: src/transport/plugin_transport_smtp.c:603 -#: src/transport/plugin_transport_smtp.c:626 -#: src/transport/plugin_transport_smtp.c:634 -#: src/transport/plugin_transport_smtp.c:647 -#: src/transport/plugin_transport_smtp.c:658 -#, c-format -msgid "SMTP: `%s' failed: %s.\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:801 -msgid "No email-address specified, can not start SMTP transport.\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:813 -msgid "# bytes received via SMTP" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:814 -msgid "# bytes sent via SMTP" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:816 -msgid "# bytes dropped by SMTP (outgoing)" -msgstr "" - -#: src/transport/plugin_transport_tcp.c:512 +#: src/transport/plugin_transport_tcp.c:591 #, c-format msgid "Unexpected address length: %u bytes\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:616 -#: src/transport/plugin_transport_tcp.c:705 -#: src/transport/plugin_transport_tcp.c:757 -#: src/transport/plugin_transport_tcp.c:830 -#: src/transport/plugin_transport_tcp.c:909 +#: src/transport/plugin_transport_tcp.c:767 +#: src/transport/plugin_transport_tcp.c:856 +#: src/transport/plugin_transport_tcp.c:906 +#: src/transport/plugin_transport_tcp.c:992 +#: src/transport/plugin_transport_tcp.c:1086 +#: src/transport/plugin_transport_tcp.c:1103 msgid "# bytes currently in TCP buffers" msgstr "" -#: src/transport/plugin_transport_tcp.c:622 -#: src/transport/plugin_transport_tcp.c:856 -#: src/transport/plugin_transport_tcp.c:1561 +#: src/transport/plugin_transport_tcp.c:774 +#: src/transport/plugin_transport_tcp.c:963 +#: src/transport/plugin_transport_tcp.c:1761 +#: src/transport/plugin_transport_tcp.c:2390 msgid "# TCP sessions active" msgstr "" -#: src/transport/plugin_transport_tcp.c:709 +#: src/transport/plugin_transport_tcp.c:860 msgid "# bytes discarded by TCP (timeout)" msgstr "" -#: src/transport/plugin_transport_tcp.c:760 +#: src/transport/plugin_transport_tcp.c:909 msgid "# bytes transmitted via TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:834 +#: src/transport/plugin_transport_tcp.c:996 msgid "# bytes discarded by TCP (disconnect)" msgstr "" -#: src/transport/plugin_transport_tcp.c:1081 +#: src/transport/plugin_transport_tcp.c:1290 #, c-format msgid "Address of unexpected length: %u\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1116 -msgid "Found valid IPv4 NAT address (creating session)!\n" -msgstr "" - -#: src/transport/plugin_transport_tcp.c:1186 +#: src/transport/plugin_transport_tcp.c:1401 msgid "# transport-service disconnect requests for TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:1603 +#: src/transport/plugin_transport_tcp.c:1802 msgid "# TCP WELCOME messages received" msgstr "" -#: src/transport/plugin_transport_tcp.c:1756 +#: src/transport/plugin_transport_tcp.c:1973 msgid "# bytes received via TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:1823 +#: src/transport/plugin_transport_tcp.c:2043 msgid "# network-level TCP disconnect events" msgstr "" -#: src/transport/plugin_transport_tcp.c:1962 src/util/service.c:889 +#: src/transport/plugin_transport_tcp.c:2279 src/util/service.c:940 #, c-format msgid "Require valid port number for service `%s' in configuration!\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1976 +#: src/transport/plugin_transport_tcp.c:2293 msgid "Failed to start service.\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2039 +#: src/transport/plugin_transport_tcp.c:2355 #, c-format msgid "Failed to find option %s in section %s!\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2062 +#: src/transport/plugin_transport_tcp.c:2378 #, c-format msgid "TCP transport listening on port %llu\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2066 +#: src/transport/plugin_transport_tcp.c:2382 msgid "TCP transport not listening on any port (client only)\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2070 +#: src/transport/plugin_transport_tcp.c:2386 #, c-format msgid "TCP transport advertises itself as being on port %llu\n" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:130 +#: src/transport/plugin_transport_udp_broadcasting.c:128 msgid "# IPv6 multicast HELLO beacons received via udp" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:172 +#: src/transport/plugin_transport_udp_broadcasting.c:169 msgid "# IPv4 broadcast HELLO beacons received via udp" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:393 +#: src/transport/plugin_transport_udp_broadcasting.c:367 #, c-format msgid "Failed to set IPv4 broadcast option for broadcast socket on port %d\n" msgstr "" -#: src/transport/plugin_transport_udp.c:1985 +#: src/transport/plugin_transport_udp.c:1894 +#, c-format +msgid "" +"UDP could not message to `%s': `%s'. Please check your network configuration " +"and disable IPv6 if your connection does not have a global IPv6 address\n" +msgstr "" + +#: src/transport/plugin_transport_udp.c:2138 msgid "Failed to open UDP sockets\n" msgstr "" -#: src/transport/plugin_transport_udp.c:2068 +#: src/transport/plugin_transport_udp.c:2306 #, c-format msgid "Given `%s' option is out of range: %llu > %u\n" msgstr "" -#: src/transport/plugin_transport_udp.c:2112 +#: src/transport/plugin_transport_udp.c:2349 #, c-format msgid "Invalid IPv6 address: `%s'\n" msgstr "" -#: src/transport/plugin_transport_unix.c:1051 +#: src/transport/plugin_transport_unix.c:1356 msgid "Failed to open UNIX sockets\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:875 -msgid "# wlan session timeouts" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:899 -msgid "# wlan session created" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:980 -#: src/transport/plugin_transport_wlan.c:1138 -#: src/transport/plugin_transport_wlan.c:1159 -#: src/transport/plugin_transport_wlan.c:1190 -#: src/transport/plugin_transport_wlan.c:2334 -#: src/transport/plugin_transport_wlan.c:3142 -msgid "# wlan pending sessions" +#: src/transport/plugin_transport_wlan.c:561 +msgid "# WLAN ACKs sent" msgstr "" -#: src/transport/plugin_transport_wlan.c:1233 -#: src/transport/plugin_transport_wlan.c:1888 -msgid "# wlan pending fragments" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:1388 -#, c-format -msgid "" -"Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n" +#: src/transport/plugin_transport_wlan.c:580 +msgid "# WLAN messages defragmented" msgstr "" -#: src/transport/plugin_transport_wlan.c:1732 -msgid "# wlan hello beacons send" +#: src/transport/plugin_transport_wlan.c:626 +#: src/transport/plugin_transport_wlan.c:676 +#: src/transport/plugin_transport_wlan.c:1696 +msgid "# WLAN sessions allocated" msgstr "" -#: src/transport/plugin_transport_wlan.c:1765 -#: src/transport/plugin_transport_wlan.c:1968 -#: src/transport/plugin_transport_wlan.c:2059 -#, c-format -msgid "Error writing to wlan helper. errno == %d, ERROR: %s\n" +#: src/transport/plugin_transport_wlan.c:749 +msgid "# WLAN message fragments sent" msgstr "" -#: src/transport/plugin_transport_wlan.c:1954 -msgid "# wlan acks send" +#: src/transport/plugin_transport_wlan.c:767 +msgid "# WLAN messages pending (with fragmentation)" msgstr "" -#: src/transport/plugin_transport_wlan.c:2025 -msgid "# wlan fragments send" +#: src/transport/plugin_transport_wlan.c:867 +#: src/transport/plugin_transport_wlan.c:948 +#: src/transport/plugin_transport_wlan.c:1698 +msgid "# WLAN MAC endpoints allocated" msgstr "" -#: src/transport/plugin_transport_wlan.c:2161 -#, c-format -msgid "Wlan Address len %d is wrong\n" +#: src/transport/plugin_transport_wlan.c:1119 +msgid "# HELLO messages received via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2295 -#: src/transport/plugin_transport_wlan.c:2919 -#: src/transport/plugin_transport_wlan.c:3145 -msgid "# wlan mac endpoints" +#: src/transport/plugin_transport_wlan.c:1140 +msgid "# fragments received via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2517 -msgid "# wlan whole messages received" +#: src/transport/plugin_transport_wlan.c:1150 +msgid "# ACKs received via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2708 -msgid "# wlan hello messages received" +#: src/transport/plugin_transport_wlan.c:1207 +msgid "# WLAN DATA messages discarded due to CRC32 error" msgstr "" -#: src/transport/plugin_transport_wlan.c:2742 -msgid "# wlan fragments received" +#: src/transport/plugin_transport_wlan.c:1306 +msgid "# DATA messages received via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2790 -msgid "# wlan acks received" +#: src/transport/plugin_transport_wlan.c:1341 +msgid "# WLAN DATA messages processed" msgstr "" -#: src/transport/plugin_transport_wlan.c:2879 -msgid "# wlan mac endpoints timeouts" +#: src/transport/plugin_transport_wlan.c:1402 +msgid "# HELLO beacons sent via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2903 -msgid "# wlan mac endpoints created" +#: src/transport/plugin_transport_wlan.c:1511 +msgid "WLAN address with invalid size encountered\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:2956 -msgid "# wlan WLAN_HELPER_DATA received" +#: src/transport/plugin_transport_wlan.c:1668 +#, c-format +msgid "Invalid configuration option `%s' in section `%s'\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:3010 -msgid "# wlan messages for this client received" +#: src/transport/plugin_transport_wlan.c:1677 +#, c-format +msgid "Helper binary `%s' not SUID, cannot run WLAN transport\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:3021 -msgid "# wlan messages inside WLAN_HELPER_DATA received" +#: src/transport/plugin_transport_wlan.c:1687 +#, c-format +msgid "Missing configuration option `%s' in section `%s'\n" msgstr "" -#: src/transport/transport_api.c:588 +#: src/transport/transport_api.c:570 #, c-format msgid "Received unexpected message of type %u in %s:%u\n" msgstr "" @@ -4667,134 +4904,127 @@ msgstr "" msgid "Metadata `%s' failed to deserialize" msgstr "" -#: src/util/client.c:304 +#: src/util/client.c:359 #, c-format msgid "" "Could not determine valid hostname and port for service `%s' from " "configuration.\n" msgstr "" -#: src/util/client.c:312 +#: src/util/client.c:367 #, c-format msgid "Need a non-empty hostname for service `%s'.\n" msgstr "" -#: src/util/client.c:657 +#: src/util/client.c:685 msgid "Failure to transmit TEST request.\n" msgstr "" -#: src/util/client.c:717 src/util/service.c:919 +#: src/util/client.c:740 src/util/service.c:970 #, c-format msgid "UNIXPATH `%s' too long, maximum length is %llu\n" msgstr "" -#: src/util/client.c:859 +#: src/util/client.c:882 #, c-format msgid "Could not connect to service `%s', must not be running.\n" msgstr "" -#: src/util/client.c:875 +#: src/util/client.c:896 #, c-format msgid "Failure to transmit request to service `%s'\n" msgstr "" -#: src/util/client.c:1143 +#: src/util/client.c:1149 msgid "Could not submit request, not expecting to receive a response.\n" msgstr "" -#: src/util/common_logging.c:239 src/util/common_logging.c:889 +#: src/util/common_logging.c:239 src/util/common_logging.c:890 msgid "DEBUG" msgstr "" -#: src/util/common_logging.c:241 src/util/common_logging.c:887 +#: src/util/common_logging.c:241 src/util/common_logging.c:888 msgid "INFO" msgstr "" -#: src/util/common_logging.c:243 src/util/common_logging.c:885 +#: src/util/common_logging.c:243 src/util/common_logging.c:886 msgid "WARNING" msgstr "" -#: src/util/common_logging.c:245 src/util/common_logging.c:883 +#: src/util/common_logging.c:245 src/util/common_logging.c:884 msgid "ERROR" msgstr "" -#: src/util/common_logging.c:247 src/util/common_logging.c:891 +#: src/util/common_logging.c:247 src/util/common_logging.c:892 msgid "NONE" msgstr "" -#: src/util/common_logging.c:609 +#: src/util/common_logging.c:610 #, c-format msgid "Failed to create or access directory for log file `%s'\n" msgstr "" -#: src/util/common_logging.c:724 +#: src/util/common_logging.c:725 #, c-format msgid "Message `%.*s' repeated %u times in the last %s\n" msgstr "" -#: src/util/common_logging.c:892 +#: src/util/common_logging.c:893 msgid "INVALID" msgstr "" -#: src/util/common_logging.c:991 +#: src/util/common_logging.c:992 msgid "unknown address" msgstr "" -#: src/util/common_logging.c:1029 +#: src/util/common_logging.c:1030 msgid "invalid address" msgstr "" -#: src/util/configuration.c:245 +#: src/util/configuration.c:244 #, c-format msgid "Syntax error in configuration file `%s' at line %u.\n" msgstr "" -#: src/util/configuration.c:817 +#: src/util/configuration.c:816 #, c-format msgid "" "Configuration value '%s' for '%s' in section '%s' is not in set of legal " "choices\n" msgstr "" -#: src/util/connection.c:460 +#: src/util/connection.c:420 #, c-format msgid "Access denied to `%s'\n" msgstr "" -#: src/util/connection.c:475 +#: src/util/connection.c:435 #, c-format msgid "Accepting connection from `%s': %p\n" msgstr "" -#: src/util/connection.c:629 +#: src/util/connection.c:550 #, c-format msgid "" "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n" msgstr "" -#: src/util/connection.c:821 src/util/connection.c:992 +#: src/util/connection.c:739 src/util/connection.c:909 #, c-format msgid "Trying to connect to `%s' (%p)\n" msgstr "" -#: src/util/connection.c:830 +#: src/util/connection.c:748 #, c-format msgid "Failed to connect to `%s' (%p)\n" msgstr "" -#: src/util/connection.c:983 +#: src/util/connection.c:900 #, c-format msgid "Attempt to connect to `%s' failed\n" msgstr "" -#: src/util/connection.c:1465 -#, c-format -msgid "" -"Could not satisfy pending transmission request, socket closed or connect " -"failed (%p).\n" -msgstr "" - -#: src/util/container_bloomfilter.c:507 +#: src/util/container_bloomfilter.c:510 #, c-format msgid "" "Size of file on disk is incorrect for this Bloom filter (want %llu, have " @@ -4811,133 +5041,133 @@ msgstr "" msgid "libgcrypt has not the expected version (version %s is required).\n" msgstr "" -#: src/util/crypto_rsa.c:618 src/util/crypto_rsa.c:665 +#: src/util/crypto_rsa.c:661 src/util/crypto_rsa.c:708 #, c-format msgid "Could not aquire lock on file `%s': %s...\n" msgstr "" -#: src/util/crypto_rsa.c:623 +#: src/util/crypto_rsa.c:666 msgid "Creating a new private key. This may take a while.\n" msgstr "" -#: src/util/crypto_rsa.c:641 +#: src/util/crypto_rsa.c:684 #, c-format msgid "I am host `%s'. Stored new private key in `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:669 src/util/crypto_rsa.c:705 +#: src/util/crypto_rsa.c:712 src/util/crypto_rsa.c:748 msgid "This may be ok if someone is currently generating a hostkey.\n" msgstr "" -#: src/util/crypto_rsa.c:700 +#: src/util/crypto_rsa.c:743 #, c-format msgid "" "When trying to read hostkey file `%s' I found %u bytes but I need at least " "%u.\n" msgstr "" -#: src/util/crypto_rsa.c:720 +#: src/util/crypto_rsa.c:763 #, c-format msgid "File `%s' does not contain a valid private key. Deleting it.\n" msgstr "" -#: src/util/crypto_rsa.c:738 +#: src/util/crypto_rsa.c:781 #, c-format msgid "I am host `%s'. Read private key from `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:959 +#: src/util/crypto_rsa.c:1032 #, c-format msgid "RSA signature verification failed at %s:%d: %s\n" msgstr "" -#: src/util/disk.c:479 +#: src/util/disk.c:498 #, c-format msgid "`%s' failed for drive `%S': %u\n" msgstr "" -#: src/util/disk.c:1087 +#: src/util/disk.c:1062 #, c-format msgid "Expected `%s' to be a directory!\n" msgstr "" -#: src/util/disk.c:1441 src/util/service.c:1580 +#: src/util/disk.c:1416 src/util/service.c:1650 #, c-format msgid "Cannot obtain information about user `%s': %s\n" msgstr "" -#: src/util/disk.c:1759 +#: src/util/disk.c:1734 #, c-format msgid "No `%s' specified for service `%s' in configuration.\n" msgstr "" -#: src/util/getopt.c:672 +#: src/util/getopt.c:669 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "" -#: src/util/getopt.c:696 +#: src/util/getopt.c:693 #, c-format msgid "%s: option `--%s' does not allow an argument\n" msgstr "" -#: src/util/getopt.c:701 +#: src/util/getopt.c:698 #, c-format msgid "%s: option `%c%s' does not allow an argument\n" msgstr "" -#: src/util/getopt.c:718 src/util/getopt.c:886 +#: src/util/getopt.c:715 src/util/getopt.c:883 #, c-format msgid "%s: option `%s' requires an argument\n" msgstr "" -#: src/util/getopt.c:747 +#: src/util/getopt.c:744 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "" -#: src/util/getopt.c:751 +#: src/util/getopt.c:748 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "" -#: src/util/getopt.c:776 +#: src/util/getopt.c:773 #, c-format msgid "%s: illegal option -- %c\n" msgstr "" -#: src/util/getopt.c:778 +#: src/util/getopt.c:775 #, c-format msgid "%s: invalid option -- %c\n" msgstr "" -#: src/util/getopt.c:806 src/util/getopt.c:934 +#: src/util/getopt.c:803 src/util/getopt.c:931 #, c-format msgid "%s: option requires an argument -- %c\n" msgstr "" -#: src/util/getopt.c:854 +#: src/util/getopt.c:851 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "" -#: src/util/getopt.c:872 +#: src/util/getopt.c:869 #, c-format msgid "%s: option `-W %s' does not allow an argument\n" msgstr "" -#: src/util/getopt.c:1038 +#: src/util/getopt.c:1035 #, c-format msgid "Use %s to get a list of options.\n" msgstr "" -#: src/util/getopt_helpers.c:84 +#: src/util/getopt_helpers.c:86 #, c-format msgid "" "Arguments mandatory for long options are also mandatory for short options.\n" msgstr "" -#: src/util/getopt_helpers.c:255 src/util/getopt_helpers.c:283 +#: src/util/getopt_helpers.c:258 src/util/getopt_helpers.c:286 #, c-format msgid "You must pass a number to the `%s' option.\n" msgstr "" @@ -4950,53 +5180,69 @@ msgstr "" msgid "Use build-in GNUnet stub resolver" msgstr "" -#: src/util/gnunet-service-resolver.c:288 +#: src/util/gnunet-rsa.c:64 #, c-format -msgid "Could not resolve `%s' (%s): %s\n" +msgid "No hostkey file specified on command line\n" msgstr "" -#: src/util/gnunet-service-resolver.c:358 -#: src/util/gnunet-service-resolver.c:399 -#, c-format -msgid "Could not find IP of host `%s': %s\n" +#: src/util/gnunet-rsa.c:112 +msgid "print the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:115 +msgid "print the hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:118 +msgid "print the short hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:124 +msgid "Manipulate GNUnet private RSA key files" msgstr "" -#: src/util/gnunet-service-resolver.c:494 +#: src/util/gnunet-service-resolver.c:288 #, c-format -msgid "Resolver asked to look up `%s'.\n" +msgid "Could not resolve `%s' (%s): %s\n" msgstr "" -#: src/util/gnunet-service-resolver.c:529 +#: src/util/gnunet-service-resolver.c:358 +#: src/util/gnunet-service-resolver.c:399 #, c-format -msgid "Resolver asked to look up IP address `%s'.\n" +msgid "Could not find IP of host `%s': %s\n" msgstr "" -#: src/util/helper.c:239 +#: src/util/helper.c:244 #, c-format msgid "Error reading from `%s': %s\n" msgstr "" -#: src/util/helper.c:254 +#: src/util/helper.c:259 #, c-format msgid "Got 0 bytes from helper `%s' (EOF)\n" msgstr "" -#: src/util/helper.c:264 +#: src/util/helper.c:269 #, c-format msgid "Got %u bytes from helper `%s'\n" msgstr "" -#: src/util/helper.c:273 +#: src/util/helper.c:278 #, c-format msgid "Failed to parse inbound message from helper `%s'\n" msgstr "" -#: src/util/helper.c:432 +#: src/util/helper.c:310 +#, c-format +msgid "Starting HELPER process `%s'\n" +msgstr "" + +#: src/util/helper.c:440 #, c-format msgid "Error writing to `%s': %s\n" msgstr "" -#: src/util/network.c:1196 +#: src/util/network.c:1200 #, c-format msgid "" "Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n" @@ -5024,12 +5270,12 @@ msgstr "" msgid "stat (%s) failed: %s\n" msgstr "" -#: src/util/os_priority.c:304 +#: src/util/os_priority.c:305 #, c-format msgid "Failed to open named pipe `%s' for reading: %s\n" msgstr "" -#: src/util/os_priority.c:305 +#: src/util/os_priority.c:306 #, c-format msgid "Failed to open named pipe `%s' for writing: %s\n" msgstr "" @@ -5053,12 +5299,12 @@ msgstr "" msgid "Could not determine plugin installation path.\n" msgstr "" -#: src/util/pseudonym.c:273 +#: src/util/pseudonym.c:276 #, c-format msgid "Failed to parse metadata about pseudonym from file `%s': %s\n" msgstr "" -#: src/util/pseudonym.c:338 +#: src/util/pseudonym.c:407 src/util/pseudonym.c:433 msgid "no-name" msgstr "" @@ -5073,187 +5319,167 @@ msgid "" "Must specify `%s' or numeric IP address for `%s' of `%s' in configuration!\n" msgstr "" -#: src/util/resolver_api.c:351 +#: src/util/resolver_api.c:347 #, c-format msgid "Timeout trying to resolve IP address `%s'.\n" msgstr "" -#: src/util/resolver_api.c:355 +#: src/util/resolver_api.c:351 #, c-format msgid "Timeout trying to resolve hostname `%s'.\n" msgstr "" -#: src/util/resolver_api.c:426 -#, c-format -msgid "Resolver returns `%s' for IP `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:807 -#, c-format -msgid "Resolver returns `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:901 -#, c-format -msgid "Resolving our FQDN `%s'\n" -msgstr "" - -#: src/util/resolver_api.c:906 +#: src/util/resolver_api.c:890 #, c-format msgid "Could not resolve our FQDN : %s\n" msgstr "" -#: src/util/resolver_api.c:938 -#, c-format -msgid "Resolving our hostname `%s'\n" -msgstr "" - -#: src/util/scheduler.c:866 +#: src/util/scheduler.c:786 msgid "Looks like we're busy waiting...\n" msgstr "" -#: src/util/scheduler.c:996 +#: src/util/scheduler.c:916 #, c-format msgid "Attempt to cancel dead task %llu!\n" msgstr "" -#: src/util/server.c:397 +#: src/util/server.c:483 #, c-format msgid "`%s' failed for port %d (%s).\n" msgstr "" -#: src/util/server.c:406 +#: src/util/server.c:492 #, c-format msgid "`%s' failed for port %d (%s): address already in use\n" msgstr "" -#: src/util/server.c:411 +#: src/util/server.c:497 #, c-format msgid "`%s' failed for `%s': address already in use\n" msgstr "" -#: src/util/server.c:640 +#: src/util/server.c:827 #, c-format msgid "" "Processing code for message of type %u did not call " "GNUNET_SERVER_receive_done after %llums\n" msgstr "" -#: src/util/service.c:117 src/util/service.c:143 src/util/service.c:186 -#: src/util/service.c:207 src/util/service.c:214 +#: src/util/service.c:135 src/util/service.c:161 src/util/service.c:204 +#: src/util/service.c:225 src/util/service.c:232 #, c-format msgid "Invalid format for IP: `%s'\n" msgstr "" -#: src/util/service.c:170 +#: src/util/service.c:188 #, c-format msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)." msgstr "" -#: src/util/service.c:263 +#: src/util/service.c:281 #, c-format msgid "Invalid network notation (does not end with ';': `%s')\n" msgstr "" -#: src/util/service.c:296 +#: src/util/service.c:313 #, c-format msgid "Wrong format `%s' for netmask\n" msgstr "" -#: src/util/service.c:326 +#: src/util/service.c:343 #, c-format msgid "Wrong format `%s' for network\n" msgstr "" -#: src/util/service.c:668 +#: src/util/service.c:698 #, c-format msgid "Access denied to UID %d / GID %d\n" msgstr "" -#: src/util/service.c:673 +#: src/util/service.c:703 #, c-format msgid "Unknown address family %d\n" msgstr "" -#: src/util/service.c:680 +#: src/util/service.c:710 #, c-format msgid "Access from `%s' denied to service `%s'\n" msgstr "" -#: src/util/service.c:724 +#: src/util/service.c:765 #, c-format msgid "Could not parse IPv4 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:752 +#: src/util/service.c:802 #, c-format msgid "Could not parse IPv6 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:869 +#: src/util/service.c:920 #, c-format msgid "" "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n" msgstr "" -#: src/util/service.c:939 +#: src/util/service.c:990 #, c-format msgid "" "Disabling UNIX domain socket support for service `%s', failed to create UNIX " "domain socket: %s\n" msgstr "" -#: src/util/service.c:956 +#: src/util/service.c:1007 #, c-format msgid "Have neither PORT nor UNIXPATH for service `%s', but one is required\n" msgstr "" -#: src/util/service.c:1191 +#: src/util/service.c:1241 msgid "Could not access a pre-bound socket, will try to bind myself\n" msgstr "" -#: src/util/service.c:1242 src/util/service.c:1260 +#: src/util/service.c:1292 src/util/service.c:1310 #, c-format msgid "Specified value for `%s' of service `%s' is invalid\n" msgstr "" -#: src/util/service.c:1287 +#: src/util/service.c:1337 #, c-format msgid "Could not access pre-bound socket %u, will try to bind myself\n" msgstr "" -#: src/util/service.c:1442 +#: src/util/service.c:1506 #, c-format msgid "Failed to start `%s' at `%s'\n" msgstr "" -#: src/util/service.c:1475 +#: src/util/service.c:1539 #, c-format msgid "Service `%s' runs at %s\n" msgstr "" -#: src/util/service.c:1521 +#: src/util/service.c:1588 msgid "Service process failed to initialize\n" msgstr "" -#: src/util/service.c:1525 +#: src/util/service.c:1592 msgid "Service process could not initialize server function\n" msgstr "" -#: src/util/service.c:1529 +#: src/util/service.c:1596 msgid "Service process failed to report status\n" msgstr "" -#: src/util/service.c:1581 +#: src/util/service.c:1651 msgid "No such user" msgstr "" -#: src/util/service.c:1594 +#: src/util/service.c:1664 #, c-format msgid "Cannot change user/group to `%s': %s\n" msgstr "" -#: src/util/service.c:1657 +#: src/util/service.c:1729 msgid "do daemonize (detach from terminal)" msgstr "" @@ -5262,53 +5488,74 @@ msgstr "" msgid "signal (%d, %p) returned %d.\n" msgstr "" -#: src/util/strings.c:143 +#: src/util/strings.c:144 msgid "b" msgstr "" -#: src/util/strings.c:354 +#: src/util/strings.c:334 #, c-format msgid "Character sets requested were `%s'->`%s'\n" msgstr "" -#: src/util/strings.c:462 +#: src/util/strings.c:481 msgid "Failed to expand `$HOME': environment variable `HOME' not set" msgstr "" -#: src/util/strings.c:554 +#: src/util/strings.c:573 msgid "ms" msgstr "" -#: src/util/strings.c:559 +#: src/util/strings.c:578 msgid "eternity" msgstr "" -#: src/util/strings.c:563 +#: src/util/strings.c:582 msgid "s" msgstr "" -#: src/util/strings.c:567 +#: src/util/strings.c:586 msgid "m" msgstr "" -#: src/util/strings.c:571 +#: src/util/strings.c:590 msgid "h" msgstr "" -#: src/util/strings.c:575 +#: src/util/strings.c:594 msgid " days" msgstr "" -#: src/util/strings.c:599 +#: src/util/strings.c:618 msgid "end of time" msgstr "" -#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1065 +#: src/util/strings.c:1012 +msgid "IPv6 address did not start with `['\n" +msgstr "" + +#: src/util/strings.c:1020 +msgid "IPv6 address did contain ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1026 +msgid "IPv6 address did contain ']' before ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1033 +msgid "IPv6 address did contain a valid port number after the last ':'\n" +msgstr "" + +#: src/util/strings.c:1042 +#, c-format +msgid "Invalid IPv6 address `%s': %s\n" +msgstr "" + +#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1071 msgid "# Active tunnels" msgstr "" #: src/vpn/gnunet-service-vpn.c:608 src/vpn/gnunet-service-vpn.c:645 -msgid "# Peers connected to mesh tunnels" +msgid "# peers connected to mesh tunnels" msgstr "" #: src/vpn/gnunet-service-vpn.c:699 @@ -5327,70 +5574,70 @@ msgstr "" msgid "Failed to setup mesh tunnel!\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:967 +#: src/vpn/gnunet-service-vpn.c:973 #, c-format msgid "Protocol %u not supported, dropping\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1285 +#: src/vpn/gnunet-service-vpn.c:1291 msgid "# ICMPv4 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1306 +#: src/vpn/gnunet-service-vpn.c:1312 msgid "# ICMPv6 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1511 +#: src/vpn/gnunet-service-vpn.c:1517 msgid "# Packets received from TUN interface" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1549 src/vpn/gnunet-service-vpn.c:1590 +#: src/vpn/gnunet-service-vpn.c:1555 src/vpn/gnunet-service-vpn.c:1596 #, c-format msgid "Packet received for unmapped destination `%s' (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1600 +#: src/vpn/gnunet-service-vpn.c:1606 msgid "Received IPv4 packet with options (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1614 +#: src/vpn/gnunet-service-vpn.c:1620 #, c-format msgid "Received packet of unknown protocol %d from TUN (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1697 +#: src/vpn/gnunet-service-vpn.c:1704 msgid "# ICMP packets received from mesh" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2038 +#: src/vpn/gnunet-service-vpn.c:2045 msgid "# UDP packets received from mesh" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2196 +#: src/vpn/gnunet-service-vpn.c:2203 msgid "# TCP packets received from mesh" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2347 +#: src/vpn/gnunet-service-vpn.c:2354 msgid "Failed to find unallocated IPv4 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2402 +#: src/vpn/gnunet-service-vpn.c:2409 msgid "Failed to find unallocated IPv6 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2441 src/vpn/gnunet-service-vpn.c:2624 +#: src/vpn/gnunet-service-vpn.c:2448 src/vpn/gnunet-service-vpn.c:2661 msgid "# Active destinations" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2726 +#: src/vpn/gnunet-service-vpn.c:2734 msgid "Failed to allocate IP address for new destination\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3133 +#: src/vpn/gnunet-service-vpn.c:3141 msgid "IPv6 support disabled as this system does not support IPv6\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3165 +#: src/vpn/gnunet-service-vpn.c:3173 msgid "IPv4 support disabled as this system does not support IPv4\n" msgstr "" @@ -5463,18 +5710,18 @@ msgstr "" msgid "Setup tunnels via VPN." msgstr "" -#: src/include/gnunet_common.h:479 src/include/gnunet_common.h:484 -#: src/include/gnunet_common.h:490 +#: src/include/gnunet_common.h:497 src/include/gnunet_common.h:502 +#: src/include/gnunet_common.h:508 #, c-format msgid "Assertion failed at %s:%d.\n" msgstr "" -#: src/include/gnunet_common.h:500 +#: src/include/gnunet_common.h:518 #, c-format msgid "External protocol violation detected at %s:%d.\n" msgstr "" -#: src/include/gnunet_common.h:521 src/include/gnunet_common.h:528 +#: src/include/gnunet_common.h:539 src/include/gnunet_common.h:546 #, c-format msgid "`%s' failed on file `%s' at %s:%d with error: %s\n" msgstr "" diff --git a/po/sv.gmo b/po/sv.gmo index 8e049a7..5f03fca 100644 Binary files a/po/sv.gmo and b/po/sv.gmo differ diff --git a/po/sv.po b/po/sv.po index b475a4e..e3e5bc3 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GNUnet 0.7.0b\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2012-02-28 18:30+0100\n" +"POT-Creation-Date: 2012-06-05 15:47+0200\n" "PO-Revision-Date: 2006-01-21 17:16+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" @@ -16,255 +16,270 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/arm/arm_api.c:187 +#: src/arm/arm_api.c:165 msgid "Failed to transmit shutdown request to client.\n" msgstr "" -#: src/arm/arm_api.c:378 +#: src/arm/arm_api.c:349 #, fuzzy, c-format msgid "Configuration failes to specify option `%s' in section `%s'!\n" msgstr "Konfigurationsfil \"%s\" hittades inte. KĂśr \"gnunet-setup -d\"!\n" -#: src/arm/arm_api.c:392 +#: src/arm/arm_api.c:363 #, fuzzy, c-format msgid "Configuration fails to specify option `%s' in section `%s'!\n" msgstr "Konfigurationsfil \"%s\" skapad.\n" -#: src/arm/arm_api.c:467 +#: src/arm/arm_api.c:432 #, c-format msgid "Error receiving response to `%s' request from ARM for service `%s'\n" msgstr "" -#: src/arm/arm_api.c:523 +#: src/arm/arm_api.c:485 #, c-format msgid "Requesting start of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:524 +#: src/arm/arm_api.c:486 #, c-format msgid "Requesting termination of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:546 +#: src/arm/arm_api.c:507 #, c-format msgid "Error while trying to transmit request to start `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:548 +#: src/arm/arm_api.c:508 #, c-format msgid "Error while trying to transmit request to stop `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:581 +#: src/arm/arm_api.c:540 #, fuzzy, c-format msgid "Asked to start service `%s' within %llu ms\n" msgstr "\"%s\": Mottog inte meddelande inom %llu ms.\n" -#: src/arm/arm_api.c:654 +#: src/arm/arm_api.c:612 #, fuzzy, c-format msgid "Stopping service `%s' within %llu ms\n" msgstr "Inget svar mottaget inom %llums.\n" -#: src/arm/gnunet-arm.c:149 +#: src/arm/gnunet-arm.c:159 #, fuzzy, c-format msgid "Service `%s' is unknown to ARM.\n" msgstr "\"%s\" är inte en fil.\n" -#: src/arm/gnunet-arm.c:154 +#: src/arm/gnunet-arm.c:164 #, fuzzy, c-format msgid "Service `%s' has been stopped.\n" msgstr "Tjänst borttagen.\n" -#: src/arm/gnunet-arm.c:157 +#: src/arm/gnunet-arm.c:167 #, fuzzy, c-format msgid "Service `%s' was already running.\n" msgstr "\"%s\" är inte en fil.\n" -#: src/arm/gnunet-arm.c:162 +#: src/arm/gnunet-arm.c:172 #, fuzzy, c-format msgid "Service `%s' has been started.\n" msgstr "Tjänst borttagen.\n" -#: src/arm/gnunet-arm.c:165 +#: src/arm/gnunet-arm.c:175 #, fuzzy, c-format msgid "Service `%s' was already being stopped.\n" msgstr "Tjänst borttagen.\n" -#: src/arm/gnunet-arm.c:169 +#: src/arm/gnunet-arm.c:179 #, fuzzy, c-format msgid "Service `%s' was already not running.\n" msgstr "\"%s\" är inte en fil.\n" -#: src/arm/gnunet-arm.c:173 +#: src/arm/gnunet-arm.c:183 msgid "Request ignored as ARM is shutting down.\n" msgstr "" -#: src/arm/gnunet-arm.c:177 +#: src/arm/gnunet-arm.c:187 #, fuzzy msgid "Error communicating with ARM service.\n" msgstr "Skriv ut information om GNUnets motparter." -#: src/arm/gnunet-arm.c:181 +#: src/arm/gnunet-arm.c:191 #, fuzzy msgid "Timeout communicating with ARM service.\n" msgstr "Skriv ut information om GNUnets motparter." -#: src/arm/gnunet-arm.c:185 +#: src/arm/gnunet-arm.c:195 #, fuzzy msgid "Operation failed.\n" msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n" -#: src/arm/gnunet-arm.c:189 +#: src/arm/gnunet-arm.c:199 msgid "Unknown response code from ARM.\n" msgstr "" -#: src/arm/gnunet-arm.c:216 +#: src/arm/gnunet-arm.c:222 +#, fuzzy +msgid "Error communicating with ARM. ARM not running?\n" +msgstr "Skriv ut information om GNUnets motparter." + +#: src/arm/gnunet-arm.c:225 +#, fuzzy +msgid "Running services:\n" +msgstr "Startade samling \"%s\".\n" + +#: src/arm/gnunet-arm.c:249 #, c-format msgid "Fatal configuration error: `%s' option in section `%s' missing.\n" msgstr "" -#: src/arm/gnunet-arm.c:224 src/arm/gnunet-arm.c:324 +#: src/arm/gnunet-arm.c:257 src/arm/gnunet-arm.c:357 src/arm/gnunet-arm.c:373 msgid "Fatal error initializing ARM API.\n" msgstr "" -#: src/arm/gnunet-arm.c:247 +#: src/arm/gnunet-arm.c:280 #, fuzzy, c-format msgid "Failed to remove configuration file %s\n" msgstr "Kunde inte spara konfigurationsfil \"%s\":" -#: src/arm/gnunet-arm.c:253 +#: src/arm/gnunet-arm.c:286 #, fuzzy, c-format msgid "Failed to remove servicehome directory %s\n" msgstr "Filformatsfel (inte en GNUnet-katalog?)\n" -#: src/arm/gnunet-arm.c:355 +#: src/arm/gnunet-arm.c:407 msgid "stop all GNUnet services" msgstr "" -#: src/arm/gnunet-arm.c:357 +#: src/arm/gnunet-arm.c:409 msgid "start a particular service" msgstr "" -#: src/arm/gnunet-arm.c:359 +#: src/arm/gnunet-arm.c:411 msgid "stop a particular service" msgstr "" -#: src/arm/gnunet-arm.c:361 +#: src/arm/gnunet-arm.c:413 msgid "start all GNUnet default services" msgstr "" -#: src/arm/gnunet-arm.c:364 +#: src/arm/gnunet-arm.c:416 msgid "stop and start all GNUnet default services" msgstr "" -#: src/arm/gnunet-arm.c:367 +#: src/arm/gnunet-arm.c:419 msgid "delete config file and directory on exit" msgstr "" -#: src/arm/gnunet-arm.c:369 +#: src/arm/gnunet-arm.c:421 msgid "don't print status messages" msgstr "" -#: src/arm/gnunet-arm.c:372 +#: src/arm/gnunet-arm.c:424 msgid "timeout for completing current operation" msgstr "" -#: src/arm/gnunet-arm.c:383 +#: src/arm/gnunet-arm.c:426 +msgid "List currently running services" +msgstr "" + +#: src/arm/gnunet-arm.c:437 msgid "Control services and the Automated Restart Manager (ARM)" msgstr "" -#: src/arm/gnunet-service-arm.c:328 +#: src/arm/gnunet-service-arm.c:332 #, fuzzy, c-format msgid "Failed to start service `%s'\n" msgstr "Misslyckades att starta samling.\n" -#: src/arm/gnunet-service-arm.c:331 +#: src/arm/gnunet-service-arm.c:335 #, fuzzy, c-format msgid "Starting service `%s'\n" msgstr "Startade samling \"%s\".\n" -#: src/arm/gnunet-service-arm.c:357 +#: src/arm/gnunet-service-arm.c:361 #, fuzzy msgid "Could not send status result to client\n" msgstr "Kunde inte skicka begäran till gnunetd.\n" -#: src/arm/gnunet-service-arm.c:484 +#: src/arm/gnunet-service-arm.c:393 +#, fuzzy +msgid "Could not send list result to client\n" +msgstr "Kunde inte skicka begäran till gnunetd.\n" + +#: src/arm/gnunet-service-arm.c:523 #, fuzzy, c-format msgid "Unable to create socket for service `%s': %s\n" msgstr "Kunde inte skapa användarkonto:" -#: src/arm/gnunet-service-arm.c:506 +#: src/arm/gnunet-service-arm.c:545 #, c-format msgid "Unable to bind listening socket for service `%s' to address `%s': %s\n" msgstr "" -#: src/arm/gnunet-service-arm.c:520 +#: src/arm/gnunet-service-arm.c:559 #, c-format msgid "ARM now monitors connections to service `%s' at `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:628 +#: src/arm/gnunet-service-arm.c:667 #, fuzzy, c-format msgid "Preparing to stop `%s'\n" msgstr "Startade samling \"%s\".\n" -#: src/arm/gnunet-service-arm.c:782 +#: src/arm/gnunet-service-arm.c:878 #, fuzzy, c-format msgid "Restarting service `%s'.\n" msgstr "Startade samling \"%s\".\n" -#: src/arm/gnunet-service-arm.c:877 +#: src/arm/gnunet-service-arm.c:970 msgid "exit" msgstr "" -#: src/arm/gnunet-service-arm.c:882 +#: src/arm/gnunet-service-arm.c:975 msgid "signal" msgstr "" -#: src/arm/gnunet-service-arm.c:887 +#: src/arm/gnunet-service-arm.c:980 #, fuzzy msgid "unknown" msgstr "Okänt fel" -#: src/arm/gnunet-service-arm.c:921 +#: src/arm/gnunet-service-arm.c:986 +#, fuzzy, c-format +msgid "Service `%s' took %llu ms to terminate\n" +msgstr "Tjänst borttagen.\n" + +#: src/arm/gnunet-service-arm.c:1021 #, c-format msgid "Service `%s' terminated with status %s/%d, will restart in %llu ms\n" msgstr "" -#: src/arm/gnunet-service-arm.c:967 src/arm/mockup-service.c:41 -#, fuzzy -msgid "Failed to transmit shutdown ACK.\n" -msgstr "Misslyckades att starta samling.\n" - -#: src/arm/gnunet-service-arm.c:1067 +#: src/arm/gnunet-service-arm.c:1127 #, fuzzy, c-format msgid "Configuration file `%s' for service `%s' not valid: %s\n" msgstr "Konfigurationsfil \"%s\" skapad.\n" -#: src/arm/gnunet-service-arm.c:1069 +#: src/arm/gnunet-service-arm.c:1129 msgid "option missing" msgstr "" -#: src/arm/gnunet-service-arm.c:1152 +#: src/arm/gnunet-service-arm.c:1213 #, fuzzy, c-format msgid "Starting default services `%s'\n" msgstr "Startade samling \"%s\".\n" -#: src/arm/gnunet-service-arm.c:1163 +#: src/arm/gnunet-service-arm.c:1224 #, c-format msgid "Default service `%s' not configured correctly!\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1177 +#: src/arm/gnunet-service-arm.c:1238 msgid "" "No default services configured, GNUnet will not really start right now.\n" msgstr "" -#: src/arm/mockup-service.c:46 -msgid "Transmitting shutdown ACK.\n" -msgstr "" - -#: src/arm/mockup-service.c:69 +#: src/arm/mockup-service.c:44 msgid "Initiating shutdown as requested by client.\n" msgstr "" @@ -324,197 +339,200 @@ msgstr "" msgid "Undefined mandatory parameter: memberCallback\n" msgstr "" -#: src/chat/gnunet-chat.c:92 +#: src/chat/gnunet-chat.c:93 msgid "Joined\n" msgstr "" -#: src/chat/gnunet-chat.c:124 +#: src/chat/gnunet-chat.c:125 src/chat/gnunet-chat.c:133 +#: src/chat/gnunet-chat.c:213 src/chat/gnunet-chat.c:253 +#: src/chat/gnunet-chat.c:329 src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:400 src/chat/gnunet-chat.c:700 msgid "anonymous" msgstr "" -#: src/chat/gnunet-chat.c:130 +#: src/chat/gnunet-chat.c:144 #, fuzzy, c-format msgid "(%s) `%s' said: %s\n" msgstr "\"%s\" %s misslyckades: %s\n" -#: src/chat/gnunet-chat.c:133 src/chat/gnunet-chat.c:136 +#: src/chat/gnunet-chat.c:147 src/chat/gnunet-chat.c:150 #, fuzzy, c-format msgid "(%s) `%s' said to you: %s\n" msgstr "\"%s\" %s misslyckades: %s\n" # drive = hard drive ? -#: src/chat/gnunet-chat.c:139 +#: src/chat/gnunet-chat.c:153 #, fuzzy, c-format msgid "(%s) `%s' said for sure: %s\n" msgstr "\"%s\" misslyckades fĂśr enhet %s: %u\n" # drive = hard drive ? -#: src/chat/gnunet-chat.c:142 +#: src/chat/gnunet-chat.c:156 #, fuzzy, c-format msgid "(%s) `%s' said to you for sure: %s\n" msgstr "\"%s\" misslyckades fĂśr enhet %s: %u\n" -#: src/chat/gnunet-chat.c:145 +#: src/chat/gnunet-chat.c:159 #, c-format msgid "(%s) `%s' was confirmed that you received: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:148 +#: src/chat/gnunet-chat.c:162 #, c-format msgid "(%s) `%s' was confirmed that you and only you received: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:151 +#: src/chat/gnunet-chat.c:165 #, c-format msgid "(%s) `%s' was confirmed that you received from him or her: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:156 +#: src/chat/gnunet-chat.c:170 #, c-format msgid "" "(%s) `%s' was confirmed that you and only you received from him or her: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:159 +#: src/chat/gnunet-chat.c:173 #, fuzzy, c-format msgid "(%s) `%s' said off the record: %s\n" msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" -#: src/chat/gnunet-chat.c:162 +#: src/chat/gnunet-chat.c:176 #, c-format msgid "(%s) <%s> said using an unknown message type: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:193 +#: src/chat/gnunet-chat.c:217 #, c-format msgid "'%s' acknowledged message #%d\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' entered the room\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' left the room\n" msgstr "" -#: src/chat/gnunet-chat.c:284 src/chat/gnunet-chat.c:316 +#: src/chat/gnunet-chat.c:321 src/chat/gnunet-chat.c:363 #, fuzzy msgid "Could not change username\n" msgstr "Kunde inte skapa namnrymd \"%s\" (existerar?).\n" -#: src/chat/gnunet-chat.c:288 src/chat/gnunet-chat.c:630 +#: src/chat/gnunet-chat.c:334 src/chat/gnunet-chat.c:702 #, fuzzy, c-format msgid "Joining room `%s' as user `%s'...\n" msgstr "Ogiltigt svar till \"%s\" frĂĽn motpart \"%s\".\n" -#: src/chat/gnunet-chat.c:320 +#: src/chat/gnunet-chat.c:373 #, fuzzy, c-format msgid "Changed username to `%s'\n" msgstr "Kan inte ändra användare/grupp till \"%s\": %s\n" -#: src/chat/gnunet-chat.c:333 +#: src/chat/gnunet-chat.c:388 #, c-format msgid "Users in room `%s': " msgstr "" -#: src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:434 msgid "Syntax: /msg USERNAME MESSAGE" msgstr "" -#: src/chat/gnunet-chat.c:379 -#, fuzzy, c-format -msgid "Unknown user `%s'\n" -msgstr "Okänd operation \"%s\"\n" +#: src/chat/gnunet-chat.c:443 +#, c-format +msgid "Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n" +msgstr "" -#: src/chat/gnunet-chat.c:395 +#: src/chat/gnunet-chat.c:460 #, c-format msgid "User `%s' is currently not in the room!\n" msgstr "" -#: src/chat/gnunet-chat.c:448 +#: src/chat/gnunet-chat.c:513 #, fuzzy, c-format msgid "Unknown command `%s'\n" msgstr "Okänd operation \"%s\"\n" -#: src/chat/gnunet-chat.c:459 +#: src/chat/gnunet-chat.c:524 msgid "" "Use `/join #roomname' to join a chat room. Joining a room will cause you to " "leave the current room" msgstr "" -#: src/chat/gnunet-chat.c:463 +#: src/chat/gnunet-chat.c:528 msgid "" "Use `/nick nickname' to change your nickname. This will cause you to leave " "the current room and immediately rejoin it with the new name." msgstr "" -#: src/chat/gnunet-chat.c:467 +#: src/chat/gnunet-chat.c:532 msgid "" "Use `/msg nickname message' to send a private message to the specified user" msgstr "" -#: src/chat/gnunet-chat.c:470 +#: src/chat/gnunet-chat.c:535 msgid "The `/notice' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:472 +#: src/chat/gnunet-chat.c:537 msgid "The `/query' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:474 +#: src/chat/gnunet-chat.c:539 msgid "Use `/sig message' to send a signed public message" msgstr "" -#: src/chat/gnunet-chat.c:477 +#: src/chat/gnunet-chat.c:542 msgid "Use `/ack message' to require signed acknowledgment of the message" msgstr "" -#: src/chat/gnunet-chat.c:480 +#: src/chat/gnunet-chat.c:545 msgid "Use `/anonymous message' to send a public anonymous message" msgstr "" -#: src/chat/gnunet-chat.c:482 +#: src/chat/gnunet-chat.c:547 msgid "The `/anon' command is an alias for `/anonymous'" msgstr "" -#: src/chat/gnunet-chat.c:484 +#: src/chat/gnunet-chat.c:549 msgid "Use `/quit' to terminate gnunet-chat" msgstr "" -#: src/chat/gnunet-chat.c:486 +#: src/chat/gnunet-chat.c:551 msgid "The `/leave' command is an alias for `/quit'" msgstr "" -#: src/chat/gnunet-chat.c:489 +#: src/chat/gnunet-chat.c:554 msgid "Use `/names' to list all of the current members in the chat room" msgstr "" -#: src/chat/gnunet-chat.c:491 +#: src/chat/gnunet-chat.c:556 msgid "Use `/help command' to get help for a specific command" msgstr "" -#: src/chat/gnunet-chat.c:606 +#: src/chat/gnunet-chat.c:672 #, fuzzy msgid "You must specify a nickname\n" msgstr "Du mĂĽste ange en mottagare!\n" -#: src/chat/gnunet-chat.c:622 +#: src/chat/gnunet-chat.c:688 #, fuzzy, c-format msgid "Failed to join room `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/chat/gnunet-chat.c:655 +#: src/chat/gnunet-chat.c:727 msgid "set the nickname to use (required)" msgstr "" -#: src/chat/gnunet-chat.c:658 +#: src/chat/gnunet-chat.c:730 msgid "set the chat room to join" msgstr "" -#: src/chat/gnunet-chat.c:670 +#: src/chat/gnunet-chat.c:742 msgid "Join a chat on GNUnet." msgstr "" @@ -538,183 +556,185 @@ msgstr "Kunde inte spara konfiguration!" msgid "Failed to queue a leave notification\n" msgstr "Kunde inte spara konfiguration!" -#: src/core/core_api.c:798 +#: src/core/core_api.c:786 msgid "Client was disconnected from core service, trying to reconnect.\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:77 -#: src/peerinfo-tool/gnunet-peerinfo.c:60 +#: src/core/gnunet-core.c:54 src/peerinfo-tool/gnunet-peerinfo.c:286 #, fuzzy, c-format msgid "Peer `%s'\n" msgstr "Jag är ändpunkt \"%s\".\n" -#: src/core/gnunet-core-list-connections.c:175 -#: src/peerinfo-tool/gnunet-peerinfo.c:194 +#: src/core/gnunet-core.c:72 src/peerinfo-tool/gnunet-peerinfo.c:817 #, fuzzy, c-format msgid "Invalid command line argument `%s'\n" msgstr "Ogiltiga kommandoradsargument:\n" -#: src/core/gnunet-core-list-connections.c:196 -#: src/peerinfo-tool/gnunet-peerinfo.c:252 -msgid "don't resolve host names" -msgstr "" - -#: src/core/gnunet-core-list-connections.c:203 +#: src/core/gnunet-core.c:95 #, fuzzy msgid "Print information about connected peers." msgstr "Skriv ut information om GNUnets motparter." -#: src/core/gnunet-service-core.c:99 +#: src/core/gnunet-service-core.c:97 #, c-format msgid "Core service of `%4s' ready.\n" msgstr "" -#: src/core/gnunet-service-core_clients.c:360 +#: src/core/gnunet-service-core_clients.c:370 msgid "# send requests dropped (disconnected)" msgstr "" -#: src/core/gnunet-service-core_clients.c:465 +#: src/core/gnunet-service-core_clients.c:475 #, fuzzy msgid "# messages discarded (session disconnected)" msgstr "Nätverksannonsering avstängd i konfigurationen!\n" -#: src/core/gnunet-service-core_clients.c:801 +#: src/core/gnunet-service-core_clients.c:818 #, fuzzy, c-format msgid "# bytes of messages of type %u received" msgstr "# krypterade PONG-meddelanden mottagna" -#: src/core/gnunet-service-core_kx.c:493 +#: src/core/gnunet-service-core_kx.c:565 msgid "# bytes encrypted" msgstr "# byte krypterade" -#: src/core/gnunet-service-core_kx.c:543 +#: src/core/gnunet-service-core_kx.c:617 msgid "# bytes decrypted" msgstr "# byte dekrypterade" -#: src/core/gnunet-service-core_kx.c:604 src/dv/gnunet-service-dv.c:3002 -#: src/hostlist/hostlist-server.c:436 src/peerinfo-tool/gnunet-peerinfo.c:151 +#: src/core/gnunet-service-core_kx.c:681 src/dv/gnunet-service-dv.c:3003 #, fuzzy msgid "Error in communication with PEERINFO service\n" msgstr "Skriv ut information om GNUnets motparter." -#: src/core/gnunet-service-core_kx.c:623 +#: src/core/gnunet-service-core_kx.c:700 msgid "# Delayed connecting due to lack of public key" msgstr "" -#: src/core/gnunet-service-core_kx.c:673 +#: src/core/gnunet-service-core_kx.c:753 msgid "# key exchanges initiated" msgstr "" -#: src/core/gnunet-service-core_kx.c:694 +#: src/core/gnunet-service-core_kx.c:775 msgid "# key exchanges stopped" msgstr "" -#: src/core/gnunet-service-core_kx.c:746 +#: src/core/gnunet-service-core_kx.c:828 #, fuzzy msgid "# session keys received" msgstr "# sessionnycklar vägrade" -#: src/core/gnunet-service-core_kx.c:765 +#: src/core/gnunet-service-core_kx.c:845 #, fuzzy, c-format msgid "`%s' is for `%s', not for me. Ignoring.\n" msgstr "storlek pĂĽ \"%s\" meddelande är fĂśr litet. Ignorerar.\n" -#: src/core/gnunet-service-core_kx.c:803 +#: src/core/gnunet-service-core_kx.c:890 #, fuzzy msgid "# SET_KEY messages decrypted" msgstr "# PING-meddelanden skapade" -#: src/core/gnunet-service-core_kx.c:883 -#: src/transport/gnunet-service-transport_validation.c:803 +#: src/core/gnunet-service-core_kx.c:977 +#: src/transport/gnunet-service-transport_validation.c:810 #, fuzzy msgid "# PING messages received" msgstr "# PING-meddelanden skapade" -#: src/core/gnunet-service-core_kx.c:917 +#: src/core/gnunet-service-core_kx.c:1010 #, c-format msgid "" "Received PING from `%s' for different identity: I am `%s', PONG identity: `" "%s'\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:938 +#: src/core/gnunet-service-core_kx.c:1029 #, fuzzy msgid "# PONG messages created" msgstr "# PING-meddelanden skapade" -#: src/core/gnunet-service-core_kx.c:1026 +#: src/core/gnunet-service-core_kx.c:1125 #, fuzzy msgid "# sessions terminated by timeout" msgstr "# byte kastade via TCP (utgĂĽende)" -#: src/core/gnunet-service-core_kx.c:1037 +#: src/core/gnunet-service-core_kx.c:1135 #, fuzzy msgid "# keepalive messages sent" msgstr "# PING-meddelanden i klartext skickade" -#: src/core/gnunet-service-core_kx.c:1095 -#: src/transport/gnunet-service-transport_validation.c:1026 +#: src/core/gnunet-service-core_kx.c:1236 +#: src/transport/gnunet-service-transport_validation.c:1031 #, fuzzy msgid "# PONG messages received" msgstr "# krypterade PONG-meddelanden mottagna" -#: src/core/gnunet-service-core_kx.c:1125 +#: src/core/gnunet-service-core_kx.c:1275 #, fuzzy msgid "# PONG messages decrypted" msgstr "# PING-meddelanden skapade" -#: src/core/gnunet-service-core_kx.c:1157 +#: src/core/gnunet-service-core_kx.c:1303 #, fuzzy msgid "# session keys confirmed via PONG" msgstr "# sessionnycklar vägrade" -#: src/core/gnunet-service-core_kx.c:1223 +#: src/core/gnunet-service-core_kx.c:1329 +#, fuzzy +msgid "# rekey operations confirmed via PONG" +msgstr "# sessionnycklar vägrade" + +#: src/core/gnunet-service-core_kx.c:1381 +#: src/core/gnunet-service-core_kx.c:1398 #, fuzzy msgid "# SET_KEY and PING messages created" msgstr "# PING-meddelanden skapade" -#: src/core/gnunet-service-core_kx.c:1364 +#: src/core/gnunet-service-core_kx.c:1402 +msgid "# REKEY operations performed" +msgstr "" + +#: src/core/gnunet-service-core_kx.c:1537 msgid "# failed to decrypt message (no session key)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1406 -#: src/core/gnunet-service-core_kx.c:1431 +#: src/core/gnunet-service-core_kx.c:1577 +#: src/core/gnunet-service-core_kx.c:1602 #, fuzzy msgid "# bytes dropped (duplicates)" msgstr "# byte kastade via UDP (utgĂĽende)" -#: src/core/gnunet-service-core_kx.c:1418 +#: src/core/gnunet-service-core_kx.c:1589 #, fuzzy msgid "# bytes dropped (out of sequence)" msgstr "# byte kastade via UDP (utgĂĽende)" -#: src/core/gnunet-service-core_kx.c:1455 +#: src/core/gnunet-service-core_kx.c:1626 #, fuzzy, c-format msgid "Message received far too old (%llu ms). Content ignored.\n" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/core/gnunet-service-core_kx.c:1459 +#: src/core/gnunet-service-core_kx.c:1630 #, fuzzy msgid "# bytes dropped (ancient message)" msgstr "# byte kastade via UDP (utgĂĽende)" -#: src/core/gnunet-service-core_kx.c:1467 +#: src/core/gnunet-service-core_kx.c:1638 #, fuzzy msgid "# bytes of payload decrypted" msgstr "# byte dekrypterade" -#: src/core/gnunet-service-core_kx.c:1528 +#: src/core/gnunet-service-core_kx.c:1700 #, fuzzy msgid "Core service is lacking HOSTKEY configuration setting. Exiting.\n" msgstr "GNUnet-konfiguration" -#: src/core/gnunet-service-core_kx.c:1536 +#: src/core/gnunet-service-core_kx.c:1708 msgid "Core service could not access hostkey. Exiting.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1546 src/hostlist/hostlist-server.c:555 -#: src/peerinfo-tool/gnunet-peerinfo.c:202 -#: src/transport/gnunet-service-transport.c:595 +#: src/core/gnunet-service-core_kx.c:1718 src/hostlist/hostlist-server.c:551 +#: src/peerinfo-tool/gnunet-peerinfo.c:823 +#: src/transport/gnunet-service-transport.c:611 #, fuzzy msgid "Could not access PEERINFO service. Exiting.\n" msgstr "Kunde inte komma ĂĽt namnrymdsinformation.\n" @@ -725,29 +745,40 @@ msgid "# sessions terminated by transport disconnect" msgstr "Nätverksannonsering avstängd i konfigurationen!\n" #: src/core/gnunet-service-core_neighbours.c:180 -#: src/core/gnunet-service-core_neighbours.c:342 +#: src/core/gnunet-service-core_neighbours.c:334 msgid "# neighbour entries allocated" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:251 +#: src/core/gnunet-service-core_neighbours.c:247 msgid "# encrypted bytes given to transport" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:430 +#: src/core/gnunet-service-core_neighbours.c:418 #, c-format msgid "Unsupported message of type %u (%u bytes) received from peer `%s'\n" msgstr "" -#: src/core/gnunet-service-core_sessions.c:208 -#: src/core/gnunet-service-core_sessions.c:273 -msgid "# entries in session map" -msgstr "" +#: src/core/gnunet-service-core_sessions.c:206 +#: src/core/gnunet-service-core_sessions.c:269 +#: src/dht/gnunet-service-dht_neighbours.c:625 +#: src/dht/gnunet-service-dht_neighbours.c:683 +#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 +#: src/topology/gnunet-daemon-topology.c:709 +#: src/topology/gnunet-daemon-topology.c:810 +#: src/transport/gnunet-service-transport_neighbours.c:874 +#: src/transport/gnunet-service-transport_neighbours.c:1080 +#: src/transport/gnunet-service-transport_neighbours.c:1089 +#: src/transport/gnunet-service-transport_neighbours.c:2568 +#: src/transport/gnunet-service-transport_neighbours.c:2814 +#, fuzzy +msgid "# peers connected" +msgstr "# av anslutna parter" -#: src/core/gnunet-service-core_sessions.c:238 +#: src/core/gnunet-service-core_sessions.c:236 msgid "# type map refreshes sent" msgstr "" -#: src/core/gnunet-service-core_sessions.c:414 +#: src/core/gnunet-service-core_sessions.c:406 msgid "# messages discarded (expired prior to transmission)" msgstr "" @@ -761,416 +792,393 @@ msgstr "# krypterade PONG-meddelanden mottagna" msgid "# updates to my type map" msgstr "" -#: src/datacache/datacache.c:118 src/datacache/datacache.c:255 -#: src/datastore/gnunet-service-datastore.c:854 +#: src/datacache/datacache.c:115 src/datacache/datacache.c:250 +#: src/datastore/gnunet-service-datastore.c:834 #, fuzzy msgid "# bytes stored" msgstr "# byte krypterade" -#: src/datacache/datacache.c:144 src/datacache/datacache.c:151 -#: src/datastore/gnunet-service-datastore.c:1531 -#: src/datastore/gnunet-service-datastore.c:1542 +#: src/datacache/datacache.c:141 src/datacache/datacache.c:148 +#: src/datastore/gnunet-service-datastore.c:1483 +#: src/datastore/gnunet-service-datastore.c:1494 #, fuzzy, c-format msgid "No `%s' specified for `%s' in configuration!\n" msgstr "Inga applikationer definierade i konfiguration!\n" -#: src/datacache/datacache.c:183 +#: src/datacache/datacache.c:180 #, c-format msgid "Loading `%s' datacache plugin\n" msgstr "" -#: src/datacache/datacache.c:191 +#: src/datacache/datacache.c:188 #, fuzzy, c-format msgid "Failed to load datacache plugin for `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/datacache/datacache.c:281 +#: src/datacache/datacache.c:276 #, fuzzy msgid "# requests received" msgstr "# byte mottogs via TCP" -#: src/datacache/datacache.c:291 +#: src/datacache/datacache.c:284 msgid "# requests filtered by bloom filter" msgstr "" -#: src/datacache/plugin_datacache_mysql.c:103 -#: src/datacache/plugin_datacache_mysql.c:110 -#: src/datacache/plugin_datacache_mysql.c:517 -#: src/datacache/plugin_datacache_mysql.c:526 -#: src/datacache/plugin_datacache_mysql.c:598 -#: src/datacache/plugin_datacache_mysql.c:614 -#: src/datacache/plugin_datacache_sqlite.c:71 -#: src/datacache/plugin_datacache_sqlite.c:74 -#: src/datastore/plugin_datastore_mysql.c:139 -#: src/datastore/plugin_datastore_mysql.c:146 -#: src/datastore/plugin_datastore_mysql.c:613 -#: src/datastore/plugin_datastore_mysql.c:673 -#: src/datastore/plugin_datastore_mysql.c:685 -#: src/datastore/plugin_datastore_mysql.c:1362 -#: src/datastore/plugin_datastore_mysql.c:1376 -#: src/datastore/plugin_datastore_sqlite.c:61 -#: src/namestore/plugin_namestore_sqlite.c:49 src/util/crypto_ksk.c:49 -#: src/util/crypto_rsa.c:92 src/include/gnunet_common.h:507 -#: src/include/gnunet_common.h:514 +#: src/datacache/plugin_datacache_mysql.c:97 +#: src/datacache/plugin_datacache_mysql.c:104 +#: src/datacache/plugin_datacache_sqlite.c:69 +#: src/datacache/plugin_datacache_sqlite.c:72 +#: src/datastore/plugin_datastore_mysql.c:803 +#: src/datastore/plugin_datastore_mysql.c:817 +#: src/datastore/plugin_datastore_sqlite.c:57 src/mysql/mysql.c:41 +#: src/mysql/mysql.c:48 src/mysql/mysql.c:522 src/mysql/mysql.c:531 +#: src/mysql/mysql.c:591 src/mysql/mysql.c:607 +#: src/namestore/plugin_namestore_sqlite.c:51 src/util/crypto_ksk.c:49 +#: src/util/crypto_rsa.c:67 src/include/gnunet_common.h:525 +#: src/include/gnunet_common.h:532 #, c-format msgid "`%s' failed at %s:%d with error: %s\n" msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" -#: src/datacache/plugin_datacache_mysql.c:224 -#: src/datastore/plugin_datastore_mysql.c:316 -#, c-format -msgid "Trying to use file `%s' for MySQL configuration.\n" -msgstr "FĂśrsĂśker använda fil \"%s\" fĂśr MySQL-konfiguration.\n" - -#: src/datacache/plugin_datacache_mysql.c:230 -#: src/datastore/plugin_datastore_mysql.c:322 -#, fuzzy, c-format -msgid "Could not access file `%s': %s\n" -msgstr "Kunde inte kĂśra \"%s\": %s\n" - -#: src/datacache/plugin_datacache_mysql.c:979 +#: src/datacache/plugin_datacache_mysql.c:450 msgid "MySQL datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_postgres.c:79 -#: src/datastore/plugin_datastore_postgres.c:93 -#, fuzzy, c-format -msgid "`%s:%s' failed at %s:%d with error: %s" -msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" - -#: src/datacache/plugin_datacache_postgres.c:149 -#, fuzzy, c-format -msgid "Unable to initialize Postgres: %s" -msgstr "Kunde inte initiera SQLite.\n" - -#: src/datacache/plugin_datacache_postgres.c:499 +#: src/datacache/plugin_datacache_postgres.c:367 msgid "Postgres datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:424 +#: src/datacache/plugin_datacache_sqlite.c:410 msgid "Sqlite datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:457 -#: src/datastore/plugin_datastore_sqlite.c:414 -#: src/namestore/plugin_namestore_sqlite.c:381 +#: src/datacache/plugin_datacache_sqlite.c:443 +#: src/datastore/plugin_datastore_sqlite.c:408 +#: src/namestore/plugin_namestore_sqlite.c:370 msgid "Tried to close sqlite without finalizing all prepared statements.\n" msgstr "" +#: src/datacache/plugin_datacache_sqlite.c:450 +#, fuzzy, c-format +msgid "Failed to close statement %p: %d\n" +msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" + #: src/datacache/plugin_datacache_template.c:121 msgid "Template datacache running\n" msgstr "" -#: src/datastore/datastore_api.c:289 +#: src/datastore/datastore_api.c:305 #, fuzzy msgid "Failed to transmit request to drop database.\n" msgstr "Misslyckades att skicka HTTP-begäran till värd \"%s\": %s\n" -#: src/datastore/datastore_api.c:372 +#: src/datastore/datastore_api.c:388 msgid "# queue entry timeouts" msgstr "" -#: src/datastore/datastore_api.c:418 +#: src/datastore/datastore_api.c:432 msgid "# queue overflows" msgstr "" -#: src/datastore/datastore_api.c:445 +#: src/datastore/datastore_api.c:459 #, fuzzy msgid "# queue entries created" msgstr "# PING-meddelanden skapade" -#: src/datastore/datastore_api.c:465 +#: src/datastore/datastore_api.c:477 msgid "# Requests dropped from datastore queue" msgstr "" -#: src/datastore/datastore_api.c:513 +#: src/datastore/datastore_api.c:525 #, fuzzy msgid "# datastore connections (re)created" msgstr "Nätverksanslutning" -#: src/datastore/datastore_api.c:540 +#: src/datastore/datastore_api.c:548 msgid "# reconnected to DATASTORE" msgstr "" -#: src/datastore/datastore_api.c:608 +#: src/datastore/datastore_api.c:612 #, fuzzy msgid "# transmission request failures" msgstr "# klartext PONG-meddelanden mottagna" -#: src/datastore/datastore_api.c:631 +#: src/datastore/datastore_api.c:633 #, fuzzy msgid "# bytes sent to datastore" msgstr "# byte krypterade" -#: src/datastore/datastore_api.c:772 +#: src/datastore/datastore_api.c:764 #, fuzzy msgid "Failed to receive status response from database." msgstr "Misslyckades att ta emot svar till \"%s\" meddelande frĂĽn gnunetd\n" -#: src/datastore/datastore_api.c:786 +#: src/datastore/datastore_api.c:778 msgid "Error reading response from datastore service" msgstr "" -#: src/datastore/datastore_api.c:798 src/datastore/datastore_api.c:804 +#: src/datastore/datastore_api.c:790 src/datastore/datastore_api.c:796 #, fuzzy msgid "Invalid error message received from datastore service" msgstr "Ogiltigt meddelande mottogs den %s:%d." -#: src/datastore/datastore_api.c:810 +#: src/datastore/datastore_api.c:800 #, fuzzy msgid "# status messages received" msgstr "# krypterade PONG-meddelanden mottagna" -#: src/datastore/datastore_api.c:883 +#: src/datastore/datastore_api.c:869 msgid "# PUT requests executed" msgstr "" -#: src/datastore/datastore_api.c:954 +#: src/datastore/datastore_api.c:936 msgid "# RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1019 +#: src/datastore/datastore_api.c:997 msgid "# RELEASE RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1080 +#: src/datastore/datastore_api.c:1054 msgid "# UPDATE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1148 +#: src/datastore/datastore_api.c:1118 msgid "# REMOVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1193 +#: src/datastore/datastore_api.c:1163 #, fuzzy msgid "Failed to receive response from database.\n" msgstr "Misslyckades att ta emot svar till \"%s\" meddelande frĂĽn gnunetd\n" -#: src/datastore/datastore_api.c:1253 +#: src/datastore/datastore_api.c:1221 #, fuzzy msgid "# Results received" msgstr "# byte mottogs via TCP" -#: src/datastore/datastore_api.c:1324 +#: src/datastore/datastore_api.c:1286 msgid "# GET REPLICATION requests executed" msgstr "" -#: src/datastore/datastore_api.c:1391 +#: src/datastore/datastore_api.c:1349 msgid "# GET ZERO ANONYMITY requests executed" msgstr "" -#: src/datastore/datastore_api.c:1455 +#: src/datastore/datastore_api.c:1409 msgid "# GET requests executed" msgstr "" -#: src/datastore/gnunet-service-datastore.c:351 +#: src/datastore/gnunet-service-datastore.c:349 #, fuzzy msgid "# bytes expired" msgstr "# byte mottogs via TCP" -#: src/datastore/gnunet-service-datastore.c:426 +#: src/datastore/gnunet-service-datastore.c:422 msgid "# bytes purged (low-priority)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:486 +#: src/datastore/gnunet-service-datastore.c:480 msgid "Transmission to client failed!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:640 +#: src/datastore/gnunet-service-datastore.c:511 +msgid "Shutdown in progress, aborting transmission.\n" +msgstr "" + +#: src/datastore/gnunet-service-datastore.c:626 msgid "# results found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:685 +#: src/datastore/gnunet-service-datastore.c:669 #, c-format msgid "" "Insufficient space (%llu bytes are available) to satisfy `%s' request for " "%llu bytes\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:696 +#: src/datastore/gnunet-service-datastore.c:680 #, c-format msgid "" "The requested amount (%llu bytes) is larger than the cache size (%llu " "bytes)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:700 +#: src/datastore/gnunet-service-datastore.c:684 msgid "" "Insufficient space to satisfy request and requested amount is larger than " "cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:706 +#: src/datastore/gnunet-service-datastore.c:690 msgid "Insufficient space to satisfy request" msgstr "" -#: src/datastore/gnunet-service-datastore.c:711 -#: src/datastore/gnunet-service-datastore.c:765 -#: src/datastore/gnunet-service-datastore.c:986 -#: src/datastore/gnunet-service-datastore.c:1465 +#: src/datastore/gnunet-service-datastore.c:695 +#: src/datastore/gnunet-service-datastore.c:747 +#: src/datastore/gnunet-service-datastore.c:960 +#: src/datastore/gnunet-service-datastore.c:1417 msgid "# reserved" msgstr "" -#: src/datastore/gnunet-service-datastore.c:780 +#: src/datastore/gnunet-service-datastore.c:760 msgid "Could not find matching reservation" msgstr "" -#: src/datastore/gnunet-service-datastore.c:868 +#: src/datastore/gnunet-service-datastore.c:846 #, c-format msgid "Need %llu bytes more space (%llu allowed, using %llu)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1034 +#: src/datastore/gnunet-service-datastore.c:1006 #, fuzzy msgid "# GET requests received" msgstr "# byte mottogs via TCP" -#: src/datastore/gnunet-service-datastore.c:1048 +#: src/datastore/gnunet-service-datastore.c:1018 msgid "# requests filtered by bloomfilter" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1076 +#: src/datastore/gnunet-service-datastore.c:1046 #, fuzzy msgid "# UPDATE requests received" msgstr "# byte mottogs via TCP" -#: src/datastore/gnunet-service-datastore.c:1110 +#: src/datastore/gnunet-service-datastore.c:1076 msgid "# GET REPLICATION requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1145 +#: src/datastore/gnunet-service-datastore.c:1109 msgid "# GET ZERO ANONYMITY requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1172 +#: src/datastore/gnunet-service-datastore.c:1134 #, fuzzy msgid "Content not found" msgstr "Kommando \"%s\" hittades inte!\n" -#: src/datastore/gnunet-service-datastore.c:1182 +#: src/datastore/gnunet-service-datastore.c:1142 msgid "# bytes removed (explicit request)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1216 +#: src/datastore/gnunet-service-datastore.c:1174 #, fuzzy msgid "# REMOVE requests received" msgstr "# byte mottogs via TCP" -#: src/datastore/gnunet-service-datastore.c:1260 +#: src/datastore/gnunet-service-datastore.c:1216 #, c-format msgid "Datastore payload inaccurate (%lld < %lld). Trying to fix.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1323 +#: src/datastore/gnunet-service-datastore.c:1277 #, c-format msgid "Loading `%s' datastore plugin\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1332 +#: src/datastore/gnunet-service-datastore.c:1286 #, fuzzy, c-format msgid "Failed to load datastore plugin for `%s'\n" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/datastore/gnunet-service-datastore.c:1536 +#: src/datastore/gnunet-service-datastore.c:1488 #, fuzzy, c-format msgid "# bytes used in file-sharing datastore `%s'" msgstr "# byte krypterade" -#: src/datastore/gnunet-service-datastore.c:1547 +#: src/datastore/gnunet-service-datastore.c:1499 msgid "# quota" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1549 +#: src/datastore/gnunet-service-datastore.c:1501 msgid "# cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1562 +#: src/datastore/gnunet-service-datastore.c:1514 #, c-format msgid "Could not use specified filename `%s' for bloomfilter.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1580 -#: src/datastore/gnunet-service-datastore.c:1596 +#: src/datastore/gnunet-service-datastore.c:1532 +#: src/datastore/gnunet-service-datastore.c:1548 #, fuzzy, c-format msgid "Failed to remove bogus bloomfilter file `%s'\n" msgstr "Kunde inte spara konfigurationsfil \"%s\":" -#: src/datastore/gnunet-service-datastore.c:1626 +#: src/datastore/gnunet-service-datastore.c:1578 #, fuzzy msgid "Failed to initialize bloomfilter.\n" msgstr "Misslyckades att initiera tjänsten \"%s\".\n" -#: src/datastore/gnunet-service-datastore.c:1655 +#: src/datastore/gnunet-service-datastore.c:1607 msgid "Rebuilding bloomfilter. Please be patient.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1660 +#: src/datastore/gnunet-service-datastore.c:1612 msgid "Plugin does not support get_keys function. Please fix!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1663 +#: src/datastore/gnunet-service-datastore.c:1615 msgid "Bloomfilter construction complete.\n" msgstr "" -#: src/datastore/plugin_datastore_mysql.c:529 -#: src/datastore/plugin_datastore_mysql.c:1336 +#: src/datastore/plugin_datastore_mysql.c:780 #, fuzzy, c-format msgid "Failed to prepare statement `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/datastore/plugin_datastore_mysql.c:622 -#: src/datastore/plugin_datastore_mysql.c:1346 +#: src/datastore/plugin_datastore_mysql.c:788 #, fuzzy, c-format msgid "`%s' for `%s' failed at %s:%d with error: %s\n" msgstr "\"%s\" till \"%s\" misslyckades vid %s:%d med fel: %s\n" -#: src/datastore/plugin_datastore_mysql.c:1581 +#: src/datastore/plugin_datastore_mysql.c:1019 msgid "Mysql database running\n" msgstr "" -#: src/datastore/plugin_datastore_postgres.c:173 -#, fuzzy, c-format -msgid "Unable to initialize Postgres with configuration `%s': %s" -msgstr "Kunde inte spara konfigurationsfil \"%s\":" +#: src/datastore/plugin_datastore_postgres.c:824 +#, fuzzy +msgid "Failed to drop table from database.\n" +msgstr "Misslyckades att ta emot svar till \"%s\" meddelande frĂĽn gnunetd\n" -#: src/datastore/plugin_datastore_postgres.c:1017 +#: src/datastore/plugin_datastore_postgres.c:860 msgid "Postgres database running\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:61 +#: src/datastore/plugin_datastore_sqlite.c:57 #, fuzzy, c-format msgid "`%s' failed at %s:%u with error: %s" msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" -#: src/datastore/plugin_datastore_sqlite.c:239 -#: src/namestore/plugin_namestore_sqlite.c:223 +#: src/datastore/plugin_datastore_sqlite.c:233 +#: src/namestore/plugin_namestore_sqlite.c:204 #, fuzzy, c-format msgid "Option `%s' in section `%s' missing in configuration!\n" msgstr "Inga applikationer definierade i konfiguration!\n" -#: src/datastore/plugin_datastore_sqlite.c:266 -#: src/namestore/plugin_namestore_sqlite.c:248 +#: src/datastore/plugin_datastore_sqlite.c:260 +#: src/namestore/plugin_namestore_sqlite.c:229 #, fuzzy, c-format msgid "Unable to initialize SQLite: %s.\n" msgstr "Kunde inte initiera SQLite.\n" -#: src/datastore/plugin_datastore_sqlite.c:669 +#: src/datastore/plugin_datastore_sqlite.c:655 msgid "Invalid data in database. Trying to fix (by deletion).\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1159 +#: src/datastore/plugin_datastore_sqlite.c:1139 msgid "sqlite version to old to determine size, assuming zero\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1178 +#: src/datastore/plugin_datastore_sqlite.c:1158 #, c-format msgid "" "Using sqlite page utilization to estimate payload (%llu pages of size %llu " "bytes)\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1218 -#: src/namestore/plugin_namestore_sqlite.c:779 +#: src/datastore/plugin_datastore_sqlite.c:1198 +#: src/namestore/plugin_namestore_sqlite.c:829 msgid "Sqlite database running\n" msgstr "" @@ -1178,33 +1186,32 @@ msgstr "" msgid "Template database running\n" msgstr "" -#: src/dht/dht_api.c:280 +#: src/dht/dht_api.c:348 #, fuzzy msgid "Failed to connect to the DHT service!\n" msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-put.c:172 -#: src/gns/gnunet-gns-lookup.c:179 +#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-monitor.c:293 +#: src/dht/gnunet-dht-put.c:192 msgid "the query key" msgstr "" -#: src/dht/gnunet-dht-get.c:204 src/gns/gnunet-gns-lookup.c:182 +#: src/dht/gnunet-dht-get.c:204 msgid "how many parallel requests (replicas) to create" msgstr "" -#: src/dht/gnunet-dht-get.c:207 src/gns/gnunet-gns-lookup.c:185 +#: src/dht/gnunet-dht-get.c:207 src/dht/gnunet-dht-monitor.c:296 msgid "the type of data to look for" msgstr "" -#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:181 -#: src/gns/gnunet-gns-lookup.c:188 +#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:201 msgid "how long to execute this query before giving up?" msgstr "" -#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-put.c:184 -#: src/fs/gnunet-download.c:270 src/fs/gnunet-publish.c:725 -#: src/fs/gnunet-search.c:297 src/fs/gnunet-unindex.c:169 -#: src/gns/gnunet-gns-lookup.c:191 src/nse/gnunet-nse-profiler.c:908 +#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-monitor.c:302 +#: src/dht/gnunet-dht-put.c:204 src/fs/gnunet-download.c:271 +#: src/fs/gnunet-publish.c:731 src/fs/gnunet-search.c:297 +#: src/fs/gnunet-unindex.c:169 src/nse/gnunet-nse-profiler.c:910 msgid "be verbose (print progress information)" msgstr "" @@ -1212,99 +1219,116 @@ msgstr "" msgid "Issue a GET request to the GNUnet DHT, prints results." msgstr "" -#: src/dht/gnunet-dht-put.c:100 +#: src/dht/gnunet-dht-monitor.c:299 +msgid "how long to execute? 0 = forever" +msgstr "" + +#: src/dht/gnunet-dht-monitor.c:321 +msgid "Prints all packets that go through the DHT." +msgstr "" + +#: src/dht/gnunet-dht-put.c:108 msgid "PUT request sent!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:124 +#: src/dht/gnunet-dht-put.c:111 +msgid "Timeout sending PUT request!\n" +msgstr "" + +#: src/dht/gnunet-dht-put.c:114 +#, fuzzy +msgid "PUT request not confirmed!\n" +msgstr "# byte mottogs via TCP" + +#: src/dht/gnunet-dht-put.c:144 msgid "Must provide KEY and DATA for DHT put!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:132 +#: src/dht/gnunet-dht-put.c:152 #, fuzzy, c-format msgid "Could not connect to %s service!\n" msgstr "Kunde inte ansluta till gnunetd.\n" -#: src/dht/gnunet-dht-put.c:137 +#: src/dht/gnunet-dht-put.c:157 #, fuzzy, c-format msgid "Connected to %s service!\n" msgstr "\"%s\" ansluten till \"%s\".\n" -#: src/dht/gnunet-dht-put.c:152 +#: src/dht/gnunet-dht-put.c:172 #, c-format msgid "Issuing put request for `%s' with data `%s'!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:166 +#: src/dht/gnunet-dht-put.c:186 msgid "the data to insert under the key" msgstr "" -#: src/dht/gnunet-dht-put.c:169 +#: src/dht/gnunet-dht-put.c:189 msgid "how long to store this entry in the dht (in seconds)" msgstr "" -#: src/dht/gnunet-dht-put.c:175 +#: src/dht/gnunet-dht-put.c:195 msgid "how many replicas to create" msgstr "" -#: src/dht/gnunet-dht-put.c:178 +#: src/dht/gnunet-dht-put.c:198 msgid "the type to insert data as" msgstr "" -#: src/dht/gnunet-dht-put.c:203 +#: src/dht/gnunet-dht-put.c:223 msgid "Issue a PUT request to the GNUnet DHT insert DATA under KEY." msgstr "" -#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:556 -#: src/testing/testing.c:1979 src/testing/testing.c:2009 +#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:544 +#: src/testing/testing.c:1968 src/testing/testing.c:1998 #, fuzzy msgid "Failed to connect to transport service!\n" msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/dht/gnunet-service-dht_clients.c:371 +#: src/dht/gnunet-service-dht_clients.c:407 #, fuzzy msgid "# GET requests from clients injected" msgstr "# byte mottogs via TCP" -#: src/dht/gnunet-service-dht_clients.c:462 +#: src/dht/gnunet-service-dht_clients.c:500 #, fuzzy msgid "# PUT requests received from clients" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/dht/gnunet-service-dht_clients.c:529 +#: src/dht/gnunet-service-dht_clients.c:584 #, fuzzy msgid "# GET requests received from clients" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/dht/gnunet-service-dht_clients.c:624 +#: src/dht/gnunet-service-dht_clients.c:682 #, fuzzy msgid "# GET STOP requests received from clients" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/dht/gnunet-service-dht_clients.c:854 +#: src/dht/gnunet-service-dht_clients.c:919 msgid "# Key match, type mismatches in REPLY to CLIENT" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:869 +#: src/dht/gnunet-service-dht_clients.c:932 msgid "# Duplicate REPLIES to CLIENT request dropped" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:906 +#: src/dht/gnunet-service-dht_clients.c:967 #, c-format msgid "Unsupported block type (%u) in request!\n" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:928 +#: src/dht/gnunet-service-dht_clients.c:989 #, fuzzy msgid "# RESULTS queued for clients" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/dht/gnunet-service-dht_clients.c:979 -#: src/dht/gnunet-service-dht_clients.c:1022 +#: src/dht/gnunet-service-dht_clients.c:1038 +#: src/dht/gnunet-service-dht_clients.c:1081 msgid "# REPLIES ignored for CLIENTS (no match)" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:989 +#: src/dht/gnunet-service-dht_clients.c:1048 #, fuzzy msgid "Could not pass reply to client, message too big!\n" msgstr "Kunde inte skicka meddelande till gnunetd\n" @@ -1318,28 +1342,28 @@ msgstr "# byte mottagna av typen %d" msgid "# ITEMS stored in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:209 +#: src/dht/gnunet-service-dht_datacache.c:207 msgid "# Good RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:220 +#: src/dht/gnunet-service-dht_datacache.c:218 msgid "# Duplicate RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:226 +#: src/dht/gnunet-service-dht_datacache.c:224 msgid "# Invalid RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:238 +#: src/dht/gnunet-service-dht_datacache.c:236 msgid "# Unsupported RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:241 +#: src/dht/gnunet-service-dht_datacache.c:239 #, c-format msgid "Unsupported block type (%u) in local response!\n" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:271 +#: src/dht/gnunet-service-dht_datacache.c:269 #, fuzzy msgid "# GET requests given to datacache" msgstr "# byte mottogs via TCP" @@ -1353,95 +1377,89 @@ msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" msgid "# Preference updates given to core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:573 +#: src/dht/gnunet-service-dht_neighbours.c:571 #, fuzzy msgid "# FIND PEER messages initiated" msgstr "# PING-meddelanden skapade" -#: src/dht/gnunet-service-dht_neighbours.c:629 -#: src/dht/gnunet-service-dht_neighbours.c:689 -#, fuzzy -msgid "# Peers connected" -msgstr "# av anslutna parter" - -#: src/dht/gnunet-service-dht_neighbours.c:723 +#: src/dht/gnunet-service-dht_neighbours.c:717 #, fuzzy msgid "# Queued messages discarded (peer disconnected)" msgstr "Nätverksannonsering avstängd i konfigurationen!\n" -#: src/dht/gnunet-service-dht_neighbours.c:778 +#: src/dht/gnunet-service-dht_neighbours.c:772 #, fuzzy msgid "# Bytes transmitted to other peers" msgstr "# byte skickade av typen %d" -#: src/dht/gnunet-service-dht_neighbours.c:816 +#: src/dht/gnunet-service-dht_neighbours.c:810 msgid "# Bytes of bandwdith requested from core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1040 -#: src/dht/gnunet-service-dht_neighbours.c:1068 +#: src/dht/gnunet-service-dht_neighbours.c:1032 +#: src/dht/gnunet-service-dht_neighbours.c:1060 msgid "# Peers excluded from routing due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1049 -#: src/dht/gnunet-service-dht_neighbours.c:1085 +#: src/dht/gnunet-service-dht_neighbours.c:1041 +#: src/dht/gnunet-service-dht_neighbours.c:1075 msgid "# Peer selection failed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1221 +#: src/dht/gnunet-service-dht_neighbours.c:1207 #, fuzzy msgid "# PUT requests routed" msgstr "# byte mottogs via TCP" -#: src/dht/gnunet-service-dht_neighbours.c:1252 +#: src/dht/gnunet-service-dht_neighbours.c:1236 #, fuzzy msgid "# PUT messages queued for transmission" msgstr "# PING-meddelanden skapade" -#: src/dht/gnunet-service-dht_neighbours.c:1333 +#: src/dht/gnunet-service-dht_neighbours.c:1315 #, fuzzy msgid "# GET requests routed" msgstr "# byte mottogs via TCP" -#: src/dht/gnunet-service-dht_neighbours.c:1364 +#: src/dht/gnunet-service-dht_neighbours.c:1342 #, fuzzy msgid "# GET messages queued for transmission" msgstr "# PING-meddelanden skapade" -#: src/dht/gnunet-service-dht_neighbours.c:1467 +#: src/dht/gnunet-service-dht_neighbours.c:1443 #, fuzzy msgid "# RESULT messages queued for transmission" msgstr "# PING-meddelanden skapade" -#: src/dht/gnunet-service-dht_neighbours.c:1555 +#: src/dht/gnunet-service-dht_neighbours.c:1531 #, fuzzy msgid "# P2P PUT requests received" msgstr "# byte mottogs via TCP" -#: src/dht/gnunet-service-dht_neighbours.c:1668 +#: src/dht/gnunet-service-dht_neighbours.c:1647 msgid "# FIND PEER requests ignored due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1676 +#: src/dht/gnunet-service-dht_neighbours.c:1655 msgid "# FIND PEER requests ignored due to lack of HELLO" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1767 +#: src/dht/gnunet-service-dht_neighbours.c:1746 #, fuzzy msgid "# P2P GET requests received" msgstr "# byte mottogs via TCP" -#: src/dht/gnunet-service-dht_neighbours.c:1811 +#: src/dht/gnunet-service-dht_neighbours.c:1788 #, fuzzy msgid "# P2P FIND PEER requests processed" msgstr "# byte mottogs via TCP" -#: src/dht/gnunet-service-dht_neighbours.c:1825 +#: src/dht/gnunet-service-dht_neighbours.c:1802 #, fuzzy msgid "# P2P GET requests ONLY routed" msgstr "# byte mottogs via TCP" -#: src/dht/gnunet-service-dht_neighbours.c:1895 +#: src/dht/gnunet-service-dht_neighbours.c:1876 #, fuzzy msgid "# P2P RESULTS received" msgstr "# krypterade PONG-meddelanden mottagna" @@ -1463,29 +1481,28 @@ msgstr "" msgid "# Invalid REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:236 +#: src/dht/gnunet-service-dht_routing.c:238 msgid "# Unsupported REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:314 -#: src/dht/gnunet-service-dht_routing.c:368 +#: src/dht/gnunet-service-dht_routing.c:311 msgid "# Entries removed from routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:324 +#: src/dht/gnunet-service-dht_routing.c:352 msgid "# Entries added to routing table" msgstr "" -#: src/dht/plugin_block_dht.c:124 +#: src/dht/plugin_block_dht.c:136 #, fuzzy, c-format msgid "Block not of type %u\n" msgstr "Ingen transport av typ %d är känd.\n" -#: src/dht/plugin_block_dht.c:131 +#: src/dht/plugin_block_dht.c:143 msgid "Size mismatch for block\n" msgstr "" -#: src/dht/plugin_block_dht.c:140 +#: src/dht/plugin_block_dht.c:152 #, c-format msgid "Block of type %u is malformed\n" msgstr "" @@ -1514,68 +1531,69 @@ msgstr "" msgid "Change DNS replies to point elsewhere." msgstr "" -#: src/dns/gnunet-service-dns.c:480 +#: src/dns/gnunet-service-dns.c:485 #, fuzzy, c-format msgid "Could not bind to any port: %s\n" msgstr "Kunde inte kĂśra \"%s\": %s\n" -#: src/dns/gnunet-service-dns.c:634 +#: src/dns/gnunet-service-dns.c:639 msgid "# DNS requests answered via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:818 +#: src/dns/gnunet-service-dns.c:822 msgid "# DNS exit failed (failed to open socket)" msgstr "" -#: src/dns/gnunet-service-dns.c:1001 +#: src/dns/gnunet-service-dns.c:1005 #, c-format msgid "Received DNS response that is too small (%u bytes)" msgstr "" -#: src/dns/gnunet-service-dns.c:1046 +#: src/dns/gnunet-service-dns.c:1050 msgid "# External DNS response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1165 +#: src/dns/gnunet-service-dns.c:1168 msgid "# Client response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1198 -msgid "Changing DNS reply according to client specifications\n" -msgstr "" - -#: src/dns/gnunet-service-dns.c:1279 +#: src/dns/gnunet-service-dns.c:1281 msgid "Received malformed IPv4-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1294 +#: src/dns/gnunet-service-dns.c:1297 msgid "Received malformed IPv6-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1303 +#: src/dns/gnunet-service-dns.c:1306 #, c-format msgid "Got non-IP packet with %u bytes and protocol %u from TUN\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1312 +#: src/dns/gnunet-service-dns.c:1315 msgid "# Non-DNS UDP packet received via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:1377 +#: src/dns/gnunet-service-dns.c:1380 #, fuzzy msgid "# DNS requests received via TUN interface" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/dns/gnunet-service-dns.c:1461 +#: src/dns/gnunet-service-dns.c:1465 #, c-format msgid "Configured DNS exit `%s' is not working / valid.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1493 src/exit/gnunet-daemon-exit.c:2673 +#: src/dns/gnunet-service-dns.c:1497 src/exit/gnunet-daemon-exit.c:2674 msgid "# Inbound MESH tunnels created" msgstr "" -#: src/dns/gnunet-service-dns.c:1567 +#: src/dns/gnunet-service-dns.c:1561 src/exit/gnunet-daemon-exit.c:3032 +#, c-format +msgid "`%s' must be installed SUID, refusing to run\n" +msgstr "" + +#: src/dns/gnunet-service-dns.c:1581 msgid "Configured to provide DNS exit, but no valid DNS server configured!\n" msgstr "" @@ -1599,15 +1617,15 @@ msgstr "" msgid "# Bytes transmitted via mesh tunnels" msgstr "# byte skickade av typen %d" -#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2068 -#: src/exit/gnunet-daemon-exit.c:2318 src/vpn/gnunet-service-vpn.c:1388 -#: src/vpn/gnunet-service-vpn.c:1788 src/vpn/gnunet-service-vpn.c:1951 +#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2069 +#: src/exit/gnunet-daemon-exit.c:2319 src/vpn/gnunet-service-vpn.c:1394 +#: src/vpn/gnunet-service-vpn.c:1795 src/vpn/gnunet-service-vpn.c:1958 msgid "# ICMPv4 packets dropped (type not allowed)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2127 -#: src/exit/gnunet-daemon-exit.c:2377 src/vpn/gnunet-service-vpn.c:1444 -#: src/vpn/gnunet-service-vpn.c:1847 src/vpn/gnunet-service-vpn.c:1984 +#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2128 +#: src/exit/gnunet-daemon-exit.c:2378 src/vpn/gnunet-service-vpn.c:1450 +#: src/vpn/gnunet-service-vpn.c:1854 src/vpn/gnunet-service-vpn.c:1991 msgid "# ICMPv6 packets dropped (type not allowed)" msgstr "" @@ -1656,137 +1674,137 @@ msgstr "" msgid "Packet from unknown protocol %u received. Ignored.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1470 +#: src/exit/gnunet-daemon-exit.c:1471 #, fuzzy msgid "# TCP packets sent via TUN" msgstr "# byte skickade via UDP" -#: src/exit/gnunet-daemon-exit.c:1570 +#: src/exit/gnunet-daemon-exit.c:1571 msgid "# TCP service creation requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1573 src/exit/gnunet-daemon-exit.c:1652 -#: src/exit/gnunet-daemon-exit.c:1762 src/exit/gnunet-daemon-exit.c:1992 -#: src/exit/gnunet-daemon-exit.c:2234 src/exit/gnunet-daemon-exit.c:2515 -#: src/exit/gnunet-daemon-exit.c:2615 +#: src/exit/gnunet-daemon-exit.c:1574 src/exit/gnunet-daemon-exit.c:1653 +#: src/exit/gnunet-daemon-exit.c:1763 src/exit/gnunet-daemon-exit.c:1993 +#: src/exit/gnunet-daemon-exit.c:2235 src/exit/gnunet-daemon-exit.c:2516 +#: src/exit/gnunet-daemon-exit.c:2616 #, fuzzy msgid "# Bytes received from MESH" msgstr "# byte mottagna via HTTP" -#: src/exit/gnunet-daemon-exit.c:1606 src/exit/gnunet-daemon-exit.c:2637 +#: src/exit/gnunet-daemon-exit.c:1607 src/exit/gnunet-daemon-exit.c:2638 #, c-format msgid "No service found for %s on port %d!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1610 +#: src/exit/gnunet-daemon-exit.c:1611 #, fuzzy msgid "# TCP requests dropped (no such service)" msgstr "# byte mottogs via TCP" -#: src/exit/gnunet-daemon-exit.c:1655 +#: src/exit/gnunet-daemon-exit.c:1656 #, fuzzy msgid "# TCP IP-exit creation requests received via mesh" msgstr "# byte mottogs via TCP" -#: src/exit/gnunet-daemon-exit.c:1765 +#: src/exit/gnunet-daemon-exit.c:1766 #, fuzzy msgid "# TCP data requests received via mesh" msgstr "# byte mottogs via TCP" -#: src/exit/gnunet-daemon-exit.c:1779 +#: src/exit/gnunet-daemon-exit.c:1780 #, fuzzy msgid "# TCP DATA requests dropped (no session)" msgstr "# byte mottogs via TCP" -#: src/exit/gnunet-daemon-exit.c:1829 +#: src/exit/gnunet-daemon-exit.c:1830 #, fuzzy msgid "# ICMP packets sent via TUN" msgstr "# byte skickade via UDP" -#: src/exit/gnunet-daemon-exit.c:1995 +#: src/exit/gnunet-daemon-exit.c:1996 #, fuzzy msgid "# ICMP IP-exit requests received via mesh" msgstr "# byte mottogs via TCP" -#: src/exit/gnunet-daemon-exit.c:2237 +#: src/exit/gnunet-daemon-exit.c:2238 #, fuzzy msgid "# ICMP service requests received via mesh" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/exit/gnunet-daemon-exit.c:2303 src/vpn/gnunet-service-vpn.c:1378 -#: src/vpn/gnunet-service-vpn.c:1945 +#: src/exit/gnunet-daemon-exit.c:2304 src/vpn/gnunet-service-vpn.c:1384 +#: src/vpn/gnunet-service-vpn.c:1952 msgid "# ICMPv4 packets dropped (impossible PT to v6)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2362 src/vpn/gnunet-service-vpn.c:1414 -#: src/vpn/gnunet-service-vpn.c:1426 src/vpn/gnunet-service-vpn.c:1835 +#: src/exit/gnunet-daemon-exit.c:2363 src/vpn/gnunet-service-vpn.c:1420 +#: src/vpn/gnunet-service-vpn.c:1432 src/vpn/gnunet-service-vpn.c:1842 msgid "# ICMPv6 packets dropped (impossible PT to v4)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2412 +#: src/exit/gnunet-daemon-exit.c:2413 #, fuzzy msgid "# UDP packets sent via TUN" msgstr "# byte skickade via UDP" -#: src/exit/gnunet-daemon-exit.c:2518 +#: src/exit/gnunet-daemon-exit.c:2519 #, fuzzy msgid "# UDP IP-exit requests received via mesh" msgstr "# byte mottogs via TCP" -#: src/exit/gnunet-daemon-exit.c:2618 +#: src/exit/gnunet-daemon-exit.c:2619 #, fuzzy msgid "# UDP service requests received via mesh" msgstr "# byte mottogs via TCP" -#: src/exit/gnunet-daemon-exit.c:2641 +#: src/exit/gnunet-daemon-exit.c:2642 #, fuzzy msgid "# UDP requests dropped (no such service)" msgstr "# byte mottogs via TCP" -#: src/exit/gnunet-daemon-exit.c:2881 +#: src/exit/gnunet-daemon-exit.c:2882 #, c-format msgid "No addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2895 src/exit/gnunet-daemon-exit.c:2907 +#: src/exit/gnunet-daemon-exit.c:2896 src/exit/gnunet-daemon-exit.c:2908 #, c-format msgid "Service `%s' configured for IPv4, but IPv4 is disabled!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2918 +#: src/exit/gnunet-daemon-exit.c:2919 #, c-format msgid "No IP addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3047 +#: src/exit/gnunet-daemon-exit.c:3048 msgid "" "This system does not support IPv4, will disable IPv4 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3055 +#: src/exit/gnunet-daemon-exit.c:3056 msgid "" "This system does not support IPv6, will disable IPv6 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3062 +#: src/exit/gnunet-daemon-exit.c:3063 msgid "" "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use " "ENABLE_IPv4=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3068 +#: src/exit/gnunet-daemon-exit.c:3069 msgid "" "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use " "ENABLE_IPv6=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3074 src/pt/gnunet-daemon-pt.c:884 +#: src/exit/gnunet-daemon-exit.c:3075 src/pt/gnunet-daemon-pt.c:884 msgid "No useful service enabled. Exiting.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3235 +#: src/exit/gnunet-daemon-exit.c:3236 msgid "Daemon to run to provide an IP exit node for the VPN" msgstr "" @@ -1794,121 +1812,126 @@ msgstr "" msgid "# acknowledgements sent for fragment" msgstr "" -#: src/fragmentation/defragmentation.c:454 +#: src/fragmentation/defragmentation.c:456 #, fuzzy msgid "# fragments received" msgstr "# byte mottogs via TCP" -#: src/fragmentation/defragmentation.c:513 +#: src/fragmentation/defragmentation.c:521 #, fuzzy msgid "# duplicate fragments received" msgstr "# byte mottogs via TCP" -#: src/fragmentation/defragmentation.c:526 +#: src/fragmentation/defragmentation.c:534 msgid "# messages defragmented" msgstr "" -#: src/fragmentation/fragmentation.c:188 +#: src/fragmentation/fragmentation.c:203 #, fuzzy msgid "# fragments transmitted" msgstr "# byte skickade av typen %d" -#: src/fragmentation/fragmentation.c:191 +#: src/fragmentation/fragmentation.c:206 #, fuzzy msgid "# fragments retransmitted" msgstr "# byte skickade av typen %d" -#: src/fragmentation/fragmentation.c:255 +#: src/fragmentation/fragmentation.c:232 +#, fuzzy +msgid "# fragments wrap arounds" +msgstr "# byte skickade av typen %d" + +#: src/fragmentation/fragmentation.c:273 msgid "# messages fragmented" msgstr "" -#: src/fragmentation/fragmentation.c:258 +#: src/fragmentation/fragmentation.c:276 msgid "# total size of fragmented messages" msgstr "" -#: src/fragmentation/fragmentation.c:343 +#: src/fragmentation/fragmentation.c:363 msgid "# fragment acknowledgements received" msgstr "" -#: src/fragmentation/fragmentation.c:349 +#: src/fragmentation/fragmentation.c:369 msgid "# bits removed from fragmentation ACKs" msgstr "" -#: src/fragmentation/fragmentation.c:373 +#: src/fragmentation/fragmentation.c:393 #, fuzzy msgid "# fragmentation transmissions completed" msgstr "# klartext PONG-meddelanden mottagna" -#: src/fs/fs_api.c:284 +#: src/fs/fs_api.c:339 #, fuzzy, c-format msgid "Could not open file `%s': %s" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/fs/fs_api.c:293 +#: src/fs/fs_api.c:348 #, fuzzy, c-format msgid "Could not read file `%s': %s" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/fs/fs_api.c:299 +#: src/fs/fs_api.c:354 #, c-format msgid "Short read reading from file `%s'!" msgstr "" -#: src/fs/fs_api.c:877 +#: src/fs/fs_api.c:938 #, fuzzy, c-format msgid "Failed to resume publishing information `%s': %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/fs_api.c:1334 +#: src/fs/fs_api.c:1395 #, c-format msgid "Failed to recover namespace `%s', cannot resume publishing operation.\n" msgstr "" -#: src/fs/fs_api.c:1376 +#: src/fs/fs_api.c:1437 #, c-format msgid "Failure while resuming publishing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:1392 +#: src/fs/fs_api.c:1453 #, fuzzy, c-format msgid "Failed to resume publishing operation `%s': %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/fs_api.c:2004 +#: src/fs/fs_api.c:2106 #, c-format msgid "Failure while resuming unindexing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2014 +#: src/fs/fs_api.c:2116 #, fuzzy, c-format msgid "Failed to resume unindexing operation `%s': %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/fs_api.c:2139 src/fs/fs_api.c:2378 +#: src/fs/fs_api.c:2241 src/fs/fs_api.c:2480 #, fuzzy, c-format msgid "Failed to resume sub-download `%s': %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/fs_api.c:2156 +#: src/fs/fs_api.c:2258 #, fuzzy, c-format msgid "Failed to resume sub-search `%s': %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/fs_api.c:2168 src/fs/fs_api.c:2187 src/fs/fs_api.c:2671 +#: src/fs/fs_api.c:2270 src/fs/fs_api.c:2289 src/fs/fs_api.c:2773 #, c-format msgid "Failure while resuming search operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2369 +#: src/fs/fs_api.c:2471 #, c-format msgid "Failed to resume sub-download `%s': could not open file `%s'\n" msgstr "" -#: src/fs/fs_api.c:2615 +#: src/fs/fs_api.c:2717 msgid "Could not resume running search, will resume as paused search\n" msgstr "" -#: src/fs/fs_api.c:2709 +#: src/fs/fs_api.c:2811 #, c-format msgid "Failure while resuming download operation `%s': %s\n" msgstr "" @@ -1918,53 +1941,58 @@ msgstr "" msgid "MAGIC mismatch. This is not a GNUnet directory.\n" msgstr "Filformatsfel (inte en GNUnet-katalog?)\n" -#: src/fs/fs_download.c:310 +#: src/fs/fs_download.c:311 msgid "" "Recursive downloads of directories larger than 4 GB are not supported on 32-" "bit systems\n" msgstr "" -#: src/fs/fs_download.c:330 +#: src/fs/fs_download.c:331 msgid "Directory too large for system address space\n" msgstr "" -#: src/fs/fs_download.c:488 src/fs/fs_download.c:500 +#: src/fs/fs_download.c:497 src/fs/fs_download.c:509 #, fuzzy, c-format msgid "Failed to open file `%s' for writing" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/fs_download.c:870 +#: src/fs/fs_download.c:878 #, fuzzy, c-format msgid "Failed to create directory for recursive download of `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/fs/fs_download.c:951 +#: src/fs/fs_download.c:960 #, c-format msgid "" "Internal error or bogus download URI (expected %u bytes at depth %u and " -"offset %llu/%llu, got %u bytes)\n" +"offset %llu/%llu, got %u bytes)" msgstr "" -#: src/fs/fs_download.c:977 +#: src/fs/fs_download.c:986 msgid "internal error decrypting content" msgstr "" -#: src/fs/fs_download.c:1000 +#: src/fs/fs_download.c:1009 #, fuzzy, c-format -msgid "Download failed: could not open file `%s': %s\n" +msgid "Download failed: could not open file `%s': %s" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/fs/fs_download.c:1010 +#: src/fs/fs_download.c:1019 #, fuzzy, c-format -msgid "Failed to seek to offset %llu in file `%s': %s\n" +msgid "Failed to seek to offset %llu in file `%s': %s" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/fs_download.c:1019 -#, c-format -msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s\n" -msgstr "" +#: src/fs/fs_download.c:1028 +#, fuzzy, c-format +msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s" +msgstr "Misslyckades att leverera \"%s\" meddelande.\n" + +#: src/fs/fs_download.c:1125 +#, fuzzy +msgid "internal error decoding tree" +msgstr "=\tFel vid läsning av katalog.\n" -#: src/fs/fs_download.c:1835 +#: src/fs/fs_download.c:1888 #, fuzzy msgid "Invalid URI" msgstr "Ogiltiga argument: " @@ -2046,68 +2074,68 @@ msgstr "Okänt fel.\n" msgid "Failed to connect to datastore." msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:395 +#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:397 #, fuzzy, c-format msgid "Publishing failed: %s" msgstr "" "\n" "Fel vid uppladdning av fil: %s\n" -#: src/fs/fs_publish.c:616 src/fs/fs_publish.c:633 src/fs/fs_publish.c:672 -#: src/fs/fs_publish.c:692 src/fs/fs_publish.c:717 src/fs/fs_publish.c:857 +#: src/fs/fs_publish.c:621 src/fs/fs_publish.c:638 src/fs/fs_publish.c:677 +#: src/fs/fs_publish.c:697 src/fs/fs_publish.c:722 src/fs/fs_publish.c:862 #, fuzzy, c-format msgid "Can not index file `%s': %s. Will try to insert instead.\n" msgstr "Indexering av fil \"%s\" misslyckades. FĂśrsĂśker att infoga fil...\n" -#: src/fs/fs_publish.c:618 +#: src/fs/fs_publish.c:623 msgid "timeout on index-start request to `fs' service" msgstr "" -#: src/fs/fs_publish.c:630 +#: src/fs/fs_publish.c:635 #, fuzzy msgid "unknown error" msgstr "Okänt fel" -#: src/fs/fs_publish.c:673 +#: src/fs/fs_publish.c:678 msgid "failed to compute hash" msgstr "" -#: src/fs/fs_publish.c:693 +#: src/fs/fs_publish.c:698 msgid "filename too long" msgstr "" -#: src/fs/fs_publish.c:718 +#: src/fs/fs_publish.c:723 #, fuzzy msgid "could not connect to `fs' service" msgstr "Kunde inte ansluta till gnunetd.\n" -#: src/fs/fs_publish.c:741 +#: src/fs/fs_publish.c:746 #, fuzzy, c-format msgid "Failed to get file identifiers for `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/fs/fs_publish.c:806 +#: src/fs/fs_publish.c:811 #, fuzzy, c-format msgid "Recursive upload failed at `%s': %s" msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n" -#: src/fs/fs_publish.c:812 +#: src/fs/fs_publish.c:817 #, fuzzy, c-format msgid "Recursive upload failed: %s" msgstr "" "\n" "Fel vid uppladdning av fil: %s\n" -#: src/fs/fs_publish.c:858 +#: src/fs/fs_publish.c:863 msgid "needs to be an actual file" msgstr "" -#: src/fs/fs_publish.c:1067 +#: src/fs/fs_publish.c:1071 #, c-format msgid "Insufficient space for publishing: %s" msgstr "" -#: src/fs/fs_publish.c:1138 +#: src/fs/fs_publish.c:1142 #, c-format msgid "Reserving space for %u entries and %llu bytes for publication\n" msgstr "" @@ -2117,7 +2145,7 @@ msgstr "" msgid "Could not connect to datastore." msgstr "Kunde inte ansluta till gnunetd.\n" -#: src/fs/fs_search.c:810 +#: src/fs/fs_search.c:829 #, c-format msgid "Got result with unknown block type `%d', ignoring" msgstr "" @@ -2127,44 +2155,64 @@ msgstr "" msgid "Failed to start daemon: %s\n" msgstr "Misslyckades att starta samling.\n" -#: src/fs/fs_unindex.c:57 +#: src/fs/fs_unindex.c:58 msgid "Failed to find given position in file" msgstr "" -#: src/fs/fs_unindex.c:62 +#: src/fs/fs_unindex.c:63 #, fuzzy msgid "Failed to read file" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/fs_unindex.c:231 +#: src/fs/fs_unindex.c:233 msgid "Unexpected time for a response from `fs' service." msgstr "" -#: src/fs/fs_unindex.c:239 +#: src/fs/fs_unindex.c:241 msgid "Timeout waiting for `fs' service." msgstr "" -#: src/fs/fs_unindex.c:247 +#: src/fs/fs_unindex.c:249 #, fuzzy msgid "Invalid response from `fs' service." msgstr "Ogiltigt svar till \"%s\" frĂĽn \"%s\"\n" -#: src/fs/fs_unindex.c:292 +#: src/fs/fs_unindex.c:293 #, fuzzy msgid "Failed to connect to FS service for unindexing." msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/fs/fs_unindex.c:325 +#: src/fs/fs_unindex.c:344 +#, fuzzy +msgid "Failed to get KSKs from directory scan." +msgstr "Filformatsfel (inte en GNUnet-katalog?)\n" + +#: src/fs/fs_unindex.c:356 +#, fuzzy, c-format +msgid "Internal error scanning `%s'.\n" +msgstr "=\tFel vid läsning av katalog.\n" + +#: src/fs/fs_unindex.c:411 +#, fuzzy, c-format +msgid "Failed to remove KBlock: %s\n" +msgstr "Misslyckades att leverera \"%s\" meddelande.\n" + +#: src/fs/fs_unindex.c:501 +#, fuzzy, c-format +msgid "Failed to parse URI `%s' from KBlock!\n" +msgstr "Fil \"%s\" har URI: %s\n" + +#: src/fs/fs_unindex.c:553 src/fs/fs_unindex.c:618 #, fuzzy msgid "Failed to connect to `datastore' service." msgstr "Misslyckades att initiera tjänsten \"%s\".\n" -#: src/fs/fs_unindex.c:338 +#: src/fs/fs_unindex.c:631 #, fuzzy msgid "Failed to open file for unindexing." msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/fs/fs_unindex.c:372 +#: src/fs/fs_unindex.c:665 #, fuzzy msgid "Failed to compute hash of file." msgstr "Misslyckades att ansluta till gnunetd.\n" @@ -2277,92 +2325,92 @@ msgstr "Filformatsfel (inte en GNUnet-katalog?)\n" msgid "Display contents of a GNUnet directory" msgstr "Filformatsfel (inte en GNUnet-katalog?)\n" -#: src/fs/gnunet-download.c:100 +#: src/fs/gnunet-download.c:101 #, fuzzy, c-format msgid "Starting download `%s'.\n" msgstr "Startade samling \"%s\".\n" -#: src/fs/gnunet-download.c:109 +#: src/fs/gnunet-download.c:110 #, fuzzy msgid "" msgstr "Okänt fel" -#: src/fs/gnunet-download.c:118 +#: src/fs/gnunet-download.c:119 #, c-format msgid "" "Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to " "download\n" msgstr "" -#: src/fs/gnunet-download.c:128 +#: src/fs/gnunet-download.c:129 #, fuzzy, c-format msgid "Error downloading: %s.\n" msgstr "Fel vid nedladdning: %s\n" -#: src/fs/gnunet-download.c:136 +#: src/fs/gnunet-download.c:137 #, fuzzy, c-format msgid "Downloading `%s' done (%s/s).\n" msgstr "Uppladdning vägrades!" -#: src/fs/gnunet-download.c:151 src/fs/gnunet-publish.c:190 +#: src/fs/gnunet-download.c:152 src/fs/gnunet-publish.c:190 #: src/fs/gnunet-search.c:190 src/fs/gnunet-unindex.c:109 #, c-format msgid "Unexpected status: %d\n" msgstr "" -#: src/fs/gnunet-download.c:176 +#: src/fs/gnunet-download.c:177 #, fuzzy msgid "You need to specify a URI argument.\n" msgstr "Du mĂĽste ange en och endast en fil att avindexera.\n" -#: src/fs/gnunet-download.c:182 src/fs/gnunet-publish.c:618 +#: src/fs/gnunet-download.c:183 src/fs/gnunet-publish.c:624 #, fuzzy, c-format msgid "Failed to parse URI: %s\n" msgstr "Fil \"%s\" har URI: %s\n" -#: src/fs/gnunet-download.c:189 +#: src/fs/gnunet-download.c:190 msgid "Only CHK or LOC URIs supported.\n" msgstr "" -#: src/fs/gnunet-download.c:196 +#: src/fs/gnunet-download.c:197 msgid "Target filename must be specified.\n" msgstr "" -#: src/fs/gnunet-download.c:210 src/fs/gnunet-publish.c:596 +#: src/fs/gnunet-download.c:211 src/fs/gnunet-publish.c:602 #: src/fs/gnunet-search.c:241 src/fs/gnunet-unindex.c:141 #, fuzzy, c-format msgid "Could not initialize `%s' subsystem.\n" msgstr "Misslyckades att initiera tjänsten \"%s\".\n" -#: src/fs/gnunet-download.c:247 src/fs/gnunet-search.c:285 +#: src/fs/gnunet-download.c:248 src/fs/gnunet-search.c:285 msgid "set the desired LEVEL of receiver-anonymity" msgstr "" -#: src/fs/gnunet-download.c:250 +#: src/fs/gnunet-download.c:251 msgid "delete incomplete downloads (when aborted with CTRL-C)" msgstr "" -#: src/fs/gnunet-download.c:253 src/fs/gnunet-search.c:288 +#: src/fs/gnunet-download.c:254 src/fs/gnunet-search.c:288 msgid "only search the local peer (no P2P network search)" msgstr "" -#: src/fs/gnunet-download.c:256 +#: src/fs/gnunet-download.c:257 msgid "write the file to FILENAME" msgstr "skriv filen till FILNAMN" -#: src/fs/gnunet-download.c:260 +#: src/fs/gnunet-download.c:261 msgid "set the maximum number of parallel downloads that is allowed" msgstr "" -#: src/fs/gnunet-download.c:264 +#: src/fs/gnunet-download.c:265 msgid "set the maximum number of parallel requests for blocks that is allowed" msgstr "" -#: src/fs/gnunet-download.c:267 +#: src/fs/gnunet-download.c:268 msgid "download a GNUnet directory recursively" msgstr "hämta en GNUnet-katalog rekursivt" -#: src/fs/gnunet-download.c:277 +#: src/fs/gnunet-download.c:278 msgid "" "Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/" "chk/...)" @@ -2377,70 +2425,65 @@ msgstr "" msgid "Special file-sharing operations" msgstr "Visa alla alternativ" -#: src/fs/gnunet-pseudonym.c:151 src/statistics/gnunet-statistics.c:126 +#: src/fs/gnunet-pseudonym.c:160 src/statistics/gnunet-statistics.c:167 #, fuzzy, c-format msgid "Invalid argument `%s'\n" msgstr "Ogiltigt argument: \"%s\"\n" -#: src/fs/gnunet-pseudonym.c:165 -#, fuzzy, c-format -msgid "Namespace `%s' unknown.\n" -msgstr "Namnrymd \"%s\" skapad(rot: %s).\n" - -#: src/fs/gnunet-pseudonym.c:240 src/fs/gnunet-pseudonym.c:247 -#: src/fs/gnunet-pseudonym.c:249 +#: src/fs/gnunet-pseudonym.c:250 src/fs/gnunet-pseudonym.c:257 +#: src/fs/gnunet-pseudonym.c:259 #, fuzzy, c-format msgid "Option `%s' ignored\n" msgstr "%s: flagga \"%s\" är tvetydig\n" -#: src/fs/gnunet-pseudonym.c:269 src/fs/gnunet-publish.c:672 +#: src/fs/gnunet-pseudonym.c:279 src/fs/gnunet-publish.c:678 msgid "set the desired LEVEL of sender-anonymity" msgstr "" -#: src/fs/gnunet-pseudonym.c:272 +#: src/fs/gnunet-pseudonym.c:282 msgid "create or advertise namespace NAME" msgstr "" -#: src/fs/gnunet-pseudonym.c:275 +#: src/fs/gnunet-pseudonym.c:285 msgid "delete namespace NAME " msgstr "" -#: src/fs/gnunet-pseudonym.c:278 +#: src/fs/gnunet-pseudonym.c:288 msgid "" "add an additional keyword for the advertisment (this option can be specified " "multiple times)" msgstr "" -#: src/fs/gnunet-pseudonym.c:282 src/fs/gnunet-publish.c:691 +#: src/fs/gnunet-pseudonym.c:292 src/fs/gnunet-publish.c:697 msgid "set the meta-data for the given TYPE to the given VALUE" msgstr "" -#: src/fs/gnunet-pseudonym.c:285 +#: src/fs/gnunet-pseudonym.c:295 msgid "print names of local namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:288 +#: src/fs/gnunet-pseudonym.c:298 msgid "use the given PRIORITY for the advertisments" msgstr "" -#: src/fs/gnunet-pseudonym.c:291 +#: src/fs/gnunet-pseudonym.c:301 msgid "do not print names of remote namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:294 src/fs/gnunet-publish.c:710 +#: src/fs/gnunet-pseudonym.c:304 src/fs/gnunet-publish.c:716 msgid "set the desired replication LEVEL" msgstr "" -#: src/fs/gnunet-pseudonym.c:297 +#: src/fs/gnunet-pseudonym.c:307 #, fuzzy msgid "specify ID of the root of the namespace" msgstr "ange prioritet fĂśr innehĂĽllet" -#: src/fs/gnunet-pseudonym.c:300 +#: src/fs/gnunet-pseudonym.c:310 msgid "change rating of namespace ID by VALUE" msgstr "" -#: src/fs/gnunet-pseudonym.c:308 +#: src/fs/gnunet-pseudonym.c:318 msgid "Manage GNUnet pseudonyms." msgstr "" @@ -2469,165 +2512,165 @@ msgstr "Jag är ändpunkt \"%s\".\n" msgid "Cleanup after abort complete.\n" msgstr "\"%s\" uppstart klar.\n" -#: src/fs/gnunet-publish.c:299 +#: src/fs/gnunet-publish.c:305 #, fuzzy, c-format msgid "Meta data for file `%s' (%s)\n" msgstr "Uppdaterar data fĂśr modul \"%s\"\n" -#: src/fs/gnunet-publish.c:301 +#: src/fs/gnunet-publish.c:307 #, fuzzy, c-format msgid "Keywords for file `%s' (%s)\n" msgstr "Nyckelord fĂśr fil \"%s\":\n" -#: src/fs/gnunet-publish.c:352 +#: src/fs/gnunet-publish.c:358 #, fuzzy, c-format msgid "Failed to create namespace `%s'\n" msgstr "Kunde inte skapa namnrymd \"%s\" (existerar?).\n" -#: src/fs/gnunet-publish.c:427 +#: src/fs/gnunet-publish.c:433 #, fuzzy msgid "Could not publish\n" msgstr "Kunde inte kĂśra \"%s\": %s\n" -#: src/fs/gnunet-publish.c:454 +#: src/fs/gnunet-publish.c:460 #, fuzzy msgid "Could not start publishing.\n" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/fs/gnunet-publish.c:485 +#: src/fs/gnunet-publish.c:491 #, fuzzy, c-format msgid "Scanning directory `%s'.\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/fs/gnunet-publish.c:487 +#: src/fs/gnunet-publish.c:493 #, fuzzy, c-format msgid "Scanning file `%s'.\n" msgstr "Startade samling \"%s\".\n" -#: src/fs/gnunet-publish.c:492 +#: src/fs/gnunet-publish.c:498 #, c-format msgid "There was trouble processing file `%s', skipping it.\n" msgstr "" -#: src/fs/gnunet-publish.c:497 +#: src/fs/gnunet-publish.c:503 #, fuzzy msgid "Preprocessing complete.\n" msgstr "Nedstängning klar.\n" -#: src/fs/gnunet-publish.c:501 +#: src/fs/gnunet-publish.c:507 #, fuzzy, c-format msgid "Extracting meta data from file `%s' complete.\n" msgstr "Uppdaterar data fĂśr modul \"%s\"\n" -#: src/fs/gnunet-publish.c:505 +#: src/fs/gnunet-publish.c:511 msgid "Meta data extraction has finished.\n" msgstr "" -#: src/fs/gnunet-publish.c:512 +#: src/fs/gnunet-publish.c:518 #, fuzzy msgid "Internal error scanning directory.\n" msgstr "=\tFel vid läsning av katalog.\n" -#: src/fs/gnunet-publish.c:546 +#: src/fs/gnunet-publish.c:552 #, c-format msgid "Cannot extract metadata from a URI!\n" msgstr "" -#: src/fs/gnunet-publish.c:553 +#: src/fs/gnunet-publish.c:559 #, fuzzy, c-format msgid "You must specify one and only one filename for insertion.\n" msgstr "Du mĂĽste ange en och endast en fil att avindexera.\n" -#: src/fs/gnunet-publish.c:559 +#: src/fs/gnunet-publish.c:565 #, fuzzy, c-format msgid "You must NOT specify an URI and a filename.\n" msgstr "Du mĂĽste ange en och endast en fil att avindexera.\n" -#: src/fs/gnunet-publish.c:567 src/vpn/gnunet-vpn.c:214 +#: src/fs/gnunet-publish.c:573 src/vpn/gnunet-vpn.c:214 #, fuzzy, c-format msgid "Option `%s' is required when using option `%s'.\n" msgstr "Kommando \"%s\" kräver ett argument (\"%s\").\n" -#: src/fs/gnunet-publish.c:577 src/fs/gnunet-publish.c:584 -#: src/transport/gnunet-transport.c:530 +#: src/fs/gnunet-publish.c:583 src/fs/gnunet-publish.c:590 +#: src/transport/gnunet-transport.c:560 #, c-format msgid "Option `%s' makes no sense without option `%s'.\n" msgstr "" -#: src/fs/gnunet-publish.c:606 +#: src/fs/gnunet-publish.c:612 #, fuzzy, c-format msgid "Could not create namespace `%s'\n" msgstr "Kunde inte skapa namnrymd \"%s\" (existerar?).\n" -#: src/fs/gnunet-publish.c:639 +#: src/fs/gnunet-publish.c:645 #, fuzzy, c-format msgid "Failed to access `%s': %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/fs/gnunet-publish.c:651 +#: src/fs/gnunet-publish.c:657 msgid "" "Failed to start meta directory scanner. Is gnunet-helper-publish-fs " "installed?\n" msgstr "" -#: src/fs/gnunet-publish.c:676 +#: src/fs/gnunet-publish.c:682 msgid "disable adding the creation time to the metadata of the uploaded file" msgstr "" -#: src/fs/gnunet-publish.c:679 +#: src/fs/gnunet-publish.c:685 msgid "do not use libextractor to add keywords or metadata" msgstr "" -#: src/fs/gnunet-publish.c:683 +#: src/fs/gnunet-publish.c:689 msgid "" "print list of extracted keywords that would be used, but do not perform " "upload" msgstr "" -#: src/fs/gnunet-publish.c:687 +#: src/fs/gnunet-publish.c:693 msgid "" "add an additional keyword for the top-level file or directory (this option " "can be specified multiple times)" msgstr "" -#: src/fs/gnunet-publish.c:694 +#: src/fs/gnunet-publish.c:700 msgid "" "do not index, perform full insertion (stores entire file in encrypted form " "in GNUnet database)" msgstr "" -#: src/fs/gnunet-publish.c:699 +#: src/fs/gnunet-publish.c:705 msgid "" "specify ID of an updated version to be published in the future (for " "namespace insertions only)" msgstr "" -#: src/fs/gnunet-publish.c:703 +#: src/fs/gnunet-publish.c:709 msgid "specify the priority of the content" msgstr "ange prioritet fĂśr innehĂĽllet" -#: src/fs/gnunet-publish.c:707 +#: src/fs/gnunet-publish.c:713 msgid "publish the files under the pseudonym NAME (place file into namespace)" msgstr "" -#: src/fs/gnunet-publish.c:713 +#: src/fs/gnunet-publish.c:719 msgid "" "only simulate the process but do not do any actual publishing (useful to " "compute URIs)" msgstr "" -#: src/fs/gnunet-publish.c:717 +#: src/fs/gnunet-publish.c:723 msgid "" "set the ID of this version of the publication (for namespace insertions only)" msgstr "" -#: src/fs/gnunet-publish.c:721 +#: src/fs/gnunet-publish.c:727 msgid "" "URI to be published (can be used instead of passing a file to add keywords " "to the file with the respective URI)" msgstr "" -#: src/fs/gnunet-publish.c:736 +#: src/fs/gnunet-publish.c:742 msgid "Publish a file or directory on GNUnet" msgstr "" @@ -2676,24 +2719,12 @@ msgid "# Loopback routes suppressed" msgstr "" #: src/fs/gnunet-service-fs.c:581 src/hostlist/gnunet-daemon-hostlist.c:297 -#: src/topology/gnunet-daemon-topology.c:1290 -#: src/topology/gnunet-daemon-topology.c:1297 +#: src/topology/gnunet-daemon-topology.c:1330 +#: src/topology/gnunet-daemon-topology.c:1337 #, fuzzy, c-format msgid "Failed to connect to `%s' service.\n" msgstr "Misslyckades att initiera tjänsten \"%s\".\n" -#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 -#: src/topology/gnunet-daemon-topology.c:654 -#: src/topology/gnunet-daemon-topology.c:756 -#: src/transport/gnunet-service-transport_neighbours.c:960 -#: src/transport/gnunet-service-transport_neighbours.c:1289 -#: src/transport/gnunet-service-transport_neighbours.c:1841 -#: src/transport/gnunet-service-transport_neighbours.c:2499 -#: src/transport/gnunet-service-transport_neighbours.c:2566 -#, fuzzy -msgid "# peers connected" -msgstr "# av anslutna parter" - #: src/fs/gnunet-service-fs_cp.c:696 #, fuzzy msgid "# migration stop messages received" @@ -3039,15 +3070,132 @@ msgstr "" msgid "Reply mismatched in terms of namespace. Discarded.\n" msgstr "" -#: src/gns/gns_api.c:221 +#: src/gns/gnunet-gns.c:191 +#, fuzzy +msgid "Failed to connect to GNS\n" +msgstr "Misslyckades att ansluta till gnunetd.\n" + +#: src/gns/gnunet-gns.c:232 +msgid "try to shorten a given GNS name" +msgstr "" + +#: src/gns/gnunet-gns.c:235 +msgid "Lookup a record using GNS (NOT IMPLEMENTED)" +msgstr "" + +#: src/gns/gnunet-gns.c:238 +msgid "Get the authority of a particular name" +msgstr "" + +#: src/gns/gnunet-gns.c:241 +#, fuzzy +msgid "Specify the type of the record lookup" +msgstr "ange prioritet fĂśr innehĂĽllet" + +#: src/gns/gnunet-gns.c:244 +msgid "No unneeded output" +msgstr "" + +#: src/gns/gnunet-gns.c:255 +msgid "GNUnet GNS access tool" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:280 +#, fuzzy, c-format +msgid "Unsupported form value `%s'\n" +msgstr "Kommando \"%s\" stĂśds ej. Avbryter.\n" + +#: src/gns/gnunet-gns-fcfsd.c:333 +#, fuzzy, c-format +msgid "Failed to create record for domain `%s': %s\n" +msgstr "Kunde inte tolka konfigurationsfil \"%s\".\n" + +#: src/gns/gnunet-gns-fcfsd.c:377 +#, c-format +msgid "Found existing name `%s' for the given key\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:439 +#, c-format +msgid "Found %u existing records for domain `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:498 +#, fuzzy, c-format +msgid "Failed to create page for `%s'\n" +msgstr "Kunde inte skapa namnrymd \"%s\" (existerar?).\n" + +#: src/gns/gnunet-gns-fcfsd.c:514 +#, fuzzy, c-format +msgid "Failed to setup post processor for `%s'\n" +msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" + +#: src/gns/gnunet-gns-fcfsd.c:725 src/gns/gnunet-gns-fcfsd.c:737 +#, fuzzy, c-format +msgid "Option `%s' not specified in configuration section `%s'\n" +msgstr "Inga applikationer definierade i konfiguration!\n" + +#: src/gns/gnunet-gns-fcfsd.c:747 src/namestore/gnunet-namestore.c:299 +#, fuzzy +msgid "Failed to read or create private zone key\n" +msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" + +#: src/gns/gnunet-gns-fcfsd.c:757 src/namestore/gnunet-namestore.c:310 #, fuzzy -msgid "Failed to connect to the GNS service!\n" +msgid "Failed to connect to namestore\n" msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/gns/gnunet-gns-lookup.c:210 -msgid "Issue a request to the GNUnet Naming System, prints results." +#: src/gns/gnunet-gns-fcfsd.c:773 src/gns/gnunet-gns-proxy.c:525 +#, fuzzy +msgid "Failed to start HTTP server\n" +msgstr "Misslyckades att starta samling.\n" + +#: src/gns/gnunet-gns-fcfsd.c:804 +msgid "GNUnet GNS first come first serve registration service" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:800 +msgid "listen on specified port" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:811 +msgid "GNUnet GNS proxy" +msgstr "" + +#: src/hello/gnunet-hello.c:122 +msgid "Call with name of HELLO file to modify.\n" +msgstr "" + +#: src/hello/gnunet-hello.c:128 +#, fuzzy, c-format +msgid "Error accessing file `%s': %s\n" +msgstr "Fel vid skapandet av användare" + +#: src/hello/gnunet-hello.c:136 +#, c-format +msgid "File `%s' is too big to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:143 +#, c-format +msgid "File `%s' is too small to be a HELLO\n" msgstr "" +#: src/hello/gnunet-hello.c:153 src/hello/gnunet-hello.c:181 +#, fuzzy, c-format +msgid "Error opening file `%s': %s\n" +msgstr "Fel vid skapandet av användare" + +#: src/hello/gnunet-hello.c:169 +#, fuzzy, c-format +msgid "Did not find well-formed HELLO in file `%s'\n" +msgstr "%d filer hittades i katalog.\n" + +#: src/hello/gnunet-hello.c:193 +#, fuzzy, c-format +msgid "Error writing HELLO to file `%s': %s\n" +msgstr "Fel vid skapandet av användare" + #: src/hostlist/gnunet-daemon-hostlist.c:264 msgid "" "None of the functions for the hostlist daemon were enabled. I have no " @@ -3076,192 +3224,193 @@ msgstr "" msgid "GNUnet hostlist server and client" msgstr "" -#: src/hostlist/hostlist-client.c:286 +#: src/hostlist/hostlist-client.c:289 msgid "# bytes downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:307 src/hostlist/hostlist-client.c:339 +#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:340 msgid "# invalid HELLOs downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:342 +#: src/hostlist/hostlist-client.c:313 src/hostlist/hostlist-client.c:343 #, fuzzy, c-format msgid "Invalid `%s' message received from hostlist at `%s'\n" msgstr "Ogiltigt meddelande mottogs den %s:%d." -#: src/hostlist/hostlist-client.c:330 +#: src/hostlist/hostlist-client.c:331 msgid "# valid HELLOs downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:374 src/hostlist/hostlist-client.c:395 +#: src/hostlist/hostlist-client.c:375 src/hostlist/hostlist-client.c:396 #, c-format msgid "No `%s' specified in `%s' configuration, will not bootstrap.\n" msgstr "" -#: src/hostlist/hostlist-client.c:472 src/hostlist/hostlist-client.c:682 -#: src/hostlist/hostlist-client.c:688 src/hostlist/hostlist-client.c:740 -#: src/hostlist/hostlist-client.c:749 src/hostlist/hostlist-client.c:877 -#: src/hostlist/hostlist-client.c:967 src/hostlist/hostlist-client.c:972 -#: src/transport/plugin_transport_http_client.c:108 -#: src/transport/plugin_transport_http_client.c:123 +#: src/hostlist/hostlist-client.c:473 src/hostlist/hostlist-client.c:683 +#: src/hostlist/hostlist-client.c:689 src/hostlist/hostlist-client.c:741 +#: src/hostlist/hostlist-client.c:750 src/hostlist/hostlist-client.c:871 +#: src/hostlist/hostlist-client.c:961 src/hostlist/hostlist-client.c:966 +#: src/transport/plugin_transport_http_client.c:110 +#: src/transport/plugin_transport_http_client.c:125 #, fuzzy, c-format msgid "%s failed at %s:%d: `%s'\n" msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n" -#: src/hostlist/hostlist-client.c:592 src/hostlist/hostlist-client.c:1342 +#: src/hostlist/hostlist-client.c:593 src/hostlist/hostlist-client.c:1331 msgid "# advertised hostlist URIs" msgstr "" -#: src/hostlist/hostlist-client.c:622 +#: src/hostlist/hostlist-client.c:623 #, c-format msgid "# advertised URI `%s' downloaded" msgstr "" -#: src/hostlist/hostlist-client.c:663 +#: src/hostlist/hostlist-client.c:664 #, c-format msgid "" "Advertised hostlist with URI `%s' could not be downloaded. Advertised URI " "gets dismissed.\n" msgstr "" -#: src/hostlist/hostlist-client.c:805 +#: src/hostlist/hostlist-client.c:802 #, fuzzy, c-format msgid "Timeout trying to download hostlist from `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/hostlist/hostlist-client.c:822 +#: src/hostlist/hostlist-client.c:816 #, c-format msgid "Download limit of %u bytes exceeded, stopping download\n" msgstr "" -#: src/hostlist/hostlist-client.c:842 +#: src/hostlist/hostlist-client.c:836 #, fuzzy, c-format -msgid "%s failed for `%s' at %s:%d: `%s'\n" -msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n" +msgid "Download of hostlist from `%s' failed: `%s'\n" +msgstr "" +"Uppladdning av \"%s\" klar, aktuell genomsnittshastighet är %8.3f kbps.\n" -#: src/hostlist/hostlist-client.c:848 +#: src/hostlist/hostlist-client.c:842 #, fuzzy, c-format msgid "Download of hostlist `%s' completed.\n" msgstr "" "Uppladdning av \"%s\" klar, aktuell genomsnittshastighet är %8.3f kbps.\n" -#: src/hostlist/hostlist-client.c:856 +#: src/hostlist/hostlist-client.c:850 #, c-format msgid "Adding successfully tested hostlist `%s' datastore.\n" msgstr "" -#: src/hostlist/hostlist-client.c:909 +#: src/hostlist/hostlist-client.c:903 #, c-format msgid "Bootstrapping using hostlist at `%s'.\n" msgstr "" -#: src/hostlist/hostlist-client.c:917 +#: src/hostlist/hostlist-client.c:911 msgid "# hostlist downloads initiated" msgstr "" -#: src/hostlist/hostlist-client.c:1045 src/hostlist/hostlist-client.c:1515 +#: src/hostlist/hostlist-client.c:1037 src/hostlist/hostlist-client.c:1505 msgid "# milliseconds between hostlist downloads" msgstr "" -#: src/hostlist/hostlist-client.c:1054 +#: src/hostlist/hostlist-client.c:1046 #, c-format msgid "Have %u/%u connections. Will consider downloading hostlist in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1092 +#: src/hostlist/hostlist-client.c:1084 msgid "Scheduled saving of hostlists\n" msgstr "" -#: src/hostlist/hostlist-client.c:1096 +#: src/hostlist/hostlist-client.c:1088 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1119 src/hostlist/hostlist-client.c:1135 +#: src/hostlist/hostlist-client.c:1111 src/hostlist/hostlist-client.c:1127 #, fuzzy msgid "# active connections" msgstr "Nätverksanslutning" -#: src/hostlist/hostlist-client.c:1253 +#: src/hostlist/hostlist-client.c:1242 #, c-format msgid "Initial time between hostlist downloads is %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1284 +#: src/hostlist/hostlist-client.c:1273 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot load hostlists from file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1290 +#: src/hostlist/hostlist-client.c:1279 #, fuzzy, c-format msgid "Loading saved hostlist entries from file `%s' \n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/hostlist/hostlist-client.c:1294 +#: src/hostlist/hostlist-client.c:1283 #, c-format msgid "Hostlist file `%s' is not existing\n" msgstr "" -#: src/hostlist/hostlist-client.c:1305 +#: src/hostlist/hostlist-client.c:1294 #, fuzzy, c-format msgid "Could not open file `%s' for reading to load hostlists: %s\n" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/hostlist/hostlist-client.c:1338 +#: src/hostlist/hostlist-client.c:1327 #, c-format msgid "%u hostlist URIs loaded from file\n" msgstr "" -#: src/hostlist/hostlist-client.c:1340 +#: src/hostlist/hostlist-client.c:1329 msgid "# hostlist URIs read from file" msgstr "" -#: src/hostlist/hostlist-client.c:1373 +#: src/hostlist/hostlist-client.c:1362 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot save hostlists to file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1387 +#: src/hostlist/hostlist-client.c:1376 #, fuzzy, c-format msgid "Could not open file `%s' for writing to save hostlists: %s\n" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/hostlist/hostlist-client.c:1392 +#: src/hostlist/hostlist-client.c:1381 #, fuzzy, c-format msgid "Writing %u hostlist URIs to `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/hostlist/hostlist-client.c:1416 src/hostlist/hostlist-client.c:1433 +#: src/hostlist/hostlist-client.c:1405 src/hostlist/hostlist-client.c:1422 #, c-format msgid "Error writing hostlist URIs to file `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:1428 +#: src/hostlist/hostlist-client.c:1417 msgid "# hostlist URIs written to file" msgstr "" -#: src/hostlist/hostlist-client.c:1480 +#: src/hostlist/hostlist-client.c:1470 msgid "Learning is enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1483 +#: src/hostlist/hostlist-client.c:1473 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1492 +#: src/hostlist/hostlist-client.c:1482 msgid "Learning is not enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1504 +#: src/hostlist/hostlist-client.c:1494 #, c-format msgid "" "Since learning is not enabled on this peer, hostlist file `%s' was removed\n" msgstr "" -#: src/hostlist/hostlist-client.c:1508 +#: src/hostlist/hostlist-client.c:1498 #, c-format msgid "Hostlist file `%s' could not be removed\n" msgstr "" @@ -3275,8 +3424,10 @@ msgstr "# byte krypterade" msgid "expired addresses encountered" msgstr "" -#: src/hostlist/hostlist-server.c:184 -#: src/topology/gnunet-daemon-topology.c:875 +#: src/hostlist/hostlist-server.c:184 src/hostlist/hostlist-server.c:425 +#: src/peerinfo-tool/gnunet-peerinfo.c:403 +#: src/peerinfo-tool/gnunet-peerinfo.c:519 +#: src/topology/gnunet-daemon-topology.c:927 #, fuzzy, c-format msgid "Error in communication with PEERINFO service: %s\n" msgstr "Skriv ut information om GNUnets motparter." @@ -3285,250 +3436,562 @@ msgstr "Skriv ut information om GNUnets motparter." msgid "HELLOs without addresses encountered (ignored)" msgstr "" -#: src/hostlist/hostlist-server.c:221 +#: src/hostlist/hostlist-server.c:219 msgid "bytes not included in hostlist (size limit)" msgstr "" -#: src/hostlist/hostlist-server.c:269 +#: src/hostlist/hostlist-server.c:263 #, c-format msgid "Refusing `%s' request to hostlist server\n" msgstr "" -#: src/hostlist/hostlist-server.c:272 +#: src/hostlist/hostlist-server.c:266 msgid "hostlist requests refused (not HTTP GET)" msgstr "" -#: src/hostlist/hostlist-server.c:280 +#: src/hostlist/hostlist-server.c:273 msgid "Sending 100 CONTINUE reply\n" msgstr "" -#: src/hostlist/hostlist-server.c:287 +#: src/hostlist/hostlist-server.c:279 #, c-format msgid "Refusing `%s' request with %llu bytes of upload data\n" msgstr "" -#: src/hostlist/hostlist-server.c:291 +#: src/hostlist/hostlist-server.c:283 msgid "hostlist requests refused (upload data)" msgstr "" -#: src/hostlist/hostlist-server.c:299 +#: src/hostlist/hostlist-server.c:291 msgid "Could not handle hostlist request since I do not have a response yet\n" msgstr "" -#: src/hostlist/hostlist-server.c:302 +#: src/hostlist/hostlist-server.c:294 msgid "hostlist requests refused (not ready)" msgstr "" -#: src/hostlist/hostlist-server.c:306 +#: src/hostlist/hostlist-server.c:298 msgid "Received request for our hostlist\n" msgstr "" -#: src/hostlist/hostlist-server.c:307 +#: src/hostlist/hostlist-server.c:299 msgid "hostlist requests processed" msgstr "" -#: src/hostlist/hostlist-server.c:350 +#: src/hostlist/hostlist-server.c:341 msgid "# hostlist advertisements send" msgstr "" -#: src/hostlist/hostlist-server.c:397 +#: src/hostlist/hostlist-server.c:388 msgid "Advertisement message could not be queued by core\n" msgstr "" -#: src/hostlist/hostlist-server.c:565 +#: src/hostlist/hostlist-server.c:561 #, fuzzy, c-format msgid "Invalid port number %llu. Exiting.\n" msgstr "Ogiltiga argument. Avslutar.\n" -#: src/hostlist/hostlist-server.c:574 +#: src/hostlist/hostlist-server.c:570 #, c-format msgid "Hostlist service starts on %s:%llu\n" msgstr "" -#: src/hostlist/hostlist-server.c:588 +#: src/hostlist/hostlist-server.c:584 #, fuzzy, c-format msgid "Address to obtain hostlist: `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/hostlist/hostlist-server.c:626 +#: src/hostlist/hostlist-server.c:624 +#, fuzzy, c-format +msgid "`%s' is not a valid IP address! Ignoring BINDTOIP.\n" +msgstr "\"%s\" är inte tillgänglig." + +#: src/hostlist/hostlist-server.c:666 #, c-format msgid "Could not start hostlist HTTP server on port %u\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4595 +#: src/integration-tests/connection_watchdog.c:997 +#, fuzzy, c-format +msgid "Transport plugin: `%s' port %llu\n" +msgstr "Testar transport(er) %s\n" + +#: src/integration-tests/connection_watchdog.c:1030 +#, fuzzy, c-format +msgid "Found %u transport plugins: `%s'\n" +msgstr "Testar transport(er) %s\n" + +#: src/integration-tests/connection_watchdog.c:1089 +msgid "Send ping messages to test connectivity (default == NO)" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1095 +#: src/template/gnunet-template.c:68 +#, fuzzy +msgid "help text" +msgstr "hjälptext fĂśr -t" + +#: src/mesh/gnunet-service-mesh.c:4590 msgid "Wrong CORE service\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4789 +#: src/mesh/gnunet-service-mesh.c:4784 #, fuzzy msgid "Mesh service is lacking key configuration settings. Exiting.\n" msgstr "GNUnet-konfiguration" -#: src/mesh/gnunet-service-mesh.c:4798 +#: src/mesh/gnunet-service-mesh.c:4793 #, fuzzy msgid "Mesh service could not access hostkey. Exiting.\n" msgstr "Kunde inte komma ĂĽt namnrymdsinformation.\n" -#: src/namestore/namestore_api.c:272 src/namestore/namestore_api.c:313 -msgid "Namestore added record successfully" +#: src/mysql/mysql.c:174 +#, c-format +msgid "Trying to use file `%s' for MySQL configuration.\n" +msgstr "FĂśrsĂśker använda fil \"%s\" fĂśr MySQL-konfiguration.\n" + +#: src/mysql/mysql.c:181 +#, fuzzy, c-format +msgid "Could not access file `%s': %s\n" +msgstr "Kunde inte kĂśra \"%s\": %s\n" + +#: src/namestore/gnunet-namestore.c:157 +#, fuzzy, c-format +msgid "Adding record failed: %s\n" msgstr "" +"\n" +"Fel vid uppladdning av fil: %s\n" -#: src/namestore/namestore_api.c:281 src/namestore/namestore_api.c:322 -msgid "Namestore failed to add record" +#: src/namestore/gnunet-namestore.c:183 +#, fuzzy, c-format +msgid "Deleting record failed: %s\n" msgstr "" +"\n" +"Fel vid uppladdning av fil: %s\n" -#: src/nat/gnunet-nat-server.c:289 +#: src/namestore/gnunet-namestore.c:239 #, c-format -msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgid "\tCorrupt or unsupported record of type %u\n" msgstr "" -#: src/nat/gnunet-nat-server.c:328 -msgid "GNUnet NAT traversal test helper daemon" +#: src/namestore/gnunet-namestore.c:276 +#, c-format +msgid "Option `%s' not given, but I need a zone key file!\n" msgstr "" -#: src/nat/nat.c:803 +#: src/namestore/gnunet-namestore.c:281 +#, fuzzy, c-format +msgid "Using default zone file `%s'\n" +msgstr "Startade samling \"%s\".\n" + +#: src/namestore/gnunet-namestore.c:291 #, c-format -msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgid "No options given\n" msgstr "" -#: src/nat/nat.c:852 +#: src/namestore/gnunet-namestore.c:321 #, fuzzy, c-format -msgid "Failed to start %s\n" -msgstr "Misslyckades att starta samling.\n" +msgid "Unsupported type `%s'\n" +msgstr "Kommando \"%s\" stĂśds ej. Avbryter.\n" -#: src/nat/nat.c:1121 +#: src/namestore/gnunet-namestore.c:328 src/namestore/gnunet-namestore.c:350 +#: src/namestore/gnunet-namestore.c:374 src/namestore/gnunet-namestore.c:384 +#: src/namestore/gnunet-namestore.c:409 #, fuzzy, c-format -msgid "Malformed %s `%s' given in configuration!\n" -msgstr "Kunde inte spara konfiguration!" +msgid "Missing option `%s' for operation `%s'\n" +msgstr "Konfigurationsfil \"%s\" skapad.\n" -#: src/nat/nat.c:1187 src/nat/nat.c:1197 -#, c-format -msgid "" -"Configuration requires `%s', but binary is not installed properly (SUID bit " +#: src/namestore/gnunet-namestore.c:329 src/namestore/gnunet-namestore.c:351 +msgid "add/del" +msgstr "" + +#: src/namestore/gnunet-namestore.c:341 +#, fuzzy, c-format +msgid "Value `%s' invalid for record type `%s'\n" +msgstr "%s: symbolvärde \"%s\" ogiltigt fĂśr %s\n" + +#: src/namestore/gnunet-namestore.c:366 +#, fuzzy, c-format +msgid "Invalid time format `%s'\n" +msgstr "Ogiltigt format fĂśr IP: \"%s\"\n" + +#: src/namestore/gnunet-namestore.c:375 src/namestore/gnunet-namestore.c:385 +msgid "add" +msgstr "" + +#: src/namestore/gnunet-namestore.c:410 +msgid "del" +msgstr "" + +#: src/namestore/gnunet-namestore.c:462 +msgid "add record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:465 +msgid "delete record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:468 +msgid "display records" +msgstr "" + +#: src/namestore/gnunet-namestore.c:471 +msgid "" +"expiration time for record to use (for adding only), \"never\" is possible" +msgstr "" + +#: src/namestore/gnunet-namestore.c:474 +msgid "name of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:477 +msgid "type of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:480 +msgid "value of the record to add/delete" +msgstr "" + +#: src/namestore/gnunet-namestore.c:483 +msgid "create or list public record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:486 +msgid "create or list non-authority record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:489 +msgid "filename with the zone key" +msgstr "" + +#: src/namestore/gnunet-namestore.c:500 +#, fuzzy +msgid "GNUnet zone manipulation tool" +msgstr "GNUnet-konfiguration" + +#: src/namestore/gnunet-service-namestore.c:143 +#, c-format +msgid "File zone `%s' but corrupt content already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:154 +#, c-format +msgid "File zone `%s' containing this key already exists\n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:160 +#, c-format +msgid "" +"File zone `%s' but different zone key already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:198 +#, fuzzy, c-format +msgid "Stored zonekey for zone `%s' in file `%s'\n" +msgstr "Misslyckades att leverera \"%s\" meddelande.\n" + +#: src/namestore/gnunet-service-namestore.c:1909 +#, fuzzy +msgid "No directory to load zonefiles specified in configuration\n" +msgstr "Inga applikationer definierade i konfiguration!\n" + +#: src/namestore/gnunet-service-namestore.c:1918 +#, c-format +msgid "Creating directory `%s' for zone files failed!\n" +msgstr "" + +#: src/namestore/namestore_api.c:315 src/namestore/namestore_api.c:353 +msgid "Namestore added record successfully" +msgstr "" + +#: src/namestore/namestore_api.c:323 +msgid "Namestore failed to add record" +msgstr "" + +#: src/namestore/namestore_api.c:361 +msgid "Namestore record already existed" +msgstr "" + +#: src/namestore/namestore_api.c:368 +msgid "Namestore failed to add record\n" +msgstr "" + +#: src/namestore/namestore_api.c:401 +msgid "Namestore removed record successfully" +msgstr "" + +#: src/namestore/namestore_api.c:408 +msgid "No records for entry" +msgstr "" + +#: src/namestore/namestore_api.c:415 +#, fuzzy +msgid "Could not find record to remove" +msgstr "Kunde inte ansluta till gnunetd.\n" + +#: src/namestore/namestore_api.c:422 +#, fuzzy +msgid "Failed to create new signature" +msgstr "Kunde inte skapa namnrymd \"%s\" (existerar?).\n" + +#: src/namestore/namestore_api.c:429 +#, fuzzy +msgid "Failed to put new set of records in database" +msgstr "Misslyckades att skicka HTTP-begäran till värd \"%s\": %s\n" + +#: src/nat/gnunet-nat-server.c:279 +#, c-format +msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgstr "" + +#: src/nat/gnunet-nat-server.c:318 +msgid "GNUnet NAT traversal test helper daemon" +msgstr "" + +#: src/nat/nat.c:799 +#, c-format +msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgstr "" + +#: src/nat/nat.c:844 +#, fuzzy, c-format +msgid "Failed to start %s\n" +msgstr "Misslyckades att starta samling.\n" + +#: src/nat/nat.c:1111 +#, fuzzy, c-format +msgid "Malformed %s `%s' given in configuration!\n" +msgstr "Kunde inte spara konfiguration!" + +#: src/nat/nat.c:1177 src/nat/nat.c:1187 +#, c-format +msgid "" +"Configuration requires `%s', but binary is not installed properly (SUID bit " "not set). Option disabled.\n" msgstr "" -#: src/nat/nat.c:1329 +#: src/nat/nat.c:1321 msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" msgstr "" -#: src/nat/nat.c:1341 +#: src/nat/nat.c:1332 #, c-format msgid "Running gnunet-helper-nat-client %s %s %u\n" msgstr "" -#: src/nat/nat_test.c:348 +#: src/nat/nat_test.c:341 #, fuzzy msgid "Failed to connect to `gnunet-nat-server'\n" msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/nat/nat_test.c:418 +#: src/nat/nat_test.c:411 #, c-format msgid "Failed to create listen socket bound to `%s' for NAT test: %s\n" msgstr "" -#: src/nse/gnunet-nse-profiler.c:926 +#: src/nse/gnunet-nse-profiler.c:928 #, fuzzy msgid "Measure quality and performance of the NSE service." msgstr "Kan inte tillgĂĽ tjänsten" -#: src/nse/gnunet-service-nse.c:936 +#: src/nse/gnunet-service-nse.c:925 #, c-format msgid "Proof of work invalid: %llu!\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1391 src/nse/gnunet-service-nse.c:1410 -#: src/nse/gnunet-service-nse.c:1431 +#: src/nse/gnunet-service-nse.c:1381 src/nse/gnunet-service-nse.c:1400 +#: src/nse/gnunet-service-nse.c:1421 msgid "NSE service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1398 +#: src/nse/gnunet-service-nse.c:1388 #, fuzzy msgid "Invalid work requirement for NSE service. Exiting.\n" msgstr "Ogiltiga argument. Avslutar.\n" -#: src/nse/gnunet-service-nse.c:1419 +#: src/nse/gnunet-service-nse.c:1409 #, fuzzy msgid "NSE service could not access hostkey. Exiting.\n" msgstr "Kunde inte komma ĂĽt namnrymdsinformation.\n" -#: src/peerinfo/gnunet-service-peerinfo.c:133 +#: src/peerinfo/gnunet-service-peerinfo.c:134 #, fuzzy, c-format msgid "Removing expired address of transport `%s'\n" msgstr "Tillgängliga transport(er): %s\n" -#: src/peerinfo/gnunet-service-peerinfo.c:195 +#: src/peerinfo/gnunet-service-peerinfo.c:203 +#, fuzzy, c-format +msgid "Failed to parse HELLO in file `%s'\n" +msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" + +#: src/peerinfo/gnunet-service-peerinfo.c:229 msgid "# peers known" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:239 +#: src/peerinfo/gnunet-service-peerinfo.c:254 #, c-format msgid "" "File `%s' in directory `%s' does not match naming convention. Removed.\n" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:305 +#: src/peerinfo/gnunet-service-peerinfo.c:353 #, c-format msgid "Still no peers found in `%s'!\n" msgstr "" -#: src/peerinfo/peerinfo_api.c:279 -#, fuzzy, c-format -msgid "Failed to transmit message to `%s' service.\n" -msgstr "Misslyckades att initiera tjänsten \"%s\".\n" +#: src/peerinfo/gnunet-service-peerinfo.c:710 +#, c-format +msgid "Importing HELLOs from `%s'\n" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:238 +msgid "aborted due to explicit disconnect request" +msgstr "" -#: src/peerinfo/peerinfo_api.c:435 +#: src/peerinfo/peerinfo_api.c:358 +#, fuzzy +msgid "failed to transmit request (service down?)" +msgstr "Misslyckades att skicka HTTP-begäran till värd \"%s\": %s\n" + +#: src/peerinfo/peerinfo_api.c:505 #, fuzzy msgid "Failed to receive response from `PEERINFO' service." msgstr "Misslyckades att ta emot svar till \"%s\" meddelande frĂĽn gnunetd\n" -#: src/peerinfo/peerinfo_api.c:463 src/peerinfo/peerinfo_api.c:481 +#: src/peerinfo/peerinfo_api.c:531 src/peerinfo/peerinfo_api.c:550 +#: src/peerinfo/peerinfo_api.c:565 src/peerinfo/peerinfo_api.c:576 +#: src/peerinfo/peerinfo_api.c:587 #, fuzzy -msgid "Received invalid message from `PEERINFO' service.\n" +msgid "Received invalid message from `PEERINFO' service." msgstr "mottog ogiltigt \"%s\" meddelande: %s.\n" -#: src/peerinfo/peerinfo_api.c:523 +#: src/peerinfo/peerinfo_api.c:663 #, fuzzy -msgid "Failed to transmit iteration request to `PEERINFO' service\n" +msgid "Timeout transmitting iteration request to `PEERINFO' service." msgstr "Misslyckades att initiera tjänsten \"%s\".\n" -#: src/peerinfo/peerinfo_api.c:557 -msgid "Timeout transmitting iteration request to `PEERINFO' service.\n" -msgstr "" - -#: src/peerinfo/peerinfo_api_notify.c:258 +#: src/peerinfo/peerinfo_api_notify.c:256 #, fuzzy, c-format msgid "Could not connect to `%s' service.\n" msgstr "Kunde inte ansluta till gnunetd.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:216 +#: src/peerinfo-tool/gnunet-peerinfo.c:581 +#, fuzzy +msgid "Failed to parse HELLO message: missing expiration time\n" +msgstr "Kunde inte spara konfiguration!" + +#: src/peerinfo-tool/gnunet-peerinfo.c:589 +#, fuzzy +msgid "Failed to parse HELLO message: invalid expiration time\n" +msgstr "Kunde inte spara konfiguration!" + +#: src/peerinfo-tool/gnunet-peerinfo.c:598 +#, fuzzy +msgid "Failed to parse HELLO message: malformed\n" +msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:608 +#, fuzzy +msgid "Failed to parse HELLO message: missing transport plugin\n" +msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:625 +#, c-format +msgid "Plugin `%s' not found\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:634 +#, c-format +msgid "Plugin `%s' does not support URIs yet\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:653 +#, fuzzy, c-format +msgid "Failed to parse `%s' as an address for plugin `%s'\n" +msgstr "Misslyckades att binda till UDP-port %d.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:685 +#, c-format +msgid "Failure adding HELLO: %s\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:833 #, fuzzy, c-format msgid "Could not find option `%s:%s' in configuration.\n" msgstr "Kunde inte hitta motpart \"%s\" i routingtabell!\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:223 +#: src/peerinfo-tool/gnunet-peerinfo.c:840 #, fuzzy, c-format msgid "Loading hostkey from `%s' failed.\n" msgstr "Tolkning av HTTP-svar fĂśr URL \"%s\" misslyckades.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:235 +#: src/peerinfo-tool/gnunet-peerinfo.c:875 +#, fuzzy, c-format +msgid "Invalid URI `%s'\n" +msgstr "Ogiltiga argument: " + +#: src/peerinfo-tool/gnunet-peerinfo.c:899 #, c-format msgid "I am peer `%s'.\n" msgstr "Jag är ändpunkt \"%s\".\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:255 +#: src/peerinfo-tool/gnunet-peerinfo.c:936 +msgid "don't resolve host names" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:939 msgid "output only the identity strings" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:258 +#: src/peerinfo-tool/gnunet-peerinfo.c:942 msgid "output our own identity only" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:264 +#: src/peerinfo-tool/gnunet-peerinfo.c:945 +msgid "list all known peers" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:948 +msgid "also output HELLO uri(s)" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:951 +msgid "add given HELLO uri to the database" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:957 #, fuzzy msgid "Print information about peers." msgstr "Skriv ut information om GNUnets motparter." +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:105 +#: src/transport/gnunet-service-transport_plugins.c:118 +#, fuzzy, c-format +msgid "Starting transport plugins `%s'\n" +msgstr "Testar transport(er) %s\n" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:109 +#: src/transport/gnunet-service-transport_plugins.c:122 +#, fuzzy, c-format +msgid "Loading `%s' transport plugin\n" +msgstr "Testar transport(er) %s\n" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:129 +#: src/transport/gnunet-service-transport_plugins.c:150 +#, fuzzy, c-format +msgid "Failed to load transport plugin for `%s'\n" +msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" + +#: src/postgres/postgres.c:59 +#, fuzzy, c-format +msgid "`%s:%s' failed at %s:%d with error: %s" +msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" + +#: src/postgres/postgres.c:148 +#, fuzzy, c-format +msgid "Unable to initialize Postgres: %s" +msgstr "Kunde inte initiera SQLite.\n" + #: src/pt/gnunet-daemon-pt.c:264 #, fuzzy msgid "Failed to pack DNS request. Dropping.\n" @@ -3595,50 +4058,65 @@ msgstr "Misslyckades att initiera tjänsten \"%s\".\n" msgid "Daemon to run to perform IP protocol translation to GNUnet" msgstr "" -#: src/statistics/gnunet-service-statistics.c:209 +#: src/statistics/gnunet-service-statistics.c:271 #, fuzzy, c-format msgid "Loading %llu bytes of statistics from `%s'\n" msgstr "Ladda ner filer frĂĽn GNUnet." -#: src/statistics/gnunet-service-statistics.c:267 +#: src/statistics/gnunet-service-statistics.c:330 #, fuzzy, c-format msgid "Wrote %llu bytes of statistics to `%s'\n" msgstr "Ladda ner filer frĂĽn GNUnet." -#: src/statistics/gnunet-statistics.c:98 +#: src/statistics/gnunet-statistics.c:122 #, fuzzy msgid "Failed to obtain statistics.\n" msgstr "Misslyckades att binda till UDP-port %d.\n" -#: src/statistics/gnunet-statistics.c:164 +#: src/statistics/gnunet-statistics.c:199 +#, c-format +msgid "No subsystem or name given\n" +msgstr "" + +#: src/statistics/gnunet-statistics.c:207 +#, fuzzy, c-format +msgid "Failed to initialize watch routine\n" +msgstr "Misslyckades att initiera tjänsten \"%s\".\n" + +#: src/statistics/gnunet-statistics.c:227 msgid "limit output to statistics for the given NAME" msgstr "" -#: src/statistics/gnunet-statistics.c:167 +#: src/statistics/gnunet-statistics.c:230 msgid "make the value being set persistent" msgstr "" -#: src/statistics/gnunet-statistics.c:170 +#: src/statistics/gnunet-statistics.c:233 msgid "limit output to the given SUBSYSTEM" msgstr "" -#: src/statistics/gnunet-statistics.c:173 +#: src/statistics/gnunet-statistics.c:236 msgid "just print the statistics value" msgstr "" -#: src/statistics/gnunet-statistics.c:180 +#: src/statistics/gnunet-statistics.c:239 +msgid "watch value continously" +msgstr "" + +#: src/statistics/gnunet-statistics.c:246 msgid "Print statistics about GNUnet operations." msgstr "Skriv ut statistik om GNUnet-operationer." -#: src/statistics/statistics_api.c:390 +#: src/statistics/statistics_api.c:456 #, fuzzy -msgid "Failed to connect to statistics service!\n" -msgstr "Misslyckades att ansluta till gnunetd.\n" +msgid "Could not save some persistent statistics\n" +msgstr "Kunde inte skapa värdnyckel!\n" -#: src/template/gnunet-template.c:68 -#, fuzzy -msgid "help text" -msgstr "hjälptext fĂśr -t" +#: src/statistics/statistics_api.c:999 +msgid "" +"Failed to receive acknowledgement from statistics service, some statistics " +"might have been lost!\n" +msgstr "" #: src/testing/gnunet-testing.c:157 #, fuzzy @@ -3687,599 +4165,437 @@ msgstr "GNUnet-konfiguration" msgid "Could not access hostkey.\n" msgstr "Kunde inte tolka konfigurationsfil \"%s\".\n" -#: src/testing/testing.c:204 +#: src/testing/testing.c:200 msgid "`scp' does not seem to terminate (timeout copying config).\n" msgstr "" -#: src/testing/testing.c:218 src/testing/testing.c:808 +#: src/testing/testing.c:214 src/testing/testing.c:798 #, fuzzy msgid "`scp' did not complete cleanly.\n" msgstr "\"%s\" är inte ansluten till nĂĽgon ändpunkt.\n" -#: src/testing/testing.c:239 +#: src/testing/testing.c:237 #, fuzzy msgid "Failed to create pipe for `gnunet-peerinfo' process.\n" msgstr "Misslyckades att starta samling.\n" -#: src/testing/testing.c:240 +#: src/testing/testing.c:238 #, fuzzy msgid "Failed to create pipe for `ssh' process.\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/testing/testing.c:292 +#: src/testing/testing.c:286 #, fuzzy, c-format msgid "Could not start `%s' process to create hostkey.\n" msgstr "Kunde inte skapa värdnyckel!\n" -#: src/testing/testing.c:299 +#: src/testing/testing.c:293 #, fuzzy msgid "Failed to start `gnunet-peerinfo' process.\n" msgstr "Misslyckades att starta samling.\n" -#: src/testing/testing.c:300 src/testing/testing.c:488 +#: src/testing/testing.c:294 src/testing/testing.c:471 #, fuzzy msgid "Failed to start `ssh' process.\n" msgstr "Misslyckades att starta samling.\n" -#: src/testing/testing.c:360 +#: src/testing/testing.c:354 #, c-format msgid "Error reading from gnunet-peerinfo: %s\n" msgstr "" -#: src/testing/testing.c:364 +#: src/testing/testing.c:358 #, fuzzy msgid "Malformed output from gnunet-peerinfo!\n" msgstr "Misslyckades att starta samling.\n" -#: src/testing/testing.c:374 +#: src/testing/testing.c:368 #, fuzzy msgid "Failed to get hostkey!\n" msgstr "Kunde inte skapa värdnyckel!\n" -#: src/testing/testing.c:406 +#: src/testing/testing.c:400 msgid "`Failed while waiting for topology setup!\n" msgstr "" -#: src/testing/testing.c:480 +#: src/testing/testing.c:463 #, fuzzy, c-format msgid "Could not start `%s' process to start GNUnet.\n" msgstr "Kunde inte skapa värdnyckel!\n" -#: src/testing/testing.c:487 +#: src/testing/testing.c:470 #, fuzzy msgid "Failed to start `gnunet-arm' process.\n" msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/testing/testing.c:509 src/testing/testing.c:612 +#: src/testing/testing.c:493 src/testing/testing.c:600 msgid "`gnunet-arm' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:510 src/testing/testing.c:613 -#: src/testing/testing.c:633 +#: src/testing/testing.c:494 src/testing/testing.c:601 +#: src/testing/testing.c:621 msgid "`ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:582 +#: src/testing/testing.c:570 msgid "Unable to get HELLO for peer!\n" msgstr "" -#: src/testing/testing.c:632 +#: src/testing/testing.c:620 msgid "`gnunet-arm' terminated with non-zero exit status (or timed out)!\n" msgstr "" -#: src/testing/testing.c:653 src/testing/testing.c:685 +#: src/testing/testing.c:643 src/testing/testing.c:675 msgid "either `gnunet-arm' or `ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:668 src/testing/testing.c:723 +#: src/testing/testing.c:658 src/testing/testing.c:713 #, fuzzy msgid "shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n" msgstr "\"%s\" är inte ansluten till nĂĽgon ändpunkt.\n" -#: src/testing/testing.c:796 +#: src/testing/testing.c:786 msgid "`scp' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:966 +#: src/testing/testing.c:948 #, fuzzy, c-format msgid "Starting service %s for peer `%4s'\n" msgstr "Startade samling \"%s\".\n" -#: src/testing/testing.c:1237 src/testing/testing_group.c:6278 +#: src/testing/testing.c:1207 src/testing/testing_group.c:6154 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration directory.\n" msgstr "Kunde inte skapa värdnyckel!\n" -#: src/testing/testing.c:1322 src/testing/testing.c:1397 +#: src/testing/testing.c:1292 src/testing/testing.c:1359 #, fuzzy, c-format msgid "Terminating peer `%4s'\n" msgstr "Åtkomst nekad fĂśr \"%s\" vid %s:%d.\n" -#: src/testing/testing.c:1480 +#: src/testing/testing.c:1448 #, fuzzy, c-format msgid "Setting d->dead on peer `%4s'\n" msgstr "Startade samling \"%s\".\n" -#: src/testing/testing.c:1610 +#: src/testing/testing.c:1601 msgid "Peer not yet running, can not change configuration at this point." msgstr "" -#: src/testing/testing.c:1618 +#: src/testing/testing.c:1609 #, fuzzy msgid "Failed to write new configuration to disk." msgstr "Kunde inte spara konfiguration!" -#: src/testing/testing.c:1647 +#: src/testing/testing.c:1636 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration file.\n" msgstr "Kunde inte skapa värdnyckel!\n" -#: src/testing/testing.c:1650 +#: src/testing/testing.c:1639 #, fuzzy msgid "Failed to copy new configuration to remote machine." msgstr "Kunde inte spara konfiguration!" -#: src/testing/testing.c:1805 +#: src/testing/testing.c:1794 #, fuzzy msgid "Peers failed to connect" msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/testing/testing.c:1933 +#: src/testing/testing.c:1922 #, fuzzy msgid "Failed to connect to core service of first peer!\n" msgstr "Misslyckades att starta samling.\n" -#: src/testing/testing.c:2156 +#: src/testing/testing.c:2145 msgid "Peers are not fully running yet, can not connect!\n" msgstr "" -#: src/testing/testing_group.c:1910 src/testing/testing_group.c:1922 -#: src/testing/testing_group.c:2023 src/testing/testing_group.c:2082 -#: src/testing/testing_group.c:2171 src/testing/testing_group.c:2191 -#: src/testing/testing_group.c:2328 src/testing/testing_peergroup.c:940 +#: src/testing/testing_group.c:1895 src/testing/testing_group.c:1907 +#: src/testing/testing_group.c:2008 src/testing/testing_group.c:2065 +#: src/testing/testing_group.c:2152 src/testing/testing_group.c:2172 +#: src/testing/testing_group.c:2302 src/testing/testing_peergroup.c:950 #, fuzzy, c-format msgid "Invalid value `%s' for option `%s' in section `%s': expected float\n" msgstr "Konfigurationsfil \"%s\" hittades inte. KĂśr \"gnunet-setup -d\"!\n" -#: src/testing/testing_group.c:1932 -#, fuzzy, c-format -msgid "Target is %d connections per peer." -msgstr "Misslyckades att starta samling.\n" - -#: src/testing/testing_group.c:2179 +#: src/testing/testing_group.c:2160 #, c-format msgid "" "Invalid value `%s' for option `%s' in section `%s': got %f, needed value " "greater than 0\n" msgstr "" -#: src/testing/testing_group.c:2209 src/testing/testing_group.c:2402 -#, c-format -msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n" -msgstr "" - -#: src/testing/testing_group.c:2246 -#, c-format -msgid "natural log of %d is %d, will run %d iterations\n" -msgstr "" - -#: src/testing/testing_group.c:2249 -#, c-format -msgid "Total connections added thus far: %u!\n" -msgstr "" - -#: src/testing/testing_group.c:2290 -#, c-format -msgid "Total connections added for small world: %d!\n" -msgstr "" - -#: src/testing/testing_group.c:2342 -#, c-format -msgid "rand is %f probability is %f\n" -msgstr "" - -#: src/testing/testing_group.c:2919 src/testing/testing_group.c:3118 +#: src/testing/testing_group.c:2877 src/testing/testing_group.c:3063 #, c-format msgid "" "No `%s' specified in peer configuration in section `%s', cannot copy friends " "file!\n" msgstr "" -#: src/testing/testing_group.c:3020 -msgid "Finished copying all friend files!\n" -msgstr "" - -#: src/testing/testing_group.c:3133 -#, fuzzy, c-format -msgid "Copying file with command cp %s %s\n" -msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" - -#: src/testing/testing_group.c:3156 -#, fuzzy, c-format -msgid "Copying file with command scp %s %s\n" -msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" - -#: src/testing/testing_group.c:3173 -#, c-format -msgid "Checking copy status of file %d\n" +#: src/testing/testing_group.c:3957 +msgid "Creating no allowed topology (all peers can connect at core level)\n" msgstr "" -#: src/testing/testing_group.c:3191 -#, c-format -msgid "File %d copied\n" +#: src/testing/testing_group.c:5226 +msgid "Unknown topology specification, can't connect peers!\n" msgstr "" -#: src/testing/testing_group.c:3206 +#: src/testing/testing_group.c:5944 src/transport/transport-testing.c:636 #, fuzzy -msgid "Finished copying all blacklist files!\n" -msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" - -#: src/testing/testing_group.c:3586 src/testing/testing_group.c:3723 -#: src/testing/testing_group.c:4884 src/testing/testing_group.c:5025 -msgid "Delaying connect, we have too many outstanding connections!\n" -msgstr "" +msgid "Could not read hostkeys file!\n" +msgstr "Kunde inte skapa värdnyckel!\n" -#: src/testing/testing_group.c:3596 src/testing/testing_group.c:4894 -#: src/testing/testing_group.c:5035 -#, c-format -msgid "Creating connection, outstanding_connections is %d\n" -msgstr "" +#: src/testing/testing_group.c:6011 +#, fuzzy, c-format +msgid "Could not create configuration for peer number %u on `%s'!\n" +msgstr "Kunde inte komma ĂĽt namnrymdsinformation.\n" -#: src/testing/testing_group.c:3608 -#, c-format -msgid "Offering HELLO of peer %s to peer %s\n" +#: src/testing/testing_new.c:169 +msgid "tmppath cannot be NULL\n" msgstr "" -#: src/testing/testing_group.c:3734 +#: src/testing/testing_new.c:356 #, c-format -msgid "Creating connection, outstanding_connections is %d (max %d)\n" -msgstr "" - -#: src/testing/testing_group.c:3988 -msgid "Creating clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:3993 -msgid "Creating small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:3998 -msgid "Creating small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4002 -msgid "Creating ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4006 -msgid "Creating 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4010 -msgid "Creating Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4014 -msgid "Creating InterNAT topology\n" -msgstr "" - -#: src/testing/testing_group.c:4018 -msgid "Creating Scale Free topology\n" -msgstr "" - -#: src/testing/testing_group.c:4023 -msgid "Creating straight line topology\n" -msgstr "" - -#: src/testing/testing_group.c:4027 -msgid "Creating topology from file!\n" -msgstr "" - -#: src/testing/testing_group.c:4043 -msgid "Creating no allowed topology (all peers can connect at core level)\n" -msgstr "" - -#: src/testing/testing_group.c:4058 -msgid "Failed during friend file copying!\n" -msgstr "" - -#: src/testing/testing_group.c:4064 -msgid "Friend files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:4081 -msgid "Blacklisting all but clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:4087 -msgid "Blacklisting all but small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4093 -msgid "Blacklisting all but small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4099 -msgid "Blacklisting all but ring topology\n" +msgid "Hostkeys file not found: %s\n" msgstr "" -#: src/testing/testing_group.c:4105 -msgid "Blacklisting all but 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4111 -msgid "Blacklisting all but Erdos-Renyi topology\n" -msgstr "" +#: src/testing/testing_new.c:365 +#, fuzzy, c-format +msgid "Could not open hostkeys file: %s\n" +msgstr "Kunde inte skapa värdnyckel!\n" -#: src/testing/testing_group.c:4117 -msgid "Blacklisting all but InterNAT topology\n" +#: src/testing/testing_new.c:380 +#, c-format +msgid "Incorrect hostkey file format: %s\n" msgstr "" -#: src/testing/testing_group.c:4152 -msgid "Blacklisting all but Scale Free topology\n" -msgstr "" +#: src/testing/testing_new.c:437 +#, fuzzy, c-format +msgid "Key number %u does not exist\n" +msgstr "antal meddelanden att använda per iteration" -#: src/testing/testing_group.c:4158 -msgid "Blacklisting all but straight line topology\n" -msgstr "" +#: src/testing/testing_new.c:446 +#, fuzzy, c-format +msgid "Error while decoding key %u\n" +msgstr "Fel vid nedladdning: %s\n" -#: src/testing/testing_group.c:4173 +#: src/testing/testing_new.c:680 #, fuzzy -msgid "Failed during blacklist file copying!\n" -msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" - -#: src/testing/testing_group.c:4179 -msgid "Blacklist files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:5263 -msgid "Creating clique CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5270 -msgid "Creating small world (ring) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5277 -msgid "Creating small world (2d-torus) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5283 -msgid "Creating ring CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5290 -msgid "Creating 2d torus CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5297 -msgid "Creating Erdos-Renyi CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5304 -msgid "Creating InterNAT CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5311 -msgid "Creating Scale Free CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5318 -msgid "Creating straight line CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5324 -msgid "Creating no CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5330 -msgid "Unknown topology specification, can't connect peers!\n" -msgstr "" +msgid "Failed to create configuration for peer (not enough free ports?)\n" +msgstr "Kunde inte komma ĂĽt namnrymdsinformation.\n" -#: src/testing/testing_group.c:5340 +#: src/testing/testing_new.c:691 #, c-format -msgid "Connecting random subset (%'.2f percent) of possible peers\n" +msgid "" +"You attempted to create a testbed with more than %u hosts. Please " +"precompute more hostkeys first.\n" msgstr "" -#: src/testing/testing_group.c:5348 -#, c-format -msgid "Connecting a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:704 +#, fuzzy, c-format +msgid "Failed to initialize hostkey for peer %u\n" +msgstr "Misslyckades att initiera tjänsten \"%s\".\n" -#: src/testing/testing_group.c:5357 -#, c-format -msgid "Using DFS to connect a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:734 +#, fuzzy, c-format +msgid "Failed to write hostkey file for peer %u: %s\n" +msgstr "Kunde inte skapa användarkonto:" -#: src/testing/testing_group.c:5367 -#, c-format -msgid "Finding additional %u closest peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:751 +#, fuzzy, c-format +msgid "Failed to write configuration file `%s' for peer %u: %s\n" +msgstr "Kunde inte spara konfigurationsfil \"%s\":" -#: src/testing/testing_group.c:6062 src/transport/transport-testing.c:650 -#, fuzzy -msgid "Could not read hostkeys file!\n" -msgstr "Kunde inte skapa värdnyckel!\n" +#: src/testing/testing_new.c:791 +#, fuzzy, c-format +msgid "Failed to start `%s': %s\n" +msgstr "Fel vid %s:%d.\n" -#: src/testing/testing_group.c:6131 +#: src/testing/testing_new.c:959 #, fuzzy, c-format -msgid "Could not create configuration for peer number %u on `%s'!\n" -msgstr "Kunde inte komma ĂĽt namnrymdsinformation.\n" +msgid "Failed to load configuration from %s\n" +msgstr "Kunde inte spara konfigurationsfil \"%s\":" -#: src/topology/gnunet-daemon-topology.c:244 +#: src/topology/gnunet-daemon-topology.c:259 msgid "# peers blacklisted" msgstr "" -#: src/topology/gnunet-daemon-topology.c:380 +#: src/topology/gnunet-daemon-topology.c:392 #, fuzzy msgid "# connect requests issued to transport" msgstr "# byte mottogs via TCP" -#: src/topology/gnunet-daemon-topology.c:675 -#: src/topology/gnunet-daemon-topology.c:761 +#: src/topology/gnunet-daemon-topology.c:730 +#: src/topology/gnunet-daemon-topology.c:815 #, fuzzy msgid "# friends connected" msgstr "# av anslutna parter" -#: src/topology/gnunet-daemon-topology.c:950 +#: src/topology/gnunet-daemon-topology.c:996 msgid "Failed to connect to core service, can not manage topology!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:982 +#: src/topology/gnunet-daemon-topology.c:1026 #, c-format msgid "Option `%s' in section `%s' not specified!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:994 +#: src/topology/gnunet-daemon-topology.c:1039 #, fuzzy, c-format msgid "Could not read friends list `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/topology/gnunet-daemon-topology.c:1000 +#: src/topology/gnunet-daemon-topology.c:1045 #, c-format msgid "Friends file `%s' is empty.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1009 +#: src/topology/gnunet-daemon-topology.c:1054 #, fuzzy, c-format msgid "Failed to read friends list from `%s': out of memory\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/topology/gnunet-daemon-topology.c:1017 +#: src/topology/gnunet-daemon-topology.c:1062 #, c-format msgid "Failed to read friends list from `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/topology/gnunet-daemon-topology.c:1037 +#: src/topology/gnunet-daemon-topology.c:1082 #, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1050 +#: src/topology/gnunet-daemon-topology.c:1095 #, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1060 +#: src/topology/gnunet-daemon-topology.c:1105 #, fuzzy, c-format msgid "Found friend `%s' in configuration\n" msgstr " gconfig\tGTK-konfiguration\n" -#: src/topology/gnunet-daemon-topology.c:1066 +#: src/topology/gnunet-daemon-topology.c:1111 #, c-format msgid "Found myself `%s' in friend list (useless, ignored)\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1076 +#: src/topology/gnunet-daemon-topology.c:1121 #, fuzzy msgid "# friends in configuration" msgstr " gconfig\tGTK-konfiguration\n" -#: src/topology/gnunet-daemon-topology.c:1082 +#: src/topology/gnunet-daemon-topology.c:1127 msgid "" "Fewer friends specified than required by minimum friend count. Will only " "connect to friends.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1089 +#: src/topology/gnunet-daemon-topology.c:1134 msgid "" "More friendly connections required than target total number of connections.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1126 +#: src/topology/gnunet-daemon-topology.c:1169 #, fuzzy msgid "# HELLO messages received" msgstr "# krypterade PONG-meddelanden mottagna" -#: src/topology/gnunet-daemon-topology.c:1183 +#: src/topology/gnunet-daemon-topology.c:1224 msgid "# HELLO messages gossipped" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1323 +#: src/topology/gnunet-daemon-topology.c:1363 msgid "GNUnet topology control (maintaining P2P mesh and F2F constraints)" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:247 +#: src/transport/gnunet-service-transport_blacklist.c:246 #, fuzzy, c-format msgid "Could not read blacklist file `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/transport/gnunet-service-transport_blacklist.c:254 +#: src/transport/gnunet-service-transport_blacklist.c:252 #, c-format msgid "Blacklist file `%s' is empty.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:266 +#: src/transport/gnunet-service-transport_blacklist.c:263 #, fuzzy, c-format msgid "Failed to read blacklist from `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/transport/gnunet-service-transport_blacklist.c:287 -#: src/transport/gnunet-service-transport_blacklist.c:311 +#: src/transport/gnunet-service-transport_blacklist.c:284 +#: src/transport/gnunet-service-transport_blacklist.c:308 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, giving up!\n" msgstr "Syntaxfel i konfigurationsfil \"%s\" pĂĽ rad %d.\n" -#: src/transport/gnunet-service-transport_blacklist.c:298 -#: src/transport/gnunet-service-transport_blacklist.c:336 +#: src/transport/gnunet-service-transport_blacklist.c:295 +#: src/transport/gnunet-service-transport_blacklist.c:331 #, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:350 +#: src/transport/gnunet-service-transport_blacklist.c:345 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n" msgstr "Syntaxfel i konfigurationsfil \"%s\" pĂĽ rad %d.\n" -#: src/transport/gnunet-service-transport_blacklist.c:364 +#: src/transport/gnunet-service-transport_blacklist.c:359 #, c-format msgid "Found myself `%s' in blacklist (useless, ignored)\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:523 -#: src/transport/gnunet-service-transport_blacklist.c:764 +#: src/transport/gnunet-service-transport_blacklist.c:514 +#: src/transport/gnunet-service-transport_blacklist.c:747 msgid "# disconnects due to blacklist" msgstr "" -#: src/transport/gnunet-service-transport.c:158 +#: src/transport/gnunet-service-transport.c:163 #, fuzzy msgid "# bytes payload discarded due to not connected peer " msgstr "Nätverksannonsering avstängd i konfigurationen!\n" -#: src/transport/gnunet-service-transport.c:572 +#: src/transport/gnunet-service-transport.c:237 +#, fuzzy +msgid "# bytes total received" +msgstr "# byte krypterade" + +#: src/transport/gnunet-service-transport.c:284 +#, fuzzy +msgid "# bytes payload received" +msgstr "# byte dekrypterade" + +#: src/transport/gnunet-service-transport.c:582 msgid "Transport service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport.c:581 +#: src/transport/gnunet-service-transport.c:591 msgid "Transport service could not access hostkey. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:353 +#: src/transport/gnunet-service-transport_clients.c:352 #, c-format msgid "Dropping message of type %u and size %u, have %u/%u messages pending\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:358 +#: src/transport/gnunet-service-transport_clients.c:357 msgid "# messages dropped due to slow client" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:510 +#: src/transport/gnunet-service-transport_clients.c:503 #, c-format msgid "Rejecting control connection from peer `%s', which is not me!\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:628 -#, fuzzy -msgid "# bytes payload received for other peers" -msgstr "# byte mottagna av typen %d" - -#: src/transport/gnunet-service-transport_clients.c:645 +#: src/transport/gnunet-service-transport_clients.c:631 msgid "# bytes payload dropped (other peer was not connected)" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:696 +#: src/transport/gnunet-service-transport_clients.c:682 #, fuzzy msgid "# REQUEST CONNECT messages received" msgstr "# krypterade PONG-meddelanden mottagna" @@ -4288,616 +4604,561 @@ msgstr "# krypterade PONG-meddelanden mottagna" msgid "# refreshed my HELLO" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:482 -msgid "# failed connection attempts due to timeout" +#: src/transport/gnunet-service-transport_neighbours.c:1032 +#, fuzzy +msgid "# DISCONNECT messages sent" +msgstr "# krypterade PONG-meddelanden mottagna" + +#: src/transport/gnunet-service-transport_neighbours.c:1148 +#: src/transport/gnunet-service-transport_neighbours.c:1482 +msgid "# bytes in message queue for other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:883 +#: src/transport/gnunet-service-transport_neighbours.c:1153 #, fuzzy -msgid "# peers disconnected due to external request" -msgstr "# av anslutna parter" +msgid "# messages transmitted to other peers" +msgstr "# byte skickade av typen %d" -#: src/transport/gnunet-service-transport_neighbours.c:966 +#: src/transport/gnunet-service-transport_neighbours.c:1158 #, fuzzy -msgid "# fast reconnects failed" -msgstr "# av anslutna parter" +msgid "# transmission failures for messages to other peers" +msgstr "# byte skickade av typen %d" -#: src/transport/gnunet-service-transport_neighbours.c:1022 -#, fuzzy -msgid "# peers disconnected due to timeout" -msgstr "# av anslutna parter" +#: src/transport/gnunet-service-transport_neighbours.c:1215 +msgid "# messages timed out while in transport queue" +msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1047 +#: src/transport/gnunet-service-transport_neighbours.c:1254 #, fuzzy msgid "# keepalives sent" msgstr "# sessionsnycklar skickade" -#: src/transport/gnunet-service-transport_neighbours.c:1088 +#: src/transport/gnunet-service-transport_neighbours.c:1278 #, fuzzy -msgid "# peers disconnected due to global disconnect" +msgid "# KEEPALIVE messages discarded (peer unknown)" msgstr "Nätverksannonsering avstängd i konfigurationen!\n" -#: src/transport/gnunet-service-transport_neighbours.c:1888 -#: src/transport/gnunet-service-transport_neighbours.c:1909 -msgid "# messages not sent (no such peer or not connected)" -msgstr "" +#: src/transport/gnunet-service-transport_neighbours.c:1286 +#, fuzzy +msgid "# KEEPALIVE messages discarded (no session)" +msgstr "Nätverksannonsering avstängd i konfigurationen!\n" -#: src/transport/gnunet-service-transport_neighbours.c:1925 -msgid "# bytes in message queue for other peers" -msgstr "" +#: src/transport/gnunet-service-transport_neighbours.c:1323 +#, fuzzy +msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" +msgstr "Nätverksannonsering avstängd i konfigurationen!\n" + +#: src/transport/gnunet-service-transport_neighbours.c:1332 +#, fuzzy +msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" +msgstr "Nätverksannonsering avstängd i konfigurationen!\n" -#: src/transport/gnunet-service-transport_neighbours.c:1977 +#: src/transport/gnunet-service-transport_neighbours.c:1388 #, fuzzy msgid "# messages discarded due to lack of neighbour record" msgstr "Nätverksannonsering avstängd i konfigurationen!\n" -#: src/transport/gnunet-service-transport_neighbours.c:2013 +#: src/transport/gnunet-service-transport_neighbours.c:1422 msgid "# bandwidth quota violations by other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2031 +#: src/transport/gnunet-service-transport_neighbours.c:1438 msgid "# ms throttling suggested" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2060 -msgid "# KEEPALIVE messages discarded (not connected)" -msgstr "" +#: src/transport/gnunet-service-transport_neighbours.c:2544 +#, fuzzy +msgid "# unexpected CONNECT_ACK messages (no peer)" +msgstr "skicka ANTAL meddelanden" -#: src/transport/gnunet-service-transport_neighbours.c:2113 +#: src/transport/gnunet-service-transport_neighbours.c:2559 +#: src/transport/gnunet-service-transport_neighbours.c:2585 #, fuzzy -msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" -msgstr "Nätverksannonsering avstängd i konfigurationen!\n" +msgid "# unexpected CONNECT_ACK messages (not ready)" +msgstr "skicka ANTAL meddelanden" -#: src/transport/gnunet-service-transport_neighbours.c:2121 +#: src/transport/gnunet-service-transport_neighbours.c:2598 #, fuzzy -msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" -msgstr "Nätverksannonsering avstängd i konfigurationen!\n" +msgid "# unexpected CONNECT_ACK messages (waiting on ATS)" +msgstr "skicka ANTAL meddelanden" + +#: src/transport/gnunet-service-transport_neighbours.c:2627 +#, fuzzy +msgid "# unexpected CONNECT_ACK messages (disconnecting)" +msgstr "skicka ANTAL meddelanden" + +#: src/transport/gnunet-service-transport_neighbours.c:2807 +#, fuzzy +msgid "# unexpected SESSION ACK messages" +msgstr "# krypterade PONG-meddelanden skickade" -#: src/transport/gnunet-service-transport_neighbours.c:2187 +#: src/transport/gnunet-service-transport_neighbours.c:2856 msgid "# SET QUOTA messages ignored (no such peer)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2205 +#: src/transport/gnunet-service-transport_neighbours.c:2870 msgid "# disconnects due to quota of 0" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2323 +#: src/transport/gnunet-service-transport_neighbours.c:2901 msgid "# disconnect messages ignored (old format)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2336 +#: src/transport/gnunet-service-transport_neighbours.c:2912 msgid "# disconnect messages ignored (timestamp)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2411 -#, fuzzy -msgid "# unexpected CONNECT_ACK messages (no peer)" -msgstr "skicka ANTAL meddelanden" - -#: src/transport/gnunet-service-transport_neighbours.c:2453 -#, fuzzy -msgid "# unexpected CONNECT_ACK messages" -msgstr "skicka ANTAL meddelanden" +#: src/transport/gnunet-service-transport_neighbours.c:2943 +msgid "# other peer asked to disconnect from us" +msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2544 +#: src/transport/gnunet-service-transport_neighbours.c:3020 #, fuzzy -msgid "# unexpected ACK messages" -msgstr "# krypterade PONG-meddelanden skickade" +msgid "# disconnected from peer upon explicit request" +msgstr "# av anslutna parter" #: src/transport/gnunet-service-transport_plugins.c:111 msgid "Transport service is lacking NEIGHBOUR_LIMIT option.\n" msgstr "" -#: src/transport/gnunet-service-transport_plugins.c:118 -#, fuzzy, c-format -msgid "Starting transport plugins `%s'\n" -msgstr "Testar transport(er) %s\n" - -#: src/transport/gnunet-service-transport_plugins.c:122 -#, fuzzy, c-format -msgid "Loading `%s' transport plugin\n" -msgstr "Testar transport(er) %s\n" - -#: src/transport/gnunet-service-transport_plugins.c:150 -#, fuzzy, c-format -msgid "Failed to load transport plugin for `%s'\n" -msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" - -#: src/transport/gnunet-service-transport_validation.c:410 +#: src/transport/gnunet-service-transport_validation.c:414 msgid "# address records discarded" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:459 +#: src/transport/gnunet-service-transport_validation.c:463 #, c-format msgid "" "Not transmitting `%s' with `%s', message too big (%u bytes!). This should " "not happen.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:508 +#: src/transport/gnunet-service-transport_validation.c:512 #, fuzzy msgid "# PING without HELLO messages sent" msgstr "# PING-meddelanden i klartext skickade" -#: src/transport/gnunet-service-transport_validation.c:566 +#: src/transport/gnunet-service-transport_validation.c:570 msgid "# address revalidations started" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:798 +#: src/transport/gnunet-service-transport_validation.c:805 #, fuzzy msgid "# PING message for different peer received" msgstr "# PING-meddelanden skapade" -#: src/transport/gnunet-service-transport_validation.c:833 +#: src/transport/gnunet-service-transport_validation.c:840 #, c-format msgid "" "Not confirming PING with address `%s' since I cannot confirm having this " "address.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:919 +#: src/transport/gnunet-service-transport_validation.c:924 msgid "# PONGs unicast via reliable transport" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:928 +#: src/transport/gnunet-service-transport_validation.c:933 msgid "# PONGs multicast to all available addresses" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1050 +#: src/transport/gnunet-service-transport_validation.c:1055 msgid "# PONGs dropped, no matching pending validation" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1075 +#: src/transport/gnunet-service-transport_validation.c:1080 msgid "# PONGs dropped, signature expired" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1134 +#: src/transport/gnunet-service-transport_validation.c:1136 #, fuzzy, c-format msgid "Adding `%s' without addresses for peer `%s'\n" msgstr "Motpart \"%s\" med pĂĽlitlighet %8u och adress \"%s\"\n" -#: src/transport/gnunet-transport.c:256 +#: src/transport/gnunet-transport.c:260 msgid "No transport plugins configured, peer will never communicate\n" msgstr "" -#: src/transport/gnunet-transport.c:269 +#: src/transport/gnunet-transport.c:273 #, c-format msgid "No port configured for plugin `%s', cannot test it\n" msgstr "" -#: src/transport/gnunet-transport.c:319 +#: src/transport/gnunet-transport.c:323 #, c-format msgid "Received %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:326 +#: src/transport/gnunet-transport.c:330 #, c-format msgid "Transmitted %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:359 +#: src/transport/gnunet-transport.c:363 #, fuzzy, c-format msgid "Transmitting %u bytes to %s\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/transport/gnunet-transport.c:379 +#: src/transport/gnunet-transport.c:383 #, fuzzy, c-format msgid "Connected to %s\n" msgstr "\"%s\" ansluten till \"%s\".\n" -#: src/transport/gnunet-transport.c:410 +#: src/transport/gnunet-transport.c:414 #, fuzzy, c-format msgid "Disconnected from %s\n" msgstr "\"%s\" ansluten till \"%s\".\n" -#: src/transport/gnunet-transport.c:439 +#: src/transport/gnunet-transport.c:443 #, c-format msgid "Received %u bytes from %s\n" msgstr "" -#: src/transport/gnunet-transport.c:453 +#: src/transport/gnunet-transport.c:466 #, fuzzy, c-format msgid "Peer `%s': %s %s\n" msgstr "Jag är ändpunkt \"%s\".\n" -#: src/transport/gnunet-transport.c:483 +#: src/transport/gnunet-transport.c:473 +#, c-format +msgid "Peer `%s': %s \n" +msgstr "" + +#: src/transport/gnunet-transport.c:501 #, fuzzy, c-format msgid "Peer `%s' disconnected\n" msgstr "# av anslutna parter" -#: src/transport/gnunet-transport.c:539 +#: src/transport/gnunet-transport.c:569 #, fuzzy, c-format msgid "Failed to parse peer identity `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/transport/gnunet-transport.c:587 +#: src/transport/gnunet-transport.c:618 msgid "measure how fast we are receiving data (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:590 +#: src/transport/gnunet-transport.c:621 #, fuzzy msgid "try to connect to the given peer" msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/transport/gnunet-transport.c:593 +#: src/transport/gnunet-transport.c:624 #, fuzzy msgid "provide information about all current connections (once)" msgstr "Skriv ut information om GNUnets motparter." -#: src/transport/gnunet-transport.c:596 +#: src/transport/gnunet-transport.c:627 #, fuzzy msgid "provide information about all current connections (continuously)" msgstr "Skriv ut information om GNUnets motparter." -#: src/transport/gnunet-transport.c:599 +#: src/transport/gnunet-transport.c:630 #, fuzzy msgid "do not resolve hostnames" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/transport/gnunet-transport.c:603 +#: src/transport/gnunet-transport.c:634 msgid "send data for benchmarking to the other peer (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:606 +#: src/transport/gnunet-transport.c:637 msgid "test transport configuration (involves external server)" msgstr "" -#: src/transport/gnunet-transport.c:614 +#: src/transport/gnunet-transport.c:645 #, fuzzy msgid "Direct access to transport service." msgstr "Misslyckades att ansluta till gnunetd.\n" -#: src/transport/plugin_transport_http.c:981 +#: src/transport/plugin_transport_http.c:1100 msgid "Disabling IPv6 since it is not supported on this system!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1029 +#: src/transport/plugin_transport_http.c:1149 #, fuzzy msgid "Require valid port number for service in configuration!\n" msgstr "Inga applikationer definierade i konfiguration!\n" -#: src/transport/plugin_transport_http.c:1054 src/util/service.c:986 +#: src/transport/plugin_transport_http.c:1174 src/util/service.c:1036 #, fuzzy, c-format msgid "Failed to resolve `%s': %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/transport/plugin_transport_http.c:1071 src/util/service.c:1003 +#: src/transport/plugin_transport_http.c:1191 src/util/service.c:1053 #, fuzzy, c-format msgid "Failed to find %saddress for `%s'.\n" msgstr "Misslyckades att binda till UDP-port %d.\n" -#: src/transport/plugin_transport_http.c:1176 +#: src/transport/plugin_transport_http.c:1296 #, c-format msgid "Found %u addresses to report to NAT service\n" msgstr "" -#: src/transport/plugin_transport_http.c:1189 +#: src/transport/plugin_transport_http.c:1309 #, c-format msgid "FREEING %s\n" msgstr "" -#: src/transport/plugin_transport_http.c:1264 +#: src/transport/plugin_transport_http.c:1386 msgid "Neither IPv4 nor IPv6 are enabled! Fix in configuration\n" msgstr "" -#: src/transport/plugin_transport_http.c:1277 +#: src/transport/plugin_transport_http.c:1399 #, fuzzy msgid "Port is required! Fix in configuration\n" msgstr " gconfig\tGTK-konfiguration\n" -#: src/transport/plugin_transport_http.c:1288 +#: src/transport/plugin_transport_http.c:1410 msgid "Port 0, client only mode\n" msgstr "" -#: src/transport/plugin_transport_http.c:1308 +#: src/transport/plugin_transport_http.c:1430 #, c-format msgid "" "Specific IPv4 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1338 +#: src/transport/plugin_transport_http.c:1460 #, c-format msgid "" "Specific IPv6 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http_client.c:621 +#: src/transport/plugin_transport_http_client.c:624 #, c-format msgid "Could not initialize curl multi handle, failed to start %s plugin!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:189 +#: src/transport/plugin_transport_http_server.c:178 msgid "" "Could not create a new TLS certificate, program `gnunet-transport-" "certificate-creation' could not be started!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:213 +#: src/transport/plugin_transport_http_server.c:202 msgid "No usable TLS certificate found and creating one failed!\n" msgstr "" -#: src/transport/plugin_transport_smtp.c:370 -#, fuzzy, c-format -msgid "Received malformed message via %s. Ignored.\n" -msgstr "Mottog ogiltigt \"%s\" meddelande frĂĽn \"%s\".\n" - -# capped är inte ett bra ord IMHO -#: src/transport/plugin_transport_smtp.c:457 -#, fuzzy -msgid "SMTP filter string to invalid, lacks ': '\n" -msgstr "SMTP-filtersträng fĂśr lĂĽng, kapad till \"%s\"\n" - -# capped är inte ett bra ord IMHO -#: src/transport/plugin_transport_smtp.c:466 -#, c-format -msgid "SMTP filter string to long, capped to `%s'\n" -msgstr "SMTP-filtersträng fĂśr lĂĽng, kapad till \"%s\"\n" - -#: src/transport/plugin_transport_smtp.c:561 -#: src/transport/plugin_transport_smtp.c:571 -#: src/transport/plugin_transport_smtp.c:584 -#: src/transport/plugin_transport_smtp.c:603 -#: src/transport/plugin_transport_smtp.c:626 -#: src/transport/plugin_transport_smtp.c:634 -#: src/transport/plugin_transport_smtp.c:647 -#: src/transport/plugin_transport_smtp.c:658 -#, fuzzy, c-format -msgid "SMTP: `%s' failed: %s.\n" -msgstr "\"%s\" %s misslyckades: %s\n" - -#: src/transport/plugin_transport_smtp.c:801 -msgid "No email-address specified, can not start SMTP transport.\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:813 -#, fuzzy -msgid "# bytes received via SMTP" -msgstr "# byte mottogs via TCP" - -#: src/transport/plugin_transport_smtp.c:814 -#, fuzzy -msgid "# bytes sent via SMTP" -msgstr "# byte skickades via TCP" - -#: src/transport/plugin_transport_smtp.c:816 -#, fuzzy -msgid "# bytes dropped by SMTP (outgoing)" -msgstr "# byte kastade via TCP (utgĂĽende)" - -#: src/transport/plugin_transport_tcp.c:512 +#: src/transport/plugin_transport_tcp.c:591 #, c-format msgid "Unexpected address length: %u bytes\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:616 -#: src/transport/plugin_transport_tcp.c:705 -#: src/transport/plugin_transport_tcp.c:757 -#: src/transport/plugin_transport_tcp.c:830 -#: src/transport/plugin_transport_tcp.c:909 +#: src/transport/plugin_transport_tcp.c:767 +#: src/transport/plugin_transport_tcp.c:856 +#: src/transport/plugin_transport_tcp.c:906 +#: src/transport/plugin_transport_tcp.c:992 +#: src/transport/plugin_transport_tcp.c:1086 +#: src/transport/plugin_transport_tcp.c:1103 #, fuzzy msgid "# bytes currently in TCP buffers" msgstr "# byte skickades via TCP" -#: src/transport/plugin_transport_tcp.c:622 -#: src/transport/plugin_transport_tcp.c:856 -#: src/transport/plugin_transport_tcp.c:1561 +#: src/transport/plugin_transport_tcp.c:774 +#: src/transport/plugin_transport_tcp.c:963 +#: src/transport/plugin_transport_tcp.c:1761 +#: src/transport/plugin_transport_tcp.c:2390 #, fuzzy msgid "# TCP sessions active" msgstr "# sessionsnycklar accepterade" -#: src/transport/plugin_transport_tcp.c:709 +#: src/transport/plugin_transport_tcp.c:860 #, fuzzy msgid "# bytes discarded by TCP (timeout)" msgstr "# byte kastade via TCP (utgĂĽende)" -#: src/transport/plugin_transport_tcp.c:760 +#: src/transport/plugin_transport_tcp.c:909 #, fuzzy msgid "# bytes transmitted via TCP" msgstr "# byte skickade av typen %d" -#: src/transport/plugin_transport_tcp.c:834 +#: src/transport/plugin_transport_tcp.c:996 #, fuzzy msgid "# bytes discarded by TCP (disconnect)" msgstr "# byte kastade via TCP (utgĂĽende)" -#: src/transport/plugin_transport_tcp.c:1081 +#: src/transport/plugin_transport_tcp.c:1290 #, c-format msgid "Address of unexpected length: %u\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1116 -msgid "Found valid IPv4 NAT address (creating session)!\n" -msgstr "" - -#: src/transport/plugin_transport_tcp.c:1186 +#: src/transport/plugin_transport_tcp.c:1401 msgid "# transport-service disconnect requests for TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:1603 +#: src/transport/plugin_transport_tcp.c:1802 #, fuzzy msgid "# TCP WELCOME messages received" msgstr "# krypterade PONG-meddelanden mottagna" -#: src/transport/plugin_transport_tcp.c:1756 +#: src/transport/plugin_transport_tcp.c:1973 msgid "# bytes received via TCP" msgstr "# byte mottogs via TCP" -#: src/transport/plugin_transport_tcp.c:1823 +#: src/transport/plugin_transport_tcp.c:2043 msgid "# network-level TCP disconnect events" msgstr "" -#: src/transport/plugin_transport_tcp.c:1962 src/util/service.c:889 +#: src/transport/plugin_transport_tcp.c:2279 src/util/service.c:940 #, c-format msgid "Require valid port number for service `%s' in configuration!\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1976 +#: src/transport/plugin_transport_tcp.c:2293 #, fuzzy msgid "Failed to start service.\n" msgstr "Misslyckades att starta samling.\n" -#: src/transport/plugin_transport_tcp.c:2039 +#: src/transport/plugin_transport_tcp.c:2355 #, fuzzy, c-format msgid "Failed to find option %s in section %s!\n" msgstr "Misslyckades att binda till UDP-port %d.\n" -#: src/transport/plugin_transport_tcp.c:2062 +#: src/transport/plugin_transport_tcp.c:2378 #, c-format msgid "TCP transport listening on port %llu\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2066 +#: src/transport/plugin_transport_tcp.c:2382 msgid "TCP transport not listening on any port (client only)\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2070 +#: src/transport/plugin_transport_tcp.c:2386 #, c-format msgid "TCP transport advertises itself as being on port %llu\n" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:130 +#: src/transport/plugin_transport_udp_broadcasting.c:128 #, fuzzy msgid "# IPv6 multicast HELLO beacons received via udp" msgstr "# krypterade PONG-meddelanden mottagna" -#: src/transport/plugin_transport_udp_broadcasting.c:172 +#: src/transport/plugin_transport_udp_broadcasting.c:169 #, fuzzy msgid "# IPv4 broadcast HELLO beacons received via udp" msgstr "# krypterade PONG-meddelanden mottagna" -#: src/transport/plugin_transport_udp_broadcasting.c:393 +#: src/transport/plugin_transport_udp_broadcasting.c:367 #, c-format msgid "Failed to set IPv4 broadcast option for broadcast socket on port %d\n" msgstr "" -#: src/transport/plugin_transport_udp.c:1985 +#: src/transport/plugin_transport_udp.c:1894 +#, c-format +msgid "" +"UDP could not message to `%s': `%s'. Please check your network configuration " +"and disable IPv6 if your connection does not have a global IPv6 address\n" +msgstr "" + +#: src/transport/plugin_transport_udp.c:2138 #, fuzzy msgid "Failed to open UDP sockets\n" msgstr "Misslyckades att binda till UDP6-port %d.\n" -#: src/transport/plugin_transport_udp.c:2068 +#: src/transport/plugin_transport_udp.c:2306 #, c-format msgid "Given `%s' option is out of range: %llu > %u\n" msgstr "" -#: src/transport/plugin_transport_udp.c:2112 +#: src/transport/plugin_transport_udp.c:2349 #, fuzzy, c-format msgid "Invalid IPv6 address: `%s'\n" msgstr "Ogiltigt svar pĂĽ \"%s\".\n" -#: src/transport/plugin_transport_unix.c:1051 +#: src/transport/plugin_transport_unix.c:1356 #, fuzzy msgid "Failed to open UNIX sockets\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/transport/plugin_transport_wlan.c:875 +#: src/transport/plugin_transport_wlan.c:561 +msgid "# WLAN ACKs sent" +msgstr "" + +#: src/transport/plugin_transport_wlan.c:580 #, fuzzy -msgid "# wlan session timeouts" -msgstr "# sessionsnycklar accepterade" +msgid "# WLAN messages defragmented" +msgstr "# PING-meddelanden skapade" -#: src/transport/plugin_transport_wlan.c:899 +#: src/transport/plugin_transport_wlan.c:626 +#: src/transport/plugin_transport_wlan.c:676 +#: src/transport/plugin_transport_wlan.c:1696 #, fuzzy -msgid "# wlan session created" +msgid "# WLAN sessions allocated" msgstr "# sessionsnycklar accepterade" -#: src/transport/plugin_transport_wlan.c:980 -#: src/transport/plugin_transport_wlan.c:1138 -#: src/transport/plugin_transport_wlan.c:1159 -#: src/transport/plugin_transport_wlan.c:1190 -#: src/transport/plugin_transport_wlan.c:2334 -#: src/transport/plugin_transport_wlan.c:3142 -msgid "# wlan pending sessions" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:1233 -#: src/transport/plugin_transport_wlan.c:1888 +#: src/transport/plugin_transport_wlan.c:749 #, fuzzy -msgid "# wlan pending fragments" +msgid "# WLAN message fragments sent" msgstr "# byte mottogs via TCP" -#: src/transport/plugin_transport_wlan.c:1388 -#, c-format -msgid "" -"Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:1732 -msgid "# wlan hello beacons send" +#: src/transport/plugin_transport_wlan.c:767 +msgid "# WLAN messages pending (with fragmentation)" msgstr "" -#: src/transport/plugin_transport_wlan.c:1765 -#: src/transport/plugin_transport_wlan.c:1968 -#: src/transport/plugin_transport_wlan.c:2059 -#, c-format -msgid "Error writing to wlan helper. errno == %d, ERROR: %s\n" -msgstr "" +#: src/transport/plugin_transport_wlan.c:867 +#: src/transport/plugin_transport_wlan.c:948 +#: src/transport/plugin_transport_wlan.c:1698 +#, fuzzy +msgid "# WLAN MAC endpoints allocated" +msgstr "# byte mottogs via TCP" -#: src/transport/plugin_transport_wlan.c:1954 -msgid "# wlan acks send" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1119 +#, fuzzy +msgid "# HELLO messages received via WLAN" +msgstr "# krypterade PONG-meddelanden mottagna" -#: src/transport/plugin_transport_wlan.c:2025 +#: src/transport/plugin_transport_wlan.c:1140 #, fuzzy -msgid "# wlan fragments send" +msgid "# fragments received via WLAN" msgstr "# byte mottogs via TCP" -#: src/transport/plugin_transport_wlan.c:2161 -#, c-format -msgid "Wlan Address len %d is wrong\n" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:2295 -#: src/transport/plugin_transport_wlan.c:2919 -#: src/transport/plugin_transport_wlan.c:3145 -msgid "# wlan mac endpoints" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1150 +#, fuzzy +msgid "# ACKs received via WLAN" +msgstr "# byte mottogs via TCP" -#: src/transport/plugin_transport_wlan.c:2517 +#: src/transport/plugin_transport_wlan.c:1207 #, fuzzy -msgid "# wlan whole messages received" -msgstr "# krypterade PONG-meddelanden mottagna" +msgid "# WLAN DATA messages discarded due to CRC32 error" +msgstr "Nätverksannonsering avstängd i konfigurationen!\n" -#: src/transport/plugin_transport_wlan.c:2708 +#: src/transport/plugin_transport_wlan.c:1306 #, fuzzy -msgid "# wlan hello messages received" +msgid "# DATA messages received via WLAN" msgstr "# krypterade PONG-meddelanden mottagna" -#: src/transport/plugin_transport_wlan.c:2742 +#: src/transport/plugin_transport_wlan.c:1341 #, fuzzy -msgid "# wlan fragments received" -msgstr "# byte mottogs via TCP" +msgid "# WLAN DATA messages processed" +msgstr "# krypterade PONG-meddelanden mottagna" -#: src/transport/plugin_transport_wlan.c:2790 +#: src/transport/plugin_transport_wlan.c:1402 #, fuzzy -msgid "# wlan acks received" -msgstr "# klartext PONG-meddelanden mottagna" +msgid "# HELLO beacons sent via WLAN" +msgstr "# byte skickade via UDP" -#: src/transport/plugin_transport_wlan.c:2879 -msgid "# wlan mac endpoints timeouts" +#: src/transport/plugin_transport_wlan.c:1511 +msgid "WLAN address with invalid size encountered\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:2903 -#, fuzzy -msgid "# wlan mac endpoints created" -msgstr "# byte mottogs via TCP" +#: src/transport/plugin_transport_wlan.c:1668 +#, fuzzy, c-format +msgid "Invalid configuration option `%s' in section `%s'\n" +msgstr "Konfigurationsfil \"%s\" skapad.\n" -#: src/transport/plugin_transport_wlan.c:2956 -msgid "# wlan WLAN_HELPER_DATA received" +#: src/transport/plugin_transport_wlan.c:1677 +#, c-format +msgid "Helper binary `%s' not SUID, cannot run WLAN transport\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:3010 -#, fuzzy -msgid "# wlan messages for this client received" -msgstr "# krypterade PONG-meddelanden mottagna" - -#: src/transport/plugin_transport_wlan.c:3021 -#, fuzzy -msgid "# wlan messages inside WLAN_HELPER_DATA received" -msgstr "# krypterade PONG-meddelanden mottagna" +#: src/transport/plugin_transport_wlan.c:1687 +#, fuzzy, c-format +msgid "Missing configuration option `%s' in section `%s'\n" +msgstr "Konfigurationsfil \"%s\" skapad.\n" -#: src/transport/transport_api.c:588 +#: src/transport/transport_api.c:570 #, fuzzy, c-format msgid "Received unexpected message of type %u in %s:%u\n" msgstr "Mottog skadat meddelande frĂĽn motpart \"%s\"i %s:%d.\n" @@ -4932,134 +5193,127 @@ msgstr "" msgid "Metadata `%s' failed to deserialize" msgstr "" -#: src/util/client.c:304 +#: src/util/client.c:359 #, c-format msgid "" "Could not determine valid hostname and port for service `%s' from " "configuration.\n" msgstr "" -#: src/util/client.c:312 +#: src/util/client.c:367 #, c-format msgid "Need a non-empty hostname for service `%s'.\n" msgstr "" -#: src/util/client.c:657 +#: src/util/client.c:685 msgid "Failure to transmit TEST request.\n" msgstr "" -#: src/util/client.c:717 src/util/service.c:919 +#: src/util/client.c:740 src/util/service.c:970 #, c-format msgid "UNIXPATH `%s' too long, maximum length is %llu\n" msgstr "" -#: src/util/client.c:859 +#: src/util/client.c:882 #, fuzzy, c-format msgid "Could not connect to service `%s', must not be running.\n" msgstr "Kunde inte ansluta till gnunetd.\n" -#: src/util/client.c:875 +#: src/util/client.c:896 #, fuzzy, c-format msgid "Failure to transmit request to service `%s'\n" msgstr "Misslyckades att skicka HTTP-begäran till värd \"%s\": %s\n" -#: src/util/client.c:1143 +#: src/util/client.c:1149 msgid "Could not submit request, not expecting to receive a response.\n" msgstr "" -#: src/util/common_logging.c:239 src/util/common_logging.c:889 +#: src/util/common_logging.c:239 src/util/common_logging.c:890 msgid "DEBUG" msgstr "FELSÖKNING" -#: src/util/common_logging.c:241 src/util/common_logging.c:887 +#: src/util/common_logging.c:241 src/util/common_logging.c:888 msgid "INFO" msgstr "INFO" -#: src/util/common_logging.c:243 src/util/common_logging.c:885 +#: src/util/common_logging.c:243 src/util/common_logging.c:886 msgid "WARNING" msgstr "VARNING" -#: src/util/common_logging.c:245 src/util/common_logging.c:883 +#: src/util/common_logging.c:245 src/util/common_logging.c:884 msgid "ERROR" msgstr "FEL" -#: src/util/common_logging.c:247 src/util/common_logging.c:891 +#: src/util/common_logging.c:247 src/util/common_logging.c:892 msgid "NONE" msgstr "" -#: src/util/common_logging.c:609 +#: src/util/common_logging.c:610 #, fuzzy, c-format msgid "Failed to create or access directory for log file `%s'\n" msgstr "Kunde inte tolka konfigurationsfil \"%s\".\n" -#: src/util/common_logging.c:724 +#: src/util/common_logging.c:725 #, c-format msgid "Message `%.*s' repeated %u times in the last %s\n" msgstr "" -#: src/util/common_logging.c:892 +#: src/util/common_logging.c:893 msgid "INVALID" msgstr "" -#: src/util/common_logging.c:991 +#: src/util/common_logging.c:992 msgid "unknown address" msgstr "" -#: src/util/common_logging.c:1029 +#: src/util/common_logging.c:1030 msgid "invalid address" msgstr "" -#: src/util/configuration.c:245 +#: src/util/configuration.c:244 #, fuzzy, c-format msgid "Syntax error in configuration file `%s' at line %u.\n" msgstr "Syntaxfel i konfigurationsfil \"%s\" pĂĽ rad %d.\n" -#: src/util/configuration.c:817 +#: src/util/configuration.c:816 #, c-format msgid "" "Configuration value '%s' for '%s' in section '%s' is not in set of legal " "choices\n" msgstr "" -#: src/util/connection.c:460 +#: src/util/connection.c:420 #, fuzzy, c-format msgid "Access denied to `%s'\n" msgstr "Åtkomst nekad fĂśr \"%s\" vid %s:%d.\n" -#: src/util/connection.c:475 +#: src/util/connection.c:435 #, c-format msgid "Accepting connection from `%s': %p\n" msgstr "" -#: src/util/connection.c:629 +#: src/util/connection.c:550 #, fuzzy, c-format msgid "" "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n" msgstr "Misslyckades att starta samling.\n" -#: src/util/connection.c:821 src/util/connection.c:992 +#: src/util/connection.c:739 src/util/connection.c:909 #, fuzzy, c-format msgid "Trying to connect to `%s' (%p)\n" msgstr "Kan inte ansluta till %u.%u.%u.%u:%u: %s\n" -#: src/util/connection.c:830 +#: src/util/connection.c:748 #, fuzzy, c-format msgid "Failed to connect to `%s' (%p)\n" msgstr "Kan inte ansluta till %u.%u.%u.%u:%u: %s\n" -#: src/util/connection.c:983 +#: src/util/connection.c:900 #, fuzzy, c-format msgid "Attempt to connect to `%s' failed\n" msgstr " Anslutning misslyckades\n" -#: src/util/connection.c:1465 -#, c-format -msgid "" -"Could not satisfy pending transmission request, socket closed or connect " -"failed (%p).\n" -msgstr "" - -#: src/util/container_bloomfilter.c:507 +#: src/util/container_bloomfilter.c:510 #, c-format msgid "" "Size of file on disk is incorrect for this Bloom filter (want %llu, have " @@ -5076,129 +5330,129 @@ msgstr "" msgid "libgcrypt has not the expected version (version %s is required).\n" msgstr "libgcrypt har inte den fĂśrväntande versionen (version %s krävs).\n" -#: src/util/crypto_rsa.c:618 src/util/crypto_rsa.c:665 +#: src/util/crypto_rsa.c:661 src/util/crypto_rsa.c:708 #, fuzzy, c-format msgid "Could not aquire lock on file `%s': %s...\n" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/util/crypto_rsa.c:623 +#: src/util/crypto_rsa.c:666 #, fuzzy msgid "Creating a new private key. This may take a while.\n" msgstr "Skapar ny värdnyckel (det här kan ta en stund).\n" -#: src/util/crypto_rsa.c:641 +#: src/util/crypto_rsa.c:684 #, c-format msgid "I am host `%s'. Stored new private key in `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:669 src/util/crypto_rsa.c:705 +#: src/util/crypto_rsa.c:712 src/util/crypto_rsa.c:748 msgid "This may be ok if someone is currently generating a hostkey.\n" msgstr "" -#: src/util/crypto_rsa.c:700 +#: src/util/crypto_rsa.c:743 #, c-format msgid "" "When trying to read hostkey file `%s' I found %u bytes but I need at least " "%u.\n" msgstr "" -#: src/util/crypto_rsa.c:720 +#: src/util/crypto_rsa.c:763 #, fuzzy, c-format msgid "File `%s' does not contain a valid private key. Deleting it.\n" msgstr "Filen \"%s\" innehĂĽller ingen pseudonym.\n" -#: src/util/crypto_rsa.c:738 +#: src/util/crypto_rsa.c:781 #, fuzzy, c-format msgid "I am host `%s'. Read private key from `%s'.\n" msgstr "Anrop till \"%s\" med nyckel \"%s\".\n" -#: src/util/crypto_rsa.c:959 +#: src/util/crypto_rsa.c:1032 #, c-format msgid "RSA signature verification failed at %s:%d: %s\n" msgstr "" # drive = hard drive ? -#: src/util/disk.c:479 +#: src/util/disk.c:498 #, fuzzy, c-format msgid "`%s' failed for drive `%S': %u\n" msgstr "\"%s\" misslyckades fĂśr enhet %s: %u\n" -#: src/util/disk.c:1087 +#: src/util/disk.c:1062 #, fuzzy, c-format msgid "Expected `%s' to be a directory!\n" msgstr "\"%s\" fĂśrväntade att \"%s\" skulle vara en katalog!\n" -#: src/util/disk.c:1441 src/util/service.c:1580 +#: src/util/disk.c:1416 src/util/service.c:1650 #, fuzzy, c-format msgid "Cannot obtain information about user `%s': %s\n" msgstr "Kan inte Ăśppna konfigurationsfil \"%s\".\n" -#: src/util/disk.c:1759 +#: src/util/disk.c:1734 #, fuzzy, c-format msgid "No `%s' specified for service `%s' in configuration.\n" msgstr "Inga applikationer definierade i konfiguration!\n" -#: src/util/getopt.c:672 +#: src/util/getopt.c:669 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "%s: flagga \"%s\" är tvetydig\n" -#: src/util/getopt.c:696 +#: src/util/getopt.c:693 #, c-format msgid "%s: option `--%s' does not allow an argument\n" msgstr "%s: flagga \"--%s\" tillĂĽter inte ett argument\n" -#: src/util/getopt.c:701 +#: src/util/getopt.c:698 #, c-format msgid "%s: option `%c%s' does not allow an argument\n" msgstr "%s: flagga \"%c%s\" tillĂĽter inte ett argument\n" -#: src/util/getopt.c:718 src/util/getopt.c:886 +#: src/util/getopt.c:715 src/util/getopt.c:883 #, c-format msgid "%s: option `%s' requires an argument\n" msgstr "%s: flagga \"%s\" kräver ett argument\n" -#: src/util/getopt.c:747 +#: src/util/getopt.c:744 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "%s: okänd flagga \"--%s\"\n" -#: src/util/getopt.c:751 +#: src/util/getopt.c:748 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "%s: okänd flagga \"%c%s\"\n" -#: src/util/getopt.c:776 +#: src/util/getopt.c:773 #, c-format msgid "%s: illegal option -- %c\n" msgstr "%s: otillĂĽten flagga -- %c\n" -#: src/util/getopt.c:778 +#: src/util/getopt.c:775 #, c-format msgid "%s: invalid option -- %c\n" msgstr "%s: ogiltig flagga -- %c\n" -#: src/util/getopt.c:806 src/util/getopt.c:934 +#: src/util/getopt.c:803 src/util/getopt.c:931 #, c-format msgid "%s: option requires an argument -- %c\n" msgstr "%s: flagga kräver ett argument -- %c\n" -#: src/util/getopt.c:854 +#: src/util/getopt.c:851 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "%s: flagga \"-W %s\" är tvetydig\n" -#: src/util/getopt.c:872 +#: src/util/getopt.c:869 #, c-format msgid "%s: option `-W %s' does not allow an argument\n" msgstr "%s: flagga \"-W %s\" tillĂĽter inte ett argument\n" -#: src/util/getopt.c:1038 +#: src/util/getopt.c:1035 #, fuzzy, c-format msgid "Use %s to get a list of options.\n" msgstr "Använd --help fĂśr att fĂĽ en lista pĂĽ flaggor.\n" -#: src/util/getopt_helpers.c:84 +#: src/util/getopt_helpers.c:86 #, c-format msgid "" "Arguments mandatory for long options are also mandatory for short options.\n" @@ -5206,7 +5460,7 @@ msgstr "" "Argument som är obligatoriska fĂśr lĂĽnga flaggor är ocksĂĽ obligatoriska fĂśr " "korta flaggor.\n" -#: src/util/getopt_helpers.c:255 src/util/getopt_helpers.c:283 +#: src/util/getopt_helpers.c:258 src/util/getopt_helpers.c:286 #, c-format msgid "You must pass a number to the `%s' option.\n" msgstr "Du mĂĽste skicka med ett nummer till flaggan \"%s\".\n" @@ -5219,6 +5473,27 @@ msgstr "" msgid "Use build-in GNUnet stub resolver" msgstr "" +#: src/util/gnunet-rsa.c:64 +#, c-format +msgid "No hostkey file specified on command line\n" +msgstr "" + +#: src/util/gnunet-rsa.c:112 +msgid "print the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:115 +msgid "print the hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:118 +msgid "print the short hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:124 +msgid "Manipulate GNUnet private RSA key files" +msgstr "" + #: src/util/gnunet-service-resolver.c:288 #, fuzzy, c-format msgid "Could not resolve `%s' (%s): %s\n" @@ -5230,42 +5505,37 @@ msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" msgid "Could not find IP of host `%s': %s\n" msgstr "" -#: src/util/gnunet-service-resolver.c:494 -#, c-format -msgid "Resolver asked to look up `%s'.\n" -msgstr "" - -#: src/util/gnunet-service-resolver.c:529 -#, c-format -msgid "Resolver asked to look up IP address `%s'.\n" -msgstr "" - -#: src/util/helper.c:239 +#: src/util/helper.c:244 #, fuzzy, c-format msgid "Error reading from `%s': %s\n" msgstr "Fel vid skapandet av användare" -#: src/util/helper.c:254 +#: src/util/helper.c:259 #, c-format msgid "Got 0 bytes from helper `%s' (EOF)\n" msgstr "" -#: src/util/helper.c:264 +#: src/util/helper.c:269 #, c-format msgid "Got %u bytes from helper `%s'\n" msgstr "" -#: src/util/helper.c:273 +#: src/util/helper.c:278 #, fuzzy, c-format msgid "Failed to parse inbound message from helper `%s'\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/util/helper.c:432 +#: src/util/helper.c:310 +#, fuzzy, c-format +msgid "Starting HELPER process `%s'\n" +msgstr "Startade samling \"%s\".\n" + +#: src/util/helper.c:440 #, fuzzy, c-format msgid "Error writing to `%s': %s\n" msgstr "Fel vid skapandet av användare" -#: src/util/network.c:1196 +#: src/util/network.c:1200 #, c-format msgid "" "Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n" @@ -5293,12 +5563,12 @@ msgstr "\"%s\" %s misslyckades: %s\n" msgid "stat (%s) failed: %s\n" msgstr "\"%s\" %s misslyckades: %s\n" -#: src/util/os_priority.c:304 +#: src/util/os_priority.c:305 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for reading: %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" -#: src/util/os_priority.c:305 +#: src/util/os_priority.c:306 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for writing: %s\n" msgstr "Misslyckades att leverera \"%s\" meddelande.\n" @@ -5323,12 +5593,12 @@ msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" msgid "Could not determine plugin installation path.\n" msgstr "Kunde inte fastställa min publika IPv6-adress.\n" -#: src/util/pseudonym.c:273 +#: src/util/pseudonym.c:276 #, fuzzy, c-format msgid "Failed to parse metadata about pseudonym from file `%s': %s\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/util/pseudonym.c:338 +#: src/util/pseudonym.c:407 src/util/pseudonym.c:433 #, fuzzy msgid "no-name" msgstr "Visa namn" @@ -5346,188 +5616,168 @@ msgstr "" "Du mĂĽste ange ett positivt nummer fĂśr \"%s\" i konfigurationen i sektion \"%s" "\".\n" -#: src/util/resolver_api.c:351 +#: src/util/resolver_api.c:347 #, c-format msgid "Timeout trying to resolve IP address `%s'.\n" msgstr "" -#: src/util/resolver_api.c:355 +#: src/util/resolver_api.c:351 #, fuzzy, c-format msgid "Timeout trying to resolve hostname `%s'.\n" msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#: src/util/resolver_api.c:426 -#, c-format -msgid "Resolver returns `%s' for IP `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:807 -#, c-format -msgid "Resolver returns `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:901 -#, c-format -msgid "Resolving our FQDN `%s'\n" -msgstr "" - -#: src/util/resolver_api.c:906 +#: src/util/resolver_api.c:890 #, fuzzy, c-format msgid "Could not resolve our FQDN : %s\n" msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" -#: src/util/resolver_api.c:938 -#, c-format -msgid "Resolving our hostname `%s'\n" -msgstr "" - -#: src/util/scheduler.c:866 +#: src/util/scheduler.c:786 msgid "Looks like we're busy waiting...\n" msgstr "" -#: src/util/scheduler.c:996 +#: src/util/scheduler.c:916 #, c-format msgid "Attempt to cancel dead task %llu!\n" msgstr "" # drive = hard drive ? -#: src/util/server.c:397 +#: src/util/server.c:483 #, fuzzy, c-format msgid "`%s' failed for port %d (%s).\n" msgstr "\"%s\" misslyckades fĂśr enhet %s: %u\n" -#: src/util/server.c:406 +#: src/util/server.c:492 #, fuzzy, c-format msgid "`%s' failed for port %d (%s): address already in use\n" msgstr "\"%s\" misslyckades fĂśr port %d: %s. KĂśrs verkligen gnunetd?\n" -#: src/util/server.c:411 +#: src/util/server.c:497 #, fuzzy, c-format msgid "`%s' failed for `%s': address already in use\n" msgstr "\"%s\" misslyckades fĂśr port %d: %s. KĂśrs verkligen gnunetd?\n" -#: src/util/server.c:640 +#: src/util/server.c:827 #, c-format msgid "" "Processing code for message of type %u did not call " "GNUNET_SERVER_receive_done after %llums\n" msgstr "" -#: src/util/service.c:117 src/util/service.c:143 src/util/service.c:186 -#: src/util/service.c:207 src/util/service.c:214 +#: src/util/service.c:135 src/util/service.c:161 src/util/service.c:204 +#: src/util/service.c:225 src/util/service.c:232 #, c-format msgid "Invalid format for IP: `%s'\n" msgstr "Ogiltigt format fĂśr IP: \"%s\"\n" -#: src/util/service.c:170 +#: src/util/service.c:188 #, c-format msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)." msgstr "Ogiltig nätverksnotation (\"/%d\" är inte giltig i IPv4 CIDR)." -#: src/util/service.c:263 +#: src/util/service.c:281 #, c-format msgid "Invalid network notation (does not end with ';': `%s')\n" msgstr "Ogiltig nätverksnotation (slutar inte med \";\": \"%s\")\n" -#: src/util/service.c:296 +#: src/util/service.c:313 #, fuzzy, c-format msgid "Wrong format `%s' for netmask\n" msgstr "Fel format \"%s\" fĂśr nätmask: %s\n" -#: src/util/service.c:326 +#: src/util/service.c:343 #, fuzzy, c-format msgid "Wrong format `%s' for network\n" msgstr "Fel format \"%s\" fĂśr nätverk: %s\n" -#: src/util/service.c:668 +#: src/util/service.c:698 #, c-format msgid "Access denied to UID %d / GID %d\n" msgstr "" -#: src/util/service.c:673 +#: src/util/service.c:703 #, fuzzy, c-format msgid "Unknown address family %d\n" msgstr "Okänd operation \"%s\"\n" -#: src/util/service.c:680 +#: src/util/service.c:710 #, c-format msgid "Access from `%s' denied to service `%s'\n" msgstr "" -#: src/util/service.c:724 +#: src/util/service.c:765 #, c-format msgid "Could not parse IPv4 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:752 +#: src/util/service.c:802 #, c-format msgid "Could not parse IPv6 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:869 +#: src/util/service.c:920 #, c-format msgid "" "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n" msgstr "" -#: src/util/service.c:939 +#: src/util/service.c:990 #, c-format msgid "" "Disabling UNIX domain socket support for service `%s', failed to create UNIX " "domain socket: %s\n" msgstr "" -#: src/util/service.c:956 +#: src/util/service.c:1007 #, c-format msgid "Have neither PORT nor UNIXPATH for service `%s', but one is required\n" msgstr "" -#: src/util/service.c:1191 +#: src/util/service.c:1241 msgid "Could not access a pre-bound socket, will try to bind myself\n" msgstr "" -#: src/util/service.c:1242 src/util/service.c:1260 +#: src/util/service.c:1292 src/util/service.c:1310 #, c-format msgid "Specified value for `%s' of service `%s' is invalid\n" msgstr "" -#: src/util/service.c:1287 +#: src/util/service.c:1337 #, c-format msgid "Could not access pre-bound socket %u, will try to bind myself\n" msgstr "" -#: src/util/service.c:1442 +#: src/util/service.c:1506 #, fuzzy, c-format msgid "Failed to start `%s' at `%s'\n" msgstr "Fel vid %s:%d.\n" -#: src/util/service.c:1475 +#: src/util/service.c:1539 #, fuzzy, c-format msgid "Service `%s' runs at %s\n" msgstr "Motpart \"%s\" med pĂĽlitlighet %8u och adress \"%s\"\n" -#: src/util/service.c:1521 +#: src/util/service.c:1588 msgid "Service process failed to initialize\n" msgstr "" -#: src/util/service.c:1525 +#: src/util/service.c:1592 msgid "Service process could not initialize server function\n" msgstr "" -#: src/util/service.c:1529 +#: src/util/service.c:1596 msgid "Service process failed to report status\n" msgstr "" -#: src/util/service.c:1581 +#: src/util/service.c:1651 msgid "No such user" msgstr "" -#: src/util/service.c:1594 +#: src/util/service.c:1664 #, c-format msgid "Cannot change user/group to `%s': %s\n" msgstr "Kan inte ändra användare/grupp till \"%s\": %s\n" -#: src/util/service.c:1657 +#: src/util/service.c:1729 msgid "do daemonize (detach from terminal)" msgstr "" @@ -5536,55 +5786,76 @@ msgstr "" msgid "signal (%d, %p) returned %d.\n" msgstr "Anrop till \"%s\" returnerade %d.\n" -#: src/util/strings.c:143 +#: src/util/strings.c:144 msgid "b" msgstr "b" -#: src/util/strings.c:354 +#: src/util/strings.c:334 #, c-format msgid "Character sets requested were `%s'->`%s'\n" msgstr "" -#: src/util/strings.c:462 +#: src/util/strings.c:481 msgid "Failed to expand `$HOME': environment variable `HOME' not set" msgstr "" -#: src/util/strings.c:554 +#: src/util/strings.c:573 msgid "ms" msgstr "ms" -#: src/util/strings.c:559 +#: src/util/strings.c:578 msgid "eternity" msgstr "" -#: src/util/strings.c:563 +#: src/util/strings.c:582 msgid "s" msgstr "s" -#: src/util/strings.c:567 +#: src/util/strings.c:586 msgid "m" msgstr "m" -#: src/util/strings.c:571 +#: src/util/strings.c:590 msgid "h" msgstr "h" -#: src/util/strings.c:575 +#: src/util/strings.c:594 msgid " days" msgstr " dagar" -#: src/util/strings.c:599 +#: src/util/strings.c:618 msgid "end of time" msgstr "" -#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1065 +#: src/util/strings.c:1012 +msgid "IPv6 address did not start with `['\n" +msgstr "" + +#: src/util/strings.c:1020 +msgid "IPv6 address did contain ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1026 +msgid "IPv6 address did contain ']' before ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1033 +msgid "IPv6 address did contain a valid port number after the last ':'\n" +msgstr "" + +#: src/util/strings.c:1042 +#, fuzzy, c-format +msgid "Invalid IPv6 address `%s': %s\n" +msgstr "Ogiltigt svar pĂĽ \"%s\".\n" + +#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1071 #, fuzzy msgid "# Active tunnels" msgstr "Nätverksanslutning" #: src/vpn/gnunet-service-vpn.c:608 src/vpn/gnunet-service-vpn.c:645 #, fuzzy -msgid "# Peers connected to mesh tunnels" +msgid "# peers connected to mesh tunnels" msgstr "# av anslutna parter" #: src/vpn/gnunet-service-vpn.c:699 @@ -5607,75 +5878,75 @@ msgstr "# PING-meddelanden skapade" msgid "Failed to setup mesh tunnel!\n" msgstr "Kunde inte skapa värdnyckel!\n" -#: src/vpn/gnunet-service-vpn.c:967 +#: src/vpn/gnunet-service-vpn.c:973 #, c-format msgid "Protocol %u not supported, dropping\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1285 +#: src/vpn/gnunet-service-vpn.c:1291 msgid "# ICMPv4 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1306 +#: src/vpn/gnunet-service-vpn.c:1312 msgid "# ICMPv6 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1511 +#: src/vpn/gnunet-service-vpn.c:1517 #, fuzzy msgid "# Packets received from TUN interface" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/vpn/gnunet-service-vpn.c:1549 src/vpn/gnunet-service-vpn.c:1590 +#: src/vpn/gnunet-service-vpn.c:1555 src/vpn/gnunet-service-vpn.c:1596 #, c-format msgid "Packet received for unmapped destination `%s' (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1600 +#: src/vpn/gnunet-service-vpn.c:1606 msgid "Received IPv4 packet with options (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1614 +#: src/vpn/gnunet-service-vpn.c:1620 #, c-format msgid "Received packet of unknown protocol %d from TUN (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1697 +#: src/vpn/gnunet-service-vpn.c:1704 #, fuzzy msgid "# ICMP packets received from mesh" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/vpn/gnunet-service-vpn.c:2038 +#: src/vpn/gnunet-service-vpn.c:2045 #, fuzzy msgid "# UDP packets received from mesh" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/vpn/gnunet-service-vpn.c:2196 +#: src/vpn/gnunet-service-vpn.c:2203 #, fuzzy msgid "# TCP packets received from mesh" msgstr "Meddelande mottaget frĂĽn klient är ogiltig.\n" -#: src/vpn/gnunet-service-vpn.c:2347 +#: src/vpn/gnunet-service-vpn.c:2354 msgid "Failed to find unallocated IPv4 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2402 +#: src/vpn/gnunet-service-vpn.c:2409 msgid "Failed to find unallocated IPv6 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2441 src/vpn/gnunet-service-vpn.c:2624 +#: src/vpn/gnunet-service-vpn.c:2448 src/vpn/gnunet-service-vpn.c:2661 #, fuzzy msgid "# Active destinations" msgstr "Nätverksanslutning" -#: src/vpn/gnunet-service-vpn.c:2726 +#: src/vpn/gnunet-service-vpn.c:2734 msgid "Failed to allocate IP address for new destination\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3133 +#: src/vpn/gnunet-service-vpn.c:3141 msgid "IPv6 support disabled as this system does not support IPv6\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3165 +#: src/vpn/gnunet-service-vpn.c:3173 msgid "IPv4 support disabled as this system does not support IPv4\n" msgstr "" @@ -5751,22 +6022,159 @@ msgstr "# byte mottagna via UDP" msgid "Setup tunnels via VPN." msgstr "" -#: src/include/gnunet_common.h:479 src/include/gnunet_common.h:484 -#: src/include/gnunet_common.h:490 +#: src/include/gnunet_common.h:497 src/include/gnunet_common.h:502 +#: src/include/gnunet_common.h:508 #, fuzzy, c-format msgid "Assertion failed at %s:%d.\n" msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n" -#: src/include/gnunet_common.h:500 +#: src/include/gnunet_common.h:518 #, c-format msgid "External protocol violation detected at %s:%d.\n" msgstr "" -#: src/include/gnunet_common.h:521 src/include/gnunet_common.h:528 +#: src/include/gnunet_common.h:539 src/include/gnunet_common.h:546 #, c-format msgid "`%s' failed on file `%s' at %s:%d with error: %s\n" msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" +#, fuzzy +#~ msgid "Received malformed message via %s. Ignored.\n" +#~ msgstr "Mottog ogiltigt \"%s\" meddelande frĂĽn \"%s\".\n" + +# capped är inte ett bra ord IMHO +#, fuzzy +#~ msgid "SMTP filter string to invalid, lacks ': '\n" +#~ msgstr "SMTP-filtersträng fĂśr lĂĽng, kapad till \"%s\"\n" + +# capped är inte ett bra ord IMHO +#~ msgid "SMTP filter string to long, capped to `%s'\n" +#~ msgstr "SMTP-filtersträng fĂśr lĂĽng, kapad till \"%s\"\n" + +#, fuzzy +#~ msgid "SMTP: `%s' failed: %s.\n" +#~ msgstr "\"%s\" %s misslyckades: %s\n" + +#, fuzzy +#~ msgid "# bytes received via SMTP" +#~ msgstr "# byte mottogs via TCP" + +#, fuzzy +#~ msgid "# bytes sent via SMTP" +#~ msgstr "# byte skickades via TCP" + +#, fuzzy +#~ msgid "# bytes dropped by SMTP (outgoing)" +#~ msgstr "# byte kastade via TCP (utgĂĽende)" + +#, fuzzy +#~ msgid "# Peers connected" +#~ msgstr "# av anslutna parter" + +#, fuzzy +#~ msgid "%s failed for `%s' at %s:%d: `%s'\n" +#~ msgstr "\"%s\" misslyckades vid %s:%d med fel: \"%s\".\n" + +#, fuzzy +#~ msgid "Failed to transmit shutdown ACK.\n" +#~ msgstr "Misslyckades att starta samling.\n" + +#, fuzzy +#~ msgid "Unable to initialize Postgres with configuration `%s': %s" +#~ msgstr "Kunde inte spara konfigurationsfil \"%s\":" + +#, fuzzy +#~ msgid "Failed to transmit message to `%s' service.\n" +#~ msgstr "Misslyckades att initiera tjänsten \"%s\".\n" + +#, fuzzy +#~ msgid "Target is %d connections per peer." +#~ msgstr "Misslyckades att starta samling.\n" + +#, fuzzy +#~ msgid "Copying file with RENAME (%s,%s)\n" +#~ msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" + +#, fuzzy +#~ msgid "Copying file with command scp %s %s\n" +#~ msgstr "\"%s\" misslyckades vid %s:%d med fel: %s\n" + +#, fuzzy +#~ msgid "Finished copying all blacklist files!\n" +#~ msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" + +#, fuzzy +#~ msgid "Failed during blacklist file copying!\n" +#~ msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" + +#, fuzzy +#~ msgid "# bytes payload received for other peers" +#~ msgstr "# byte mottagna av typen %d" + +#, fuzzy +#~ msgid "# fast reconnects failed" +#~ msgstr "# av anslutna parter" + +#, fuzzy +#~ msgid "# peers disconnected due to timeout" +#~ msgstr "# av anslutna parter" + +#, fuzzy +#~ msgid "# peers disconnected due to global disconnect" +#~ msgstr "Nätverksannonsering avstängd i konfigurationen!\n" + +#, fuzzy +#~ msgid "# unexpected CONNECT_ACK messages" +#~ msgstr "skicka ANTAL meddelanden" + +#, fuzzy +#~ msgid "# wlan session timeouts" +#~ msgstr "# sessionsnycklar accepterade" + +#, fuzzy +#~ msgid "# wlan session created" +#~ msgstr "# sessionsnycklar accepterade" + +#, fuzzy +#~ msgid "# wlan pending fragments" +#~ msgstr "# byte mottogs via TCP" + +#, fuzzy +#~ msgid "# wlan whole messages received" +#~ msgstr "# krypterade PONG-meddelanden mottagna" + +#, fuzzy +#~ msgid "# wlan hello messages received" +#~ msgstr "# krypterade PONG-meddelanden mottagna" + +#, fuzzy +#~ msgid "# wlan fragments received" +#~ msgstr "# byte mottogs via TCP" + +#, fuzzy +#~ msgid "# wlan acks received" +#~ msgstr "# klartext PONG-meddelanden mottagna" + +#, fuzzy +#~ msgid "# wlan messages for this client received" +#~ msgstr "# krypterade PONG-meddelanden mottagna" + +#, fuzzy +#~ msgid "# wlan messages inside WLAN_HELPER_DATA received" +#~ msgstr "# krypterade PONG-meddelanden mottagna" + +#, fuzzy +#~ msgid "Unknown user `%s'\n" +#~ msgstr "Okänd operation \"%s\"\n" + +#, fuzzy +#~ msgid "Namespace `%s' unknown.\n" +#~ msgstr "Namnrymd \"%s\" skapad(rot: %s).\n" + +#, fuzzy +#~ msgid "Failed to connect to statistics service!\n" +#~ msgstr "Misslyckades att ansluta till gnunetd.\n" + #, fuzzy #~ msgid "Failed to send to `%s': %s\n" #~ msgstr "Misslyckades att leverera \"%s\" meddelande.\n" @@ -5824,10 +6232,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Unable to accept connection for service `%s': %s\n" #~ msgstr "Kunde inte spara konfigurationsfil \"%s\":" -#, fuzzy -#~ msgid "Service `%s' started\n" -#~ msgstr "Tjänst borttagen.\n" - #, fuzzy #~ msgid "Peer `%s' plugin: `%s' address `%s'\n" #~ msgstr "Motpart \"%s\" med pĂĽlitlighet %8u och adress \"%s\"\n" @@ -5848,14 +6252,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Failed to load dhtlog plugin for `%s'\n" #~ msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" -#, fuzzy -#~ msgid "Failed to get full path for `%s'\n" -#~ msgstr "Misslyckades att läsa kompislista frĂĽn \"%s\"\n" - -#, fuzzy -#~ msgid "Failed to create file for dhtlog.\n" -#~ msgstr "Kunde inte skapa användarkonto:" - #, fuzzy #~ msgid "Found peer `%s'\n" #~ msgstr "Jag är ändpunkt \"%s\".\n" @@ -5864,10 +6260,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Loading udp transport plugin\n" #~ msgstr "Testar transport(er) %s\n" -#, fuzzy -#~ msgid "Failed to load transport plugin for udp\n" -#~ msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" - #, fuzzy #~ msgid "# SET QUOTA messages received" #~ msgstr "# krypterade PONG-meddelanden mottagna" @@ -5908,10 +6300,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Misconfigured address to bind to in configuration!\n" #~ msgstr "Inga applikationer definierade i konfiguration!\n" -#, fuzzy -#~ msgid "Loading HTTP transport plugin `%s'\n" -#~ msgstr "Testar transport(er) %s\n" - #, fuzzy #~ msgid "Failed to load transport plugin for http\n" #~ msgstr "Kunde inte slĂĽ upp \"%s\": %s\n" @@ -5972,9 +6360,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Ok" #~ msgstr "k" -#~ msgid "GNUnet configuration" -#~ msgstr "GNUnet-konfiguration" - #~ msgid "" #~ "Welcome to GNUnet!\n" #~ "\n" @@ -6316,9 +6701,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Command `%s' requires two arguments (`%s' and `%s').\n" #~ msgstr "Kommando \"%s\" kräver tvĂĽ argument (\"%s\" och \"%s\").\n" -#~ msgid "Unsupported command `%s'. Aborting.\n" -#~ msgstr "Kommando \"%s\" stĂśds ej. Avbryter.\n" - #, fuzzy #~ msgid "# dht discovery messages sent" #~ msgstr "# krypterade PONG-meddelanden skickade" @@ -6529,10 +6911,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Downloading %d files from directory `%s'.\n" #~ msgstr "Ladda ner filer frĂĽn GNUnet." -#, fuzzy -#~ msgid "Did not find any files in directory `%s'\n" -#~ msgstr "%d filer hittades i katalog.\n" - #~ msgid "File stored as `%s'.\n" #~ msgstr "Fil lagrad som \"%s\".\n" @@ -6585,10 +6963,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Friend list of %s:%d\n" #~ msgstr "Fel vid %s:%d.\n" -#, fuzzy -#~ msgid "set number of daemons to start" -#~ msgstr "antal meddelanden att använda per iteration" - #, fuzzy #~ msgid "Waiting for peers to connect" #~ msgstr "Väntar pĂĽ att motparter ska ansluta (%u iterationer kvar)...\n" @@ -6974,9 +7348,6 @@ msgstr "\"%s\" misslyckades fĂśr fil \"%s\" vid %s:%d med fel: %s\n" #~ msgid "Peer `%s' did not report back.\n" #~ msgstr "Motpart \"%s\" rapporterade inte tillbaka.\n" -#~ msgid "%s: symbol value `%s' invalid for %s\n" -#~ msgstr "%s: symbolvärde \"%s\" ogiltigt fĂśr %s\n" - #~ msgid "Sorry, no help is available for this option.\n" #~ msgstr "Tyvärr, ingen hjälp är tillgänglig fĂśr den här flaggan.\n" diff --git a/po/vi.gmo b/po/vi.gmo index e205a02..fe4edd8 100644 Binary files a/po/vi.gmo and b/po/vi.gmo differ diff --git a/po/vi.po b/po/vi.po index bfa7f9d..6ee9cf4 100644 --- a/po/vi.po +++ b/po/vi.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet 0.8.0a\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2012-02-28 18:30+0100\n" +"POT-Creation-Date: 2012-06-05 15:47+0200\n" "PO-Revision-Date: 2008-09-10 22:05+0930\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" @@ -19,261 +19,276 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: LocFactoryEditor 1.7b3\n" -#: src/arm/arm_api.c:187 +#: src/arm/arm_api.c:165 msgid "Failed to transmit shutdown request to client.\n" msgstr "" -#: src/arm/arm_api.c:378 +#: src/arm/arm_api.c:349 #, fuzzy, c-format msgid "Configuration failes to specify option `%s' in section `%s'!\n" msgstr "" "CẼu hĂŹnh khĂ´ng thỏa mĂŁn cĂĄc rĂ ng buộc cᝧa táş­p tin đặc tả cẼu hĂŹnh ÂŤ %s Âť.\n" -#: src/arm/arm_api.c:392 +#: src/arm/arm_api.c:363 #, fuzzy, c-format msgid "Configuration fails to specify option `%s' in section `%s'!\n" msgstr "" "CẼu hĂŹnh khĂ´ng thỏa mĂŁn cĂĄc rĂ ng buộc cᝧa táş­p tin đặc tả cẼu hĂŹnh ÂŤ %s Âť.\n" -#: src/arm/arm_api.c:467 +#: src/arm/arm_api.c:432 #, c-format msgid "Error receiving response to `%s' request from ARM for service `%s'\n" msgstr "" -#: src/arm/arm_api.c:523 +#: src/arm/arm_api.c:485 #, c-format msgid "Requesting start of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:524 +#: src/arm/arm_api.c:486 #, c-format msgid "Requesting termination of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:546 +#: src/arm/arm_api.c:507 #, c-format msgid "Error while trying to transmit request to start `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:548 +#: src/arm/arm_api.c:508 #, c-format msgid "Error while trying to transmit request to stop `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:581 +#: src/arm/arm_api.c:540 #, fuzzy, c-format msgid "Asked to start service `%s' within %llu ms\n" msgstr "ÂŤ %s Âť: ChĆ°a nháş­n thĂ´ng bĂĄo sau %llu miligiây.\n" -#: src/arm/arm_api.c:654 +#: src/arm/arm_api.c:612 #, c-format msgid "Stopping service `%s' within %llu ms\n" msgstr "" -#: src/arm/gnunet-arm.c:149 +#: src/arm/gnunet-arm.c:159 #, fuzzy, c-format msgid "Service `%s' is unknown to ARM.\n" msgstr "KhĂ´ng gian tĂŞn ÂŤ %s Âť cĂł đánh giĂĄ %d.\n" -#: src/arm/gnunet-arm.c:154 +#: src/arm/gnunet-arm.c:164 #, fuzzy, c-format msgid "Service `%s' has been stopped.\n" msgstr "Dịch v᝼ đã bị xoĂĄ.\n" -#: src/arm/gnunet-arm.c:157 +#: src/arm/gnunet-arm.c:167 #, fuzzy, c-format msgid "Service `%s' was already running.\n" msgstr "KhĂ´ng gian tĂŞn ÂŤ %s Âť cĂł đánh giĂĄ %d.\n" -#: src/arm/gnunet-arm.c:162 +#: src/arm/gnunet-arm.c:172 #, fuzzy, c-format msgid "Service `%s' has been started.\n" msgstr "Dịch v᝼ đã bị xoĂĄ.\n" -#: src/arm/gnunet-arm.c:165 +#: src/arm/gnunet-arm.c:175 #, fuzzy, c-format msgid "Service `%s' was already being stopped.\n" msgstr "Dịch v᝼ đã bị xoĂĄ.\n" -#: src/arm/gnunet-arm.c:169 +#: src/arm/gnunet-arm.c:179 #, fuzzy, c-format msgid "Service `%s' was already not running.\n" msgstr "ÂŤ %s Âť khĂ´ng phải lĂ  một táş­p tin.\n" -#: src/arm/gnunet-arm.c:173 +#: src/arm/gnunet-arm.c:183 #, fuzzy msgid "Request ignored as ARM is shutting down.\n" msgstr "ÂŤ %s Âť đang tắt.\n" -#: src/arm/gnunet-arm.c:177 +#: src/arm/gnunet-arm.c:187 #, fuzzy msgid "Error communicating with ARM service.\n" msgstr "Cổng để liĂŞn lấc với giao diện người dĂšng GNUnet" -#: src/arm/gnunet-arm.c:181 +#: src/arm/gnunet-arm.c:191 #, fuzzy msgid "Timeout communicating with ARM service.\n" msgstr "Cổng để liĂŞn lấc với giao diện người dĂšng GNUnet" -#: src/arm/gnunet-arm.c:185 +#: src/arm/gnunet-arm.c:195 #, fuzzy msgid "Operation failed.\n" msgstr "Lỗi nội bộ : kháşłng định khĂ´ng thĂ nh cĂ´ng tấi %s:%d.\n" -#: src/arm/gnunet-arm.c:189 +#: src/arm/gnunet-arm.c:199 msgid "Unknown response code from ARM.\n" msgstr "" -#: src/arm/gnunet-arm.c:216 +#: src/arm/gnunet-arm.c:222 +#, fuzzy +msgid "Error communicating with ARM. ARM not running?\n" +msgstr "Cổng để liĂŞn lấc với giao diện người dĂšng GNUnet" + +#: src/arm/gnunet-arm.c:225 +#, fuzzy +msgid "Running services:\n" +msgstr "Đang nấp vĂ  khởi động dĂšng ÂŤ %s Âť.\n" + +#: src/arm/gnunet-arm.c:249 #, c-format msgid "Fatal configuration error: `%s' option in section `%s' missing.\n" msgstr "" -#: src/arm/gnunet-arm.c:224 src/arm/gnunet-arm.c:324 +#: src/arm/gnunet-arm.c:257 src/arm/gnunet-arm.c:357 src/arm/gnunet-arm.c:373 msgid "Fatal error initializing ARM API.\n" msgstr "" -#: src/arm/gnunet-arm.c:247 +#: src/arm/gnunet-arm.c:280 #, fuzzy, c-format msgid "Failed to remove configuration file %s\n" msgstr "KhĂ´ng thᝃ lĆ°u táş­p tin cẼu hĂŹnh ÂŤ %s Âť:" -#: src/arm/gnunet-arm.c:253 +#: src/arm/gnunet-arm.c:286 #, fuzzy, c-format msgid "Failed to remove servicehome directory %s\n" msgstr "Lỗi truy cáş­p đến thĆ° m᝼c nhĂ  GNUnet ÂŤ %s Âť\n" -#: src/arm/gnunet-arm.c:355 +#: src/arm/gnunet-arm.c:407 #, fuzzy msgid "stop all GNUnet services" msgstr "hᝧy cĂ i đặt dịch v᝼ GNUnet" -#: src/arm/gnunet-arm.c:357 +#: src/arm/gnunet-arm.c:409 msgid "start a particular service" msgstr "" -#: src/arm/gnunet-arm.c:359 +#: src/arm/gnunet-arm.c:411 msgid "stop a particular service" msgstr "" -#: src/arm/gnunet-arm.c:361 +#: src/arm/gnunet-arm.c:413 #, fuzzy msgid "start all GNUnet default services" msgstr "hᝧy cĂ i đặt dịch v᝼ GNUnet" -#: src/arm/gnunet-arm.c:364 +#: src/arm/gnunet-arm.c:416 #, fuzzy msgid "stop and start all GNUnet default services" msgstr "hᝧy cĂ i đặt dịch v᝼ GNUnet" -#: src/arm/gnunet-arm.c:367 +#: src/arm/gnunet-arm.c:419 msgid "delete config file and directory on exit" msgstr "" -#: src/arm/gnunet-arm.c:369 +#: src/arm/gnunet-arm.c:421 msgid "don't print status messages" msgstr "" -#: src/arm/gnunet-arm.c:372 +#: src/arm/gnunet-arm.c:424 #, fuzzy msgid "timeout for completing current operation" msgstr "thời gian chờ sáťą hoĂ n thĂ nh cᝧa một lần lạp (theo miligiây)" -#: src/arm/gnunet-arm.c:383 +#: src/arm/gnunet-arm.c:426 +msgid "List currently running services" +msgstr "" + +#: src/arm/gnunet-arm.c:437 msgid "Control services and the Automated Restart Manager (ARM)" msgstr "" -#: src/arm/gnunet-service-arm.c:328 +#: src/arm/gnunet-service-arm.c:332 #, fuzzy, c-format msgid "Failed to start service `%s'\n" msgstr "Lỗi bắt đầu thu tháş­p.\n" -#: src/arm/gnunet-service-arm.c:331 +#: src/arm/gnunet-service-arm.c:335 #, fuzzy, c-format msgid "Starting service `%s'\n" msgstr "Đang bắt đầu tĂ i vᝁ ÂŤ %s Âť\n" -#: src/arm/gnunet-service-arm.c:357 +#: src/arm/gnunet-service-arm.c:361 msgid "Could not send status result to client\n" msgstr "" -#: src/arm/gnunet-service-arm.c:484 +#: src/arm/gnunet-service-arm.c:393 +#, fuzzy +msgid "Could not send list result to client\n" +msgstr "KhĂ´ng thᝃ đọc danh sĂĄch bấn bè ÂŤ %s Âť\n" + +#: src/arm/gnunet-service-arm.c:523 #, fuzzy, c-format msgid "Unable to create socket for service `%s': %s\n" msgstr "KhĂ´ng thᝃ tấo tĂ i khoản người dĂšng:" -#: src/arm/gnunet-service-arm.c:506 +#: src/arm/gnunet-service-arm.c:545 #, c-format msgid "Unable to bind listening socket for service `%s' to address `%s': %s\n" msgstr "" -#: src/arm/gnunet-service-arm.c:520 +#: src/arm/gnunet-service-arm.c:559 #, c-format msgid "ARM now monitors connections to service `%s' at `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:628 +#: src/arm/gnunet-service-arm.c:667 #, fuzzy, c-format msgid "Preparing to stop `%s'\n" msgstr "Đang bắt đầu tĂ i lĂŞn ÂŤ %s Âť.\n" -#: src/arm/gnunet-service-arm.c:782 +#: src/arm/gnunet-service-arm.c:878 #, fuzzy, c-format msgid "Restarting service `%s'.\n" msgstr "Đang nấp vĂ  khởi động dĂšng ÂŤ %s Âť.\n" -#: src/arm/gnunet-service-arm.c:877 +#: src/arm/gnunet-service-arm.c:970 msgid "exit" msgstr "" -#: src/arm/gnunet-service-arm.c:882 +#: src/arm/gnunet-service-arm.c:975 msgid "signal" msgstr "" -#: src/arm/gnunet-service-arm.c:887 +#: src/arm/gnunet-service-arm.c:980 #, fuzzy msgid "unknown" msgstr "Lỗi khĂ´ng rĂľ" -#: src/arm/gnunet-service-arm.c:921 +#: src/arm/gnunet-service-arm.c:986 +#, fuzzy, c-format +msgid "Service `%s' took %llu ms to terminate\n" +msgstr "Dịch v᝼ đã bị xoĂĄ.\n" + +#: src/arm/gnunet-service-arm.c:1021 #, c-format msgid "Service `%s' terminated with status %s/%d, will restart in %llu ms\n" msgstr "" -#: src/arm/gnunet-service-arm.c:967 src/arm/mockup-service.c:41 -#, fuzzy -msgid "Failed to transmit shutdown ACK.\n" -msgstr "Lỗi bắt đầu thu tháş­p.\n" - -#: src/arm/gnunet-service-arm.c:1067 +#: src/arm/gnunet-service-arm.c:1127 #, fuzzy, c-format msgid "Configuration file `%s' for service `%s' not valid: %s\n" msgstr "Táş­p tin cẼu hĂŹnh ÂŤ %s Âť đã được ghi.\n" -#: src/arm/gnunet-service-arm.c:1069 +#: src/arm/gnunet-service-arm.c:1129 msgid "option missing" msgstr "" -#: src/arm/gnunet-service-arm.c:1152 +#: src/arm/gnunet-service-arm.c:1213 #, fuzzy, c-format msgid "Starting default services `%s'\n" msgstr "Đang bắt đầu tĂ i vᝁ ÂŤ %s Âť\n" -#: src/arm/gnunet-service-arm.c:1163 +#: src/arm/gnunet-service-arm.c:1224 #, c-format msgid "Default service `%s' not configured correctly!\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1177 +#: src/arm/gnunet-service-arm.c:1238 msgid "" "No default services configured, GNUnet will not really start right now.\n" msgstr "" -#: src/arm/mockup-service.c:46 -msgid "Transmitting shutdown ACK.\n" -msgstr "" - -#: src/arm/mockup-service.c:69 +#: src/arm/mockup-service.c:44 msgid "Initiating shutdown as requested by client.\n" msgstr "" @@ -333,120 +348,123 @@ msgstr "" msgid "Undefined mandatory parameter: memberCallback\n" msgstr "" -#: src/chat/gnunet-chat.c:92 +#: src/chat/gnunet-chat.c:93 msgid "Joined\n" msgstr "" -#: src/chat/gnunet-chat.c:124 +#: src/chat/gnunet-chat.c:125 src/chat/gnunet-chat.c:133 +#: src/chat/gnunet-chat.c:213 src/chat/gnunet-chat.c:253 +#: src/chat/gnunet-chat.c:329 src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:400 src/chat/gnunet-chat.c:700 msgid "anonymous" msgstr "nạc danh" -#: src/chat/gnunet-chat.c:130 +#: src/chat/gnunet-chat.c:144 #, fuzzy, c-format msgid "(%s) `%s' said: %s\n" msgstr "ÂŤ %s Âť nĂłi: %s\n" -#: src/chat/gnunet-chat.c:133 src/chat/gnunet-chat.c:136 +#: src/chat/gnunet-chat.c:147 src/chat/gnunet-chat.c:150 #, fuzzy, c-format msgid "(%s) `%s' said to you: %s\n" msgstr "ÂŤ %s Âť nĂłi cho bấn: %s\n" -#: src/chat/gnunet-chat.c:139 +#: src/chat/gnunet-chat.c:153 #, fuzzy, c-format msgid "(%s) `%s' said for sure: %s\n" msgstr "ÂŤ %s Âť nĂłi tháş­t: %s\n" -#: src/chat/gnunet-chat.c:142 +#: src/chat/gnunet-chat.c:156 #, fuzzy, c-format msgid "(%s) `%s' said to you for sure: %s\n" msgstr "ÂŤ %s Âť nĂłi tháş­t cho bấn: %s\n" -#: src/chat/gnunet-chat.c:145 +#: src/chat/gnunet-chat.c:159 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you received: %s\n" msgstr "ÂŤ %s Âť xĂĄc nháş­n bấn đã nháş­n được: %s\n" -#: src/chat/gnunet-chat.c:148 +#: src/chat/gnunet-chat.c:162 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you and only you received: %s\n" msgstr "ÂŤ %s Âť xĂĄc nháş­n mĂ  chỉ bấn đã nháş­n được: %s\n" -#: src/chat/gnunet-chat.c:151 +#: src/chat/gnunet-chat.c:165 #, fuzzy, c-format msgid "(%s) `%s' was confirmed that you received from him or her: %s\n" msgstr "ÂŤ %s Âť xĂĄc nháş­n mĂ  bấn đã nháş­n được tᝍ họ : %s\n" -#: src/chat/gnunet-chat.c:156 +#: src/chat/gnunet-chat.c:170 #, fuzzy, c-format msgid "" "(%s) `%s' was confirmed that you and only you received from him or her: %s\n" msgstr "ÂŤ %s Âť xĂĄc nháş­n mĂ  chỉ bấn đa nháş­n được tᝍ họ : %s\n" -#: src/chat/gnunet-chat.c:159 +#: src/chat/gnunet-chat.c:173 #, fuzzy, c-format msgid "(%s) `%s' said off the record: %s\n" msgstr "ÂŤ %s Âť nĂłi khĂ´ng chĂ­nh thᝊc: %s\n" -#: src/chat/gnunet-chat.c:162 +#: src/chat/gnunet-chat.c:176 #, fuzzy, c-format msgid "(%s) <%s> said using an unknown message type: %s\n" msgstr "<%s> đã nĂłi báşąng một kiᝃu tin nháşłn khĂ´ng rĂľ : %s\n" -#: src/chat/gnunet-chat.c:193 +#: src/chat/gnunet-chat.c:217 #, c-format msgid "'%s' acknowledged message #%d\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' entered the room\n" msgstr "ÂŤ %s Âť vĂ o phòng\n" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' left the room\n" msgstr "ÂŤ %s Âť rời phòng\n" -#: src/chat/gnunet-chat.c:284 src/chat/gnunet-chat.c:316 +#: src/chat/gnunet-chat.c:321 src/chat/gnunet-chat.c:363 #, fuzzy msgid "Could not change username\n" msgstr "KhĂ´ng thᝃ tấo miᝁn tĂŞn.\n" -#: src/chat/gnunet-chat.c:288 src/chat/gnunet-chat.c:630 +#: src/chat/gnunet-chat.c:334 src/chat/gnunet-chat.c:702 #, fuzzy, c-format msgid "Joining room `%s' as user `%s'...\n" msgstr "Đã vĂ o phòng ÂŤ %s Âť lĂ  người dĂšng ÂŤ %s Âť.\n" -#: src/chat/gnunet-chat.c:320 +#: src/chat/gnunet-chat.c:373 #, fuzzy, c-format msgid "Changed username to `%s'\n" msgstr "Đã thay đổi tĂŞn người dĂšng thĂ nh ÂŤ %s Âť.\n" -#: src/chat/gnunet-chat.c:333 +#: src/chat/gnunet-chat.c:388 #, c-format msgid "Users in room `%s': " msgstr "Người dĂšng trong phòng ÂŤ %s Âť:" -#: src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:434 msgid "Syntax: /msg USERNAME MESSAGE" msgstr "CĂş phĂĄp: /msg TÊN_NGƯỜI_DÙNG TIN_NHẲN" -#: src/chat/gnunet-chat.c:379 +#: src/chat/gnunet-chat.c:443 #, c-format -msgid "Unknown user `%s'\n" -msgstr "KhĂ´ng rĂľ người dĂšng ÂŤ %s Âť\n" +msgid "Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n" +msgstr "" -#: src/chat/gnunet-chat.c:395 +#: src/chat/gnunet-chat.c:460 #, c-format msgid "User `%s' is currently not in the room!\n" msgstr "Người dĂšng ÂŤ %s Âť hiện thời khĂ´ng cĂł trong phòng nĂ y.\n" -#: src/chat/gnunet-chat.c:448 +#: src/chat/gnunet-chat.c:513 #, fuzzy, c-format msgid "Unknown command `%s'\n" msgstr "KhĂ´ng rĂľ câu lệnh ÂŤ %s Âť.\n" -#: src/chat/gnunet-chat.c:459 +#: src/chat/gnunet-chat.c:524 msgid "" "Use `/join #roomname' to join a chat room. Joining a room will cause you to " "leave the current room" @@ -454,7 +472,7 @@ msgstr "" "GĂľ chuỗi ÂŤ /join #tĂŞn_phòng Âť để vĂ o một phòng trò chuyện nĂ o đó (việc nĂ y " "cĹŠng gây ra bấn ra khỏi phòng hiện tấi)" -#: src/chat/gnunet-chat.c:463 +#: src/chat/gnunet-chat.c:528 msgid "" "Use `/nick nickname' to change your nickname. This will cause you to leave " "the current room and immediately rejoin it with the new name." @@ -462,77 +480,77 @@ msgstr "" "GĂľ chuỗi ÂŤ /nick tĂŞn_hiệu Âť để thay đổi tĂŞn hiệu cᝧa mĂŹnh (việc nĂ y cĹŠng gây " "ra bấn ra khỏi phòng hiện tấi, sau đó vĂ o lấi ngay với tĂŞn mới)" -#: src/chat/gnunet-chat.c:467 +#: src/chat/gnunet-chat.c:532 msgid "" "Use `/msg nickname message' to send a private message to the specified user" msgstr "" "GĂľ chuỗi ÂŤ /msg tĂŞn_hiệu tin_nháşłn Âť để gáť­i một tin nháşłn riĂŞng cho người dĂšng " "cĂł tĂŞn đó" -#: src/chat/gnunet-chat.c:470 +#: src/chat/gnunet-chat.c:535 msgid "The `/notice' command is an alias for `/msg'" msgstr "Lệnh ÂŤ /notice Âť lĂ  một biệt hiệu cho ÂŤ /msg Âť" -#: src/chat/gnunet-chat.c:472 +#: src/chat/gnunet-chat.c:537 msgid "The `/query' command is an alias for `/msg'" msgstr "Lệnh ÂŤ /query Âť lĂ  một biệt hiệu cho ÂŤ /msg Âť" -#: src/chat/gnunet-chat.c:474 +#: src/chat/gnunet-chat.c:539 #, fuzzy msgid "Use `/sig message' to send a signed public message" msgstr "" "GĂľ chuỗi ÂŤ /msg tĂŞn_hiệu tin_nháşłn Âť để gáť­i một tin nháşłn riĂŞng cho người dĂšng " "cĂł tĂŞn đó" -#: src/chat/gnunet-chat.c:477 +#: src/chat/gnunet-chat.c:542 msgid "Use `/ack message' to require signed acknowledgment of the message" msgstr "" -#: src/chat/gnunet-chat.c:480 +#: src/chat/gnunet-chat.c:545 msgid "Use `/anonymous message' to send a public anonymous message" msgstr "" -#: src/chat/gnunet-chat.c:482 +#: src/chat/gnunet-chat.c:547 #, fuzzy msgid "The `/anon' command is an alias for `/anonymous'" msgstr "Lệnh ÂŤ /notice Âť lĂ  một biệt hiệu cho ÂŤ /msg Âť" -#: src/chat/gnunet-chat.c:484 +#: src/chat/gnunet-chat.c:549 msgid "Use `/quit' to terminate gnunet-chat" msgstr "GĂľ chuỗi ÂŤ /quit Âť để thoĂĄt khỏi trĂŹnh gnunet-chat" -#: src/chat/gnunet-chat.c:486 +#: src/chat/gnunet-chat.c:551 msgid "The `/leave' command is an alias for `/quit'" msgstr "Lệnh ÂŤ /leave Âť lĂ  một biệt hiệu cho ÂŤ /quit Âť" -#: src/chat/gnunet-chat.c:489 +#: src/chat/gnunet-chat.c:554 msgid "Use `/names' to list all of the current members in the chat room" msgstr "" "GĂľ chuỗi ÂŤ /names Âť để liệt kĂŞ tẼt cả cĂĄc thĂ nh viĂŞn hiện thời trong phòng " "trò chuyện đó" -#: src/chat/gnunet-chat.c:491 +#: src/chat/gnunet-chat.c:556 msgid "Use `/help command' to get help for a specific command" msgstr "GĂľ chuỗi ÂŤ /help LỆNH Âť để xem trᝣ giĂşp vᝁ lệnh đó" -#: src/chat/gnunet-chat.c:606 +#: src/chat/gnunet-chat.c:672 msgid "You must specify a nickname\n" msgstr "Phải ghi rĂľ tĂŞn hiệu\n" -#: src/chat/gnunet-chat.c:622 +#: src/chat/gnunet-chat.c:688 #, c-format msgid "Failed to join room `%s'\n" msgstr "Lỗi vĂ o phòng ÂŤ %s Âť\n" -#: src/chat/gnunet-chat.c:655 +#: src/chat/gnunet-chat.c:727 msgid "set the nickname to use (required)" msgstr "đặt tĂŞn hiệu cần dĂšng (cần thiáşżt)" -#: src/chat/gnunet-chat.c:658 +#: src/chat/gnunet-chat.c:730 msgid "set the chat room to join" msgstr "đặt phòng trò chuyện cần vĂ o" -#: src/chat/gnunet-chat.c:670 +#: src/chat/gnunet-chat.c:742 msgid "Join a chat on GNUnet." msgstr "VĂ o phòng trò chuyện trĂŞn GNUnet." @@ -556,184 +574,186 @@ msgstr "Lỗi lĆ°u cẼu hĂŹnh." msgid "Failed to queue a leave notification\n" msgstr "Lỗi lĆ°u cẼu hĂŹnh." -#: src/core/core_api.c:798 +#: src/core/core_api.c:786 msgid "Client was disconnected from core service, trying to reconnect.\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:77 -#: src/peerinfo-tool/gnunet-peerinfo.c:60 +#: src/core/gnunet-core.c:54 src/peerinfo-tool/gnunet-peerinfo.c:286 #, fuzzy, c-format msgid "Peer `%s'\n" msgstr "TĂ´i lĂ  đồng đẳng ÂŤ %s Âť.\n" -#: src/core/gnunet-core-list-connections.c:175 -#: src/peerinfo-tool/gnunet-peerinfo.c:194 +#: src/core/gnunet-core.c:72 src/peerinfo-tool/gnunet-peerinfo.c:817 #, fuzzy, c-format msgid "Invalid command line argument `%s'\n" msgstr "Đối số khĂ´ng hᝣp lệ cho ÂŤ %s Âť.\n" -#: src/core/gnunet-core-list-connections.c:196 -#: src/peerinfo-tool/gnunet-peerinfo.c:252 -msgid "don't resolve host names" -msgstr "khĂ´ng quyáşżt định cĂĄc tĂŞn mĂĄy" - -#: src/core/gnunet-core-list-connections.c:203 +#: src/core/gnunet-core.c:95 #, fuzzy msgid "Print information about connected peers." msgstr "In ra thĂ´ng tin vᝁ cĂĄc đồng đẳng GNUnet." -#: src/core/gnunet-service-core.c:99 +#: src/core/gnunet-service-core.c:97 #, c-format msgid "Core service of `%4s' ready.\n" msgstr "" -#: src/core/gnunet-service-core_clients.c:360 +#: src/core/gnunet-service-core_clients.c:370 #, fuzzy msgid "# send requests dropped (disconnected)" msgstr "# cĂĄc yĂŞu cầu lỗ hổng bị bỏ do trọng tải" -#: src/core/gnunet-service-core_clients.c:465 +#: src/core/gnunet-service-core_clients.c:475 #, fuzzy msgid "# messages discarded (session disconnected)" msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/core/gnunet-service-core_clients.c:801 +#: src/core/gnunet-service-core_clients.c:818 #, fuzzy, c-format msgid "# bytes of messages of type %u received" msgstr "# cĂĄc byte nhiễu được nháş­n" -#: src/core/gnunet-service-core_kx.c:493 +#: src/core/gnunet-service-core_kx.c:565 msgid "# bytes encrypted" msgstr "# cĂĄc byte đã mĂŁ hoĂĄ" -#: src/core/gnunet-service-core_kx.c:543 +#: src/core/gnunet-service-core_kx.c:617 msgid "# bytes decrypted" msgstr "# cĂĄc byte đã giải mĂŁ" -#: src/core/gnunet-service-core_kx.c:604 src/dv/gnunet-service-dv.c:3002 -#: src/hostlist/hostlist-server.c:436 src/peerinfo-tool/gnunet-peerinfo.c:151 +#: src/core/gnunet-service-core_kx.c:681 src/dv/gnunet-service-dv.c:3003 #, fuzzy msgid "Error in communication with PEERINFO service\n" msgstr "Cổng để liĂŞn lấc với giao diện người dĂšng GNUnet" -#: src/core/gnunet-service-core_kx.c:623 +#: src/core/gnunet-service-core_kx.c:700 msgid "# Delayed connecting due to lack of public key" msgstr "" -#: src/core/gnunet-service-core_kx.c:673 +#: src/core/gnunet-service-core_kx.c:753 msgid "# key exchanges initiated" msgstr "" -#: src/core/gnunet-service-core_kx.c:694 +#: src/core/gnunet-service-core_kx.c:775 msgid "# key exchanges stopped" msgstr "" -#: src/core/gnunet-service-core_kx.c:746 +#: src/core/gnunet-service-core_kx.c:828 #, fuzzy msgid "# session keys received" msgstr "# cĂĄc khoĂĄ phiĂŞn chấy bị tᝍ chối" -#: src/core/gnunet-service-core_kx.c:765 +#: src/core/gnunet-service-core_kx.c:845 #, c-format msgid "`%s' is for `%s', not for me. Ignoring.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:803 +#: src/core/gnunet-service-core_kx.c:890 #, fuzzy msgid "# SET_KEY messages decrypted" msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/core/gnunet-service-core_kx.c:883 -#: src/transport/gnunet-service-transport_validation.c:803 +#: src/core/gnunet-service-core_kx.c:977 +#: src/transport/gnunet-service-transport_validation.c:810 #, fuzzy msgid "# PING messages received" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/core/gnunet-service-core_kx.c:917 +#: src/core/gnunet-service-core_kx.c:1010 #, c-format msgid "" "Received PING from `%s' for different identity: I am `%s', PONG identity: `" "%s'\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:938 +#: src/core/gnunet-service-core_kx.c:1029 #, fuzzy msgid "# PONG messages created" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/core/gnunet-service-core_kx.c:1026 +#: src/core/gnunet-service-core_kx.c:1125 #, fuzzy msgid "# sessions terminated by timeout" msgstr "# cĂĄc byte loấi đi bởi TCP (đi ra)" -#: src/core/gnunet-service-core_kx.c:1037 +#: src/core/gnunet-service-core_kx.c:1135 #, fuzzy msgid "# keepalive messages sent" msgstr "# cĂĄc thĂ´ng bĂĄo PING nháş­p thĂ´ được gáť­i" -#: src/core/gnunet-service-core_kx.c:1095 -#: src/transport/gnunet-service-transport_validation.c:1026 +#: src/core/gnunet-service-core_kx.c:1236 +#: src/transport/gnunet-service-transport_validation.c:1031 #, fuzzy msgid "# PONG messages received" msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/core/gnunet-service-core_kx.c:1125 +#: src/core/gnunet-service-core_kx.c:1275 #, fuzzy msgid "# PONG messages decrypted" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/core/gnunet-service-core_kx.c:1157 +#: src/core/gnunet-service-core_kx.c:1303 #, fuzzy msgid "# session keys confirmed via PONG" msgstr "# CĂĄc quảng cĂĄo đồng đẳng được xĂĄc nháş­n qua PONG" -#: src/core/gnunet-service-core_kx.c:1223 +#: src/core/gnunet-service-core_kx.c:1329 +#, fuzzy +msgid "# rekey operations confirmed via PONG" +msgstr "# CĂĄc quảng cĂĄo đồng đẳng được xĂĄc nháş­n qua PONG" + +#: src/core/gnunet-service-core_kx.c:1381 +#: src/core/gnunet-service-core_kx.c:1398 #, fuzzy msgid "# SET_KEY and PING messages created" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/core/gnunet-service-core_kx.c:1364 +#: src/core/gnunet-service-core_kx.c:1402 +msgid "# REKEY operations performed" +msgstr "" + +#: src/core/gnunet-service-core_kx.c:1537 msgid "# failed to decrypt message (no session key)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1406 -#: src/core/gnunet-service-core_kx.c:1431 +#: src/core/gnunet-service-core_kx.c:1577 +#: src/core/gnunet-service-core_kx.c:1602 #, fuzzy msgid "# bytes dropped (duplicates)" msgstr "# cĂĄc byte loấi bỏ bởi UDP (đi ra)" -#: src/core/gnunet-service-core_kx.c:1418 +#: src/core/gnunet-service-core_kx.c:1589 #, fuzzy msgid "# bytes dropped (out of sequence)" msgstr "# cĂĄc byte loấi bỏ bởi UDP (đi ra)" -#: src/core/gnunet-service-core_kx.c:1455 +#: src/core/gnunet-service-core_kx.c:1626 #, fuzzy, c-format msgid "Message received far too old (%llu ms). Content ignored.\n" msgstr "ThĂ´ng bĂĄo nháş­n được cĹŠ hĆĄn một ngĂ y. Đã loấi bỏ.\n" -#: src/core/gnunet-service-core_kx.c:1459 +#: src/core/gnunet-service-core_kx.c:1630 #, fuzzy msgid "# bytes dropped (ancient message)" msgstr "# cĂĄc byte loấi bỏ bởi UDP (đi ra)" -#: src/core/gnunet-service-core_kx.c:1467 +#: src/core/gnunet-service-core_kx.c:1638 #, fuzzy msgid "# bytes of payload decrypted" msgstr "# cĂĄc byte đã giải mĂŁ" -#: src/core/gnunet-service-core_kx.c:1528 +#: src/core/gnunet-service-core_kx.c:1700 #, fuzzy msgid "Core service is lacking HOSTKEY configuration setting. Exiting.\n" msgstr "LĆ°u cẼu hĂŹnh ngay bây giờ khĂ´ng?" -#: src/core/gnunet-service-core_kx.c:1536 +#: src/core/gnunet-service-core_kx.c:1708 msgid "Core service could not access hostkey. Exiting.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1546 src/hostlist/hostlist-server.c:555 -#: src/peerinfo-tool/gnunet-peerinfo.c:202 -#: src/transport/gnunet-service-transport.c:595 +#: src/core/gnunet-service-core_kx.c:1718 src/hostlist/hostlist-server.c:551 +#: src/peerinfo-tool/gnunet-peerinfo.c:823 +#: src/transport/gnunet-service-transport.c:611 #, fuzzy msgid "Could not access PEERINFO service. Exiting.\n" msgstr "KhĂ´ng thᝃ truy cáş­p đến thĂ´ng tin vᝁ khĂ´ng gian tĂŞn.\n" @@ -744,30 +764,41 @@ msgid "# sessions terminated by transport disconnect" msgstr "# CĂĄc quảng cĂĄo đồng đẳng bị hᝧy do trọng tải" #: src/core/gnunet-service-core_neighbours.c:180 -#: src/core/gnunet-service-core_neighbours.c:342 +#: src/core/gnunet-service-core_neighbours.c:334 msgid "# neighbour entries allocated" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:251 +#: src/core/gnunet-service-core_neighbours.c:247 msgid "# encrypted bytes given to transport" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:430 +#: src/core/gnunet-service-core_neighbours.c:418 #, c-format msgid "Unsupported message of type %u (%u bytes) received from peer `%s'\n" msgstr "" -#: src/core/gnunet-service-core_sessions.c:208 -#: src/core/gnunet-service-core_sessions.c:273 -msgid "# entries in session map" -msgstr "" +#: src/core/gnunet-service-core_sessions.c:206 +#: src/core/gnunet-service-core_sessions.c:269 +#: src/dht/gnunet-service-dht_neighbours.c:625 +#: src/dht/gnunet-service-dht_neighbours.c:683 +#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 +#: src/topology/gnunet-daemon-topology.c:709 +#: src/topology/gnunet-daemon-topology.c:810 +#: src/transport/gnunet-service-transport_neighbours.c:874 +#: src/transport/gnunet-service-transport_neighbours.c:1080 +#: src/transport/gnunet-service-transport_neighbours.c:1089 +#: src/transport/gnunet-service-transport_neighbours.c:2568 +#: src/transport/gnunet-service-transport_neighbours.c:2814 +#, fuzzy +msgid "# peers connected" +msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" -#: src/core/gnunet-service-core_sessions.c:238 +#: src/core/gnunet-service-core_sessions.c:236 #, fuzzy msgid "# type map refreshes sent" msgstr "# tổng số yĂŞu cầu lỗ hổng được gáť­i" -#: src/core/gnunet-service-core_sessions.c:414 +#: src/core/gnunet-service-core_sessions.c:406 msgid "# messages discarded (expired prior to transmission)" msgstr "" @@ -781,428 +812,407 @@ msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" msgid "# updates to my type map" msgstr "" -#: src/datacache/datacache.c:118 src/datacache/datacache.c:255 -#: src/datastore/gnunet-service-datastore.c:854 +#: src/datacache/datacache.c:115 src/datacache/datacache.c:250 +#: src/datastore/gnunet-service-datastore.c:834 #, fuzzy msgid "# bytes stored" msgstr "# cĂĄc byte trong kho dᝯ liệu" -#: src/datacache/datacache.c:144 src/datacache/datacache.c:151 -#: src/datastore/gnunet-service-datastore.c:1531 -#: src/datastore/gnunet-service-datastore.c:1542 +#: src/datacache/datacache.c:141 src/datacache/datacache.c:148 +#: src/datastore/gnunet-service-datastore.c:1483 +#: src/datastore/gnunet-service-datastore.c:1494 #, c-format msgid "No `%s' specified for `%s' in configuration!\n" msgstr "" -#: src/datacache/datacache.c:183 +#: src/datacache/datacache.c:180 #, c-format msgid "Loading `%s' datacache plugin\n" msgstr "" -#: src/datacache/datacache.c:191 +#: src/datacache/datacache.c:188 #, fuzzy, c-format msgid "Failed to load datacache plugin for `%s'\n" msgstr "Lỗi cáş­p nháş­t dᝯ liệu cho mĂ´-đun ÂŤ %s Âť\n" -#: src/datacache/datacache.c:281 +#: src/datacache/datacache.c:276 #, fuzzy msgid "# requests received" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/datacache/datacache.c:291 +#: src/datacache/datacache.c:284 msgid "# requests filtered by bloom filter" msgstr "# cĂĄc yĂŞu cầu được lọc theo bộ lọc bloom" -#: src/datacache/plugin_datacache_mysql.c:103 -#: src/datacache/plugin_datacache_mysql.c:110 -#: src/datacache/plugin_datacache_mysql.c:517 -#: src/datacache/plugin_datacache_mysql.c:526 -#: src/datacache/plugin_datacache_mysql.c:598 -#: src/datacache/plugin_datacache_mysql.c:614 -#: src/datacache/plugin_datacache_sqlite.c:71 -#: src/datacache/plugin_datacache_sqlite.c:74 -#: src/datastore/plugin_datastore_mysql.c:139 -#: src/datastore/plugin_datastore_mysql.c:146 -#: src/datastore/plugin_datastore_mysql.c:613 -#: src/datastore/plugin_datastore_mysql.c:673 -#: src/datastore/plugin_datastore_mysql.c:685 -#: src/datastore/plugin_datastore_mysql.c:1362 -#: src/datastore/plugin_datastore_mysql.c:1376 -#: src/datastore/plugin_datastore_sqlite.c:61 -#: src/namestore/plugin_namestore_sqlite.c:49 src/util/crypto_ksk.c:49 -#: src/util/crypto_rsa.c:92 src/include/gnunet_common.h:507 -#: src/include/gnunet_common.h:514 +#: src/datacache/plugin_datacache_mysql.c:97 +#: src/datacache/plugin_datacache_mysql.c:104 +#: src/datacache/plugin_datacache_sqlite.c:69 +#: src/datacache/plugin_datacache_sqlite.c:72 +#: src/datastore/plugin_datastore_mysql.c:803 +#: src/datastore/plugin_datastore_mysql.c:817 +#: src/datastore/plugin_datastore_sqlite.c:57 src/mysql/mysql.c:41 +#: src/mysql/mysql.c:48 src/mysql/mysql.c:522 src/mysql/mysql.c:531 +#: src/mysql/mysql.c:591 src/mysql/mysql.c:607 +#: src/namestore/plugin_namestore_sqlite.c:51 src/util/crypto_ksk.c:49 +#: src/util/crypto_rsa.c:67 src/include/gnunet_common.h:525 +#: src/include/gnunet_common.h:532 #, c-format msgid "`%s' failed at %s:%d with error: %s\n" msgstr "ÂŤ %s Âť bị lỗi tấi %s:%d với lỗi: %s\n" -#: src/datacache/plugin_datacache_mysql.c:224 -#: src/datastore/plugin_datastore_mysql.c:316 -#, c-format -msgid "Trying to use file `%s' for MySQL configuration.\n" -msgstr "Đang tháť­ dĂšng táş­p tin ÂŤ %s Âť cho cẼu hĂŹnh MySQL.\n" - -#: src/datacache/plugin_datacache_mysql.c:230 -#: src/datastore/plugin_datastore_mysql.c:322 -#, fuzzy, c-format -msgid "Could not access file `%s': %s\n" -msgstr "KhĂ´ng thᝃ truy cáş­p đến ÂŤ %s Âť: %s\n" - -#: src/datacache/plugin_datacache_mysql.c:979 +#: src/datacache/plugin_datacache_mysql.c:450 msgid "MySQL datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_postgres.c:79 -#: src/datastore/plugin_datastore_postgres.c:93 -#, fuzzy, c-format -msgid "`%s:%s' failed at %s:%d with error: %s" -msgstr "ÂŤ %s Âť bị lỗi tấi %s:%d với lỗi: %s" - -#: src/datacache/plugin_datacache_postgres.c:149 -#, fuzzy, c-format -msgid "Unable to initialize Postgres: %s" -msgstr "KhĂ´ng thᝃ sĆĄ khởi SQLite: %s.\n" - -#: src/datacache/plugin_datacache_postgres.c:499 +#: src/datacache/plugin_datacache_postgres.c:367 msgid "Postgres datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:424 +#: src/datacache/plugin_datacache_sqlite.c:410 msgid "Sqlite datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:457 -#: src/datastore/plugin_datastore_sqlite.c:414 -#: src/namestore/plugin_namestore_sqlite.c:381 +#: src/datacache/plugin_datacache_sqlite.c:443 +#: src/datastore/plugin_datastore_sqlite.c:408 +#: src/namestore/plugin_namestore_sqlite.c:370 msgid "Tried to close sqlite without finalizing all prepared statements.\n" msgstr "" +#: src/datacache/plugin_datacache_sqlite.c:450 +#, fuzzy, c-format +msgid "Failed to close statement %p: %d\n" +msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" + #: src/datacache/plugin_datacache_template.c:121 msgid "Template datacache running\n" msgstr "" -#: src/datastore/datastore_api.c:289 +#: src/datastore/datastore_api.c:305 msgid "Failed to transmit request to drop database.\n" msgstr "" -#: src/datastore/datastore_api.c:372 +#: src/datastore/datastore_api.c:388 msgid "# queue entry timeouts" msgstr "" -#: src/datastore/datastore_api.c:418 +#: src/datastore/datastore_api.c:432 msgid "# queue overflows" msgstr "" -#: src/datastore/datastore_api.c:445 +#: src/datastore/datastore_api.c:459 #, fuzzy msgid "# queue entries created" msgstr "# cĂĄc truy vẼn lỗ hổng được định tuyáşżn" -#: src/datastore/datastore_api.c:465 +#: src/datastore/datastore_api.c:477 #, fuzzy msgid "# Requests dropped from datastore queue" msgstr "# cĂĄc yĂŞu cầu lỗ hổng bị bỏ do trọng tải" -#: src/datastore/datastore_api.c:513 +#: src/datastore/datastore_api.c:525 #, fuzzy msgid "# datastore connections (re)created" msgstr "# cĂĄc káşżt nối dht" -#: src/datastore/datastore_api.c:540 +#: src/datastore/datastore_api.c:548 msgid "# reconnected to DATASTORE" msgstr "" -#: src/datastore/datastore_api.c:608 +#: src/datastore/datastore_api.c:612 #, fuzzy msgid "# transmission request failures" msgstr "# cĂĄc sáťą truyᝁn PONG bị lỗi" -#: src/datastore/datastore_api.c:631 +#: src/datastore/datastore_api.c:633 #, fuzzy msgid "# bytes sent to datastore" msgstr "# cĂĄc byte trong kho dᝯ liệu" -#: src/datastore/datastore_api.c:772 +#: src/datastore/datastore_api.c:764 #, fuzzy msgid "Failed to receive status response from database." msgstr "" "\n" "KhĂ´ng nháş­n được đáp ᝊng tᝍ gnunetd.\n" -#: src/datastore/datastore_api.c:786 +#: src/datastore/datastore_api.c:778 msgid "Error reading response from datastore service" msgstr "" -#: src/datastore/datastore_api.c:798 src/datastore/datastore_api.c:804 +#: src/datastore/datastore_api.c:790 src/datastore/datastore_api.c:796 #, fuzzy msgid "Invalid error message received from datastore service" msgstr "Nháş­n được thĂ´ng bĂĄo ÂŤ %s Âť sai tᝍ đồng đẳng ÂŤ %s Âť.\n" -#: src/datastore/datastore_api.c:810 +#: src/datastore/datastore_api.c:800 #, fuzzy msgid "# status messages received" msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" -#: src/datastore/datastore_api.c:883 +#: src/datastore/datastore_api.c:869 #, fuzzy msgid "# PUT requests executed" msgstr "# cĂĄc yĂŞu cầu dht được định tuyáşżn" -#: src/datastore/datastore_api.c:954 +#: src/datastore/datastore_api.c:936 #, fuzzy msgid "# RESERVE requests executed" msgstr "# cĂĄc yĂŞu cầu dht được định tuyáşżn" -#: src/datastore/datastore_api.c:1019 +#: src/datastore/datastore_api.c:997 msgid "# RELEASE RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1080 +#: src/datastore/datastore_api.c:1054 #, fuzzy msgid "# UPDATE requests executed" msgstr "# cĂĄc yĂŞu cầu dht được định tuyáşżn" -#: src/datastore/datastore_api.c:1148 +#: src/datastore/datastore_api.c:1118 #, fuzzy msgid "# REMOVE requests executed" msgstr "# cĂĄc yĂŞu cầu dht được định tuyáşżn" -#: src/datastore/datastore_api.c:1193 +#: src/datastore/datastore_api.c:1163 #, fuzzy msgid "Failed to receive response from database.\n" msgstr "" "\n" "KhĂ´ng nháş­n được đáp ᝊng tᝍ gnunetd.\n" -#: src/datastore/datastore_api.c:1253 +#: src/datastore/datastore_api.c:1221 #, fuzzy msgid "# Results received" msgstr "# cĂĄc káşżt quả dht được nháş­n" -#: src/datastore/datastore_api.c:1324 +#: src/datastore/datastore_api.c:1286 msgid "# GET REPLICATION requests executed" msgstr "" -#: src/datastore/datastore_api.c:1391 +#: src/datastore/datastore_api.c:1349 msgid "# GET ZERO ANONYMITY requests executed" msgstr "" -#: src/datastore/datastore_api.c:1455 +#: src/datastore/datastore_api.c:1409 #, fuzzy msgid "# GET requests executed" msgstr "# cĂĄc yĂŞu cầu dht được định tuyáşżn" -#: src/datastore/gnunet-service-datastore.c:351 +#: src/datastore/gnunet-service-datastore.c:349 #, fuzzy msgid "# bytes expired" msgstr "# cĂĄc byte được nháş­n" -#: src/datastore/gnunet-service-datastore.c:426 +#: src/datastore/gnunet-service-datastore.c:422 msgid "# bytes purged (low-priority)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:486 +#: src/datastore/gnunet-service-datastore.c:480 msgid "Transmission to client failed!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:640 +#: src/datastore/gnunet-service-datastore.c:511 +msgid "Shutdown in progress, aborting transmission.\n" +msgstr "" + +#: src/datastore/gnunet-service-datastore.c:626 msgid "# results found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:685 +#: src/datastore/gnunet-service-datastore.c:669 #, c-format msgid "" "Insufficient space (%llu bytes are available) to satisfy `%s' request for " "%llu bytes\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:696 +#: src/datastore/gnunet-service-datastore.c:680 #, c-format msgid "" "The requested amount (%llu bytes) is larger than the cache size (%llu " "bytes)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:700 +#: src/datastore/gnunet-service-datastore.c:684 msgid "" "Insufficient space to satisfy request and requested amount is larger than " "cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:706 +#: src/datastore/gnunet-service-datastore.c:690 msgid "Insufficient space to satisfy request" msgstr "" -#: src/datastore/gnunet-service-datastore.c:711 -#: src/datastore/gnunet-service-datastore.c:765 -#: src/datastore/gnunet-service-datastore.c:986 -#: src/datastore/gnunet-service-datastore.c:1465 +#: src/datastore/gnunet-service-datastore.c:695 +#: src/datastore/gnunet-service-datastore.c:747 +#: src/datastore/gnunet-service-datastore.c:960 +#: src/datastore/gnunet-service-datastore.c:1417 msgid "# reserved" msgstr "" -#: src/datastore/gnunet-service-datastore.c:780 +#: src/datastore/gnunet-service-datastore.c:760 msgid "Could not find matching reservation" msgstr "" -#: src/datastore/gnunet-service-datastore.c:868 +#: src/datastore/gnunet-service-datastore.c:846 #, c-format msgid "Need %llu bytes more space (%llu allowed, using %llu)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1034 +#: src/datastore/gnunet-service-datastore.c:1006 #, fuzzy msgid "# GET requests received" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/datastore/gnunet-service-datastore.c:1048 +#: src/datastore/gnunet-service-datastore.c:1018 #, fuzzy msgid "# requests filtered by bloomfilter" msgstr "# cĂĄc yĂŞu cầu được lọc theo bộ lọc bloom" -#: src/datastore/gnunet-service-datastore.c:1076 +#: src/datastore/gnunet-service-datastore.c:1046 #, fuzzy msgid "# UPDATE requests received" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/datastore/gnunet-service-datastore.c:1110 +#: src/datastore/gnunet-service-datastore.c:1076 #, fuzzy msgid "# GET REPLICATION requests received" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/datastore/gnunet-service-datastore.c:1145 +#: src/datastore/gnunet-service-datastore.c:1109 #, fuzzy msgid "# GET ZERO ANONYMITY requests received" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/datastore/gnunet-service-datastore.c:1172 +#: src/datastore/gnunet-service-datastore.c:1134 msgid "Content not found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1182 +#: src/datastore/gnunet-service-datastore.c:1142 msgid "# bytes removed (explicit request)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1216 +#: src/datastore/gnunet-service-datastore.c:1174 #, fuzzy msgid "# REMOVE requests received" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/datastore/gnunet-service-datastore.c:1260 +#: src/datastore/gnunet-service-datastore.c:1216 #, c-format msgid "Datastore payload inaccurate (%lld < %lld). Trying to fix.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1323 +#: src/datastore/gnunet-service-datastore.c:1277 #, c-format msgid "Loading `%s' datastore plugin\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1332 +#: src/datastore/gnunet-service-datastore.c:1286 #, fuzzy, c-format msgid "Failed to load datastore plugin for `%s'\n" msgstr "KhĂ´ng thᝃ nấp phần bổ sung truyᝁn tải ÂŤ %s Âť\n" -#: src/datastore/gnunet-service-datastore.c:1536 +#: src/datastore/gnunet-service-datastore.c:1488 #, fuzzy, c-format msgid "# bytes used in file-sharing datastore `%s'" msgstr "# cĂĄc byte được phĂŠp trong kho dᝯ liệu" -#: src/datastore/gnunet-service-datastore.c:1547 +#: src/datastore/gnunet-service-datastore.c:1499 msgid "# quota" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1549 +#: src/datastore/gnunet-service-datastore.c:1501 msgid "# cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1562 +#: src/datastore/gnunet-service-datastore.c:1514 #, c-format msgid "Could not use specified filename `%s' for bloomfilter.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1580 -#: src/datastore/gnunet-service-datastore.c:1596 +#: src/datastore/gnunet-service-datastore.c:1532 +#: src/datastore/gnunet-service-datastore.c:1548 #, fuzzy, c-format msgid "Failed to remove bogus bloomfilter file `%s'\n" msgstr "KhĂ´ng thᝃ lĆ°u táş­p tin cẼu hĂŹnh ÂŤ %s Âť:" -#: src/datastore/gnunet-service-datastore.c:1626 +#: src/datastore/gnunet-service-datastore.c:1578 #, fuzzy msgid "Failed to initialize bloomfilter.\n" msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" -#: src/datastore/gnunet-service-datastore.c:1655 +#: src/datastore/gnunet-service-datastore.c:1607 msgid "Rebuilding bloomfilter. Please be patient.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1660 +#: src/datastore/gnunet-service-datastore.c:1612 msgid "Plugin does not support get_keys function. Please fix!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1663 +#: src/datastore/gnunet-service-datastore.c:1615 msgid "Bloomfilter construction complete.\n" msgstr "" -#: src/datastore/plugin_datastore_mysql.c:529 -#: src/datastore/plugin_datastore_mysql.c:1336 +#: src/datastore/plugin_datastore_mysql.c:780 #, fuzzy, c-format msgid "Failed to prepare statement `%s'\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/datastore/plugin_datastore_mysql.c:622 -#: src/datastore/plugin_datastore_mysql.c:1346 +#: src/datastore/plugin_datastore_mysql.c:788 #, fuzzy, c-format msgid "`%s' for `%s' failed at %s:%d with error: %s\n" msgstr "ÂŤ %s Âť bị lỗi tấi %s:%d với lỗi: %s\n" -#: src/datastore/plugin_datastore_mysql.c:1581 +#: src/datastore/plugin_datastore_mysql.c:1019 msgid "Mysql database running\n" msgstr "" -#: src/datastore/plugin_datastore_postgres.c:173 -#, fuzzy, c-format -msgid "Unable to initialize Postgres with configuration `%s': %s" -msgstr "KhĂ´ng thᝃ lĆ°u táş­p tin cẼu hĂŹnh ÂŤ %s Âť:" +#: src/datastore/plugin_datastore_postgres.c:824 +#, fuzzy +msgid "Failed to drop table from database.\n" +msgstr "" +"\n" +"KhĂ´ng nháş­n được đáp ᝊng tᝍ gnunetd.\n" -#: src/datastore/plugin_datastore_postgres.c:1017 +#: src/datastore/plugin_datastore_postgres.c:860 msgid "Postgres database running\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:61 +#: src/datastore/plugin_datastore_sqlite.c:57 #, fuzzy, c-format msgid "`%s' failed at %s:%u with error: %s" msgstr "ÂŤ %s Âť bị lỗi tấi %s:%d với lỗi: %s" -#: src/datastore/plugin_datastore_sqlite.c:239 -#: src/namestore/plugin_namestore_sqlite.c:223 +#: src/datastore/plugin_datastore_sqlite.c:233 +#: src/namestore/plugin_namestore_sqlite.c:204 #, c-format msgid "Option `%s' in section `%s' missing in configuration!\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:266 -#: src/namestore/plugin_namestore_sqlite.c:248 +#: src/datastore/plugin_datastore_sqlite.c:260 +#: src/namestore/plugin_namestore_sqlite.c:229 #, c-format msgid "Unable to initialize SQLite: %s.\n" msgstr "KhĂ´ng thᝃ sĆĄ khởi SQLite: %s.\n" -#: src/datastore/plugin_datastore_sqlite.c:669 +#: src/datastore/plugin_datastore_sqlite.c:655 #, fuzzy msgid "Invalid data in database. Trying to fix (by deletion).\n" msgstr "Dᝯ liệu sai trong %s. Đang tháť­ sáť­a chᝯa (báşąng cĂĄch xoĂĄ).\n" -#: src/datastore/plugin_datastore_sqlite.c:1159 +#: src/datastore/plugin_datastore_sqlite.c:1139 msgid "sqlite version to old to determine size, assuming zero\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1178 +#: src/datastore/plugin_datastore_sqlite.c:1158 #, c-format msgid "" "Using sqlite page utilization to estimate payload (%llu pages of size %llu " "bytes)\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1218 -#: src/namestore/plugin_namestore_sqlite.c:779 +#: src/datastore/plugin_datastore_sqlite.c:1198 +#: src/namestore/plugin_namestore_sqlite.c:829 #, fuzzy msgid "Sqlite database running\n" msgstr "kho dᝯ liệu sqlite" @@ -1211,33 +1221,32 @@ msgstr "kho dᝯ liệu sqlite" msgid "Template database running\n" msgstr "" -#: src/dht/dht_api.c:280 +#: src/dht/dht_api.c:348 #, fuzzy msgid "Failed to connect to the DHT service!\n" msgstr "Lỗi káşżt nối đến gnunetd.\n" -#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-put.c:172 -#: src/gns/gnunet-gns-lookup.c:179 +#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-monitor.c:293 +#: src/dht/gnunet-dht-put.c:192 msgid "the query key" msgstr "" -#: src/dht/gnunet-dht-get.c:204 src/gns/gnunet-gns-lookup.c:182 +#: src/dht/gnunet-dht-get.c:204 msgid "how many parallel requests (replicas) to create" msgstr "" -#: src/dht/gnunet-dht-get.c:207 src/gns/gnunet-gns-lookup.c:185 +#: src/dht/gnunet-dht-get.c:207 src/dht/gnunet-dht-monitor.c:296 msgid "the type of data to look for" msgstr "" -#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:181 -#: src/gns/gnunet-gns-lookup.c:188 +#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:201 msgid "how long to execute this query before giving up?" msgstr "" -#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-put.c:184 -#: src/fs/gnunet-download.c:270 src/fs/gnunet-publish.c:725 -#: src/fs/gnunet-search.c:297 src/fs/gnunet-unindex.c:169 -#: src/gns/gnunet-gns-lookup.c:191 src/nse/gnunet-nse-profiler.c:908 +#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-monitor.c:302 +#: src/dht/gnunet-dht-put.c:204 src/fs/gnunet-download.c:271 +#: src/fs/gnunet-publish.c:731 src/fs/gnunet-search.c:297 +#: src/fs/gnunet-unindex.c:169 src/nse/gnunet-nse-profiler.c:910 msgid "be verbose (print progress information)" msgstr "" @@ -1245,99 +1254,116 @@ msgstr "" msgid "Issue a GET request to the GNUnet DHT, prints results." msgstr "" -#: src/dht/gnunet-dht-put.c:100 +#: src/dht/gnunet-dht-monitor.c:299 +msgid "how long to execute? 0 = forever" +msgstr "" + +#: src/dht/gnunet-dht-monitor.c:321 +msgid "Prints all packets that go through the DHT." +msgstr "" + +#: src/dht/gnunet-dht-put.c:108 #, fuzzy msgid "PUT request sent!\n" msgstr "# độ tin cáş­y được tiĂŞu phĂ­" -#: src/dht/gnunet-dht-put.c:124 +#: src/dht/gnunet-dht-put.c:111 +msgid "Timeout sending PUT request!\n" +msgstr "" + +#: src/dht/gnunet-dht-put.c:114 +#, fuzzy +msgid "PUT request not confirmed!\n" +msgstr "# độ tin cáş­y được tiĂŞu phĂ­" + +#: src/dht/gnunet-dht-put.c:144 msgid "Must provide KEY and DATA for DHT put!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:132 +#: src/dht/gnunet-dht-put.c:152 #, fuzzy, c-format msgid "Could not connect to %s service!\n" msgstr "KhĂ´ng thᝃ káşżt nối tới %s:%u: %s\n" -#: src/dht/gnunet-dht-put.c:137 +#: src/dht/gnunet-dht-put.c:157 #, fuzzy, c-format msgid "Connected to %s service!\n" msgstr "ÂŤ %s Âť được káşżt nối tới ÂŤ %s Âť.\n" -#: src/dht/gnunet-dht-put.c:152 +#: src/dht/gnunet-dht-put.c:172 #, c-format msgid "Issuing put request for `%s' with data `%s'!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:166 +#: src/dht/gnunet-dht-put.c:186 msgid "the data to insert under the key" msgstr "" -#: src/dht/gnunet-dht-put.c:169 +#: src/dht/gnunet-dht-put.c:189 msgid "how long to store this entry in the dht (in seconds)" msgstr "" -#: src/dht/gnunet-dht-put.c:175 +#: src/dht/gnunet-dht-put.c:195 msgid "how many replicas to create" msgstr "" -#: src/dht/gnunet-dht-put.c:178 +#: src/dht/gnunet-dht-put.c:198 msgid "the type to insert data as" msgstr "" -#: src/dht/gnunet-dht-put.c:203 +#: src/dht/gnunet-dht-put.c:223 msgid "Issue a PUT request to the GNUnet DHT insert DATA under KEY." msgstr "" -#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:556 -#: src/testing/testing.c:1979 src/testing/testing.c:2009 +#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:544 +#: src/testing/testing.c:1968 src/testing/testing.c:1998 #, fuzzy msgid "Failed to connect to transport service!\n" msgstr "Lỗi káşżt nối đến gnunetd.\n" -#: src/dht/gnunet-service-dht_clients.c:371 +#: src/dht/gnunet-service-dht_clients.c:407 #, fuzzy msgid "# GET requests from clients injected" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/dht/gnunet-service-dht_clients.c:462 +#: src/dht/gnunet-service-dht_clients.c:500 #, fuzzy msgid "# PUT requests received from clients" msgstr "# cĂĄc đáp ᝊng lỗ hổng được gáť­i cho trĂŹnh/mĂĄy khĂĄch" -#: src/dht/gnunet-service-dht_clients.c:529 +#: src/dht/gnunet-service-dht_clients.c:584 #, fuzzy msgid "# GET requests received from clients" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/dht/gnunet-service-dht_clients.c:624 +#: src/dht/gnunet-service-dht_clients.c:682 #, fuzzy msgid "# GET STOP requests received from clients" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/dht/gnunet-service-dht_clients.c:854 +#: src/dht/gnunet-service-dht_clients.c:919 msgid "# Key match, type mismatches in REPLY to CLIENT" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:869 +#: src/dht/gnunet-service-dht_clients.c:932 msgid "# Duplicate REPLIES to CLIENT request dropped" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:906 +#: src/dht/gnunet-service-dht_clients.c:967 #, c-format msgid "Unsupported block type (%u) in request!\n" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:928 +#: src/dht/gnunet-service-dht_clients.c:989 msgid "# RESULTS queued for clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:979 -#: src/dht/gnunet-service-dht_clients.c:1022 +#: src/dht/gnunet-service-dht_clients.c:1038 +#: src/dht/gnunet-service-dht_clients.c:1081 msgid "# REPLIES ignored for CLIENTS (no match)" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:989 +#: src/dht/gnunet-service-dht_clients.c:1048 msgid "Could not pass reply to client, message too big!\n" msgstr "" @@ -1350,28 +1376,28 @@ msgstr "# cĂĄc byte kiᝃu %d được nháş­n" msgid "# ITEMS stored in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:209 +#: src/dht/gnunet-service-dht_datacache.c:207 msgid "# Good RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:220 +#: src/dht/gnunet-service-dht_datacache.c:218 msgid "# Duplicate RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:226 +#: src/dht/gnunet-service-dht_datacache.c:224 msgid "# Invalid RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:238 +#: src/dht/gnunet-service-dht_datacache.c:236 msgid "# Unsupported RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:241 +#: src/dht/gnunet-service-dht_datacache.c:239 #, c-format msgid "Unsupported block type (%u) in local response!\n" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:271 +#: src/dht/gnunet-service-dht_datacache.c:269 #, fuzzy msgid "# GET requests given to datacache" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" @@ -1385,98 +1411,92 @@ msgstr "Nháş­n được thĂ´ng bĂĄo ÂŤ %s Âť sai tᝍ đồng đẳng ÂŤ %s Âť.\ msgid "# Preference updates given to core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:573 +#: src/dht/gnunet-service-dht_neighbours.c:571 #, fuzzy msgid "# FIND PEER messages initiated" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/dht/gnunet-service-dht_neighbours.c:629 -#: src/dht/gnunet-service-dht_neighbours.c:689 -#, fuzzy -msgid "# Peers connected" -msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" - -#: src/dht/gnunet-service-dht_neighbours.c:723 +#: src/dht/gnunet-service-dht_neighbours.c:717 #, fuzzy msgid "# Queued messages discarded (peer disconnected)" msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/dht/gnunet-service-dht_neighbours.c:778 +#: src/dht/gnunet-service-dht_neighbours.c:772 #, fuzzy msgid "# Bytes transmitted to other peers" msgstr "# cĂĄc byte kiᝃu %d được gáť­i " -#: src/dht/gnunet-service-dht_neighbours.c:816 +#: src/dht/gnunet-service-dht_neighbours.c:810 #, fuzzy msgid "# Bytes of bandwdith requested from core" msgstr "# cĂĄc yĂŞu cầu mĂĄy/trĂŹnh khĂĄch lỗ hổng được phun vĂ o" -#: src/dht/gnunet-service-dht_neighbours.c:1040 -#: src/dht/gnunet-service-dht_neighbours.c:1068 +#: src/dht/gnunet-service-dht_neighbours.c:1032 +#: src/dht/gnunet-service-dht_neighbours.c:1060 msgid "# Peers excluded from routing due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1049 -#: src/dht/gnunet-service-dht_neighbours.c:1085 +#: src/dht/gnunet-service-dht_neighbours.c:1041 +#: src/dht/gnunet-service-dht_neighbours.c:1075 #, fuzzy msgid "# Peer selection failed" msgstr "# cĂĄc cuộc gọi HTTP select (láťąa chọn)" -#: src/dht/gnunet-service-dht_neighbours.c:1221 +#: src/dht/gnunet-service-dht_neighbours.c:1207 #, fuzzy msgid "# PUT requests routed" msgstr "# cĂĄc yĂŞu cầu dht được định tuyáşżn" -#: src/dht/gnunet-service-dht_neighbours.c:1252 +#: src/dht/gnunet-service-dht_neighbours.c:1236 #, fuzzy msgid "# PUT messages queued for transmission" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/dht/gnunet-service-dht_neighbours.c:1333 +#: src/dht/gnunet-service-dht_neighbours.c:1315 #, fuzzy msgid "# GET requests routed" msgstr "# cĂĄc yĂŞu cầu dht được định tuyáşżn" -#: src/dht/gnunet-service-dht_neighbours.c:1364 +#: src/dht/gnunet-service-dht_neighbours.c:1342 #, fuzzy msgid "# GET messages queued for transmission" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/dht/gnunet-service-dht_neighbours.c:1467 +#: src/dht/gnunet-service-dht_neighbours.c:1443 #, fuzzy msgid "# RESULT messages queued for transmission" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/dht/gnunet-service-dht_neighbours.c:1555 +#: src/dht/gnunet-service-dht_neighbours.c:1531 #, fuzzy msgid "# P2P PUT requests received" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/dht/gnunet-service-dht_neighbours.c:1668 +#: src/dht/gnunet-service-dht_neighbours.c:1647 #, fuzzy msgid "# FIND PEER requests ignored due to Bloomfilter" msgstr "# cĂĄc yĂŞu cầu được lọc theo bộ lọc bloom" -#: src/dht/gnunet-service-dht_neighbours.c:1676 +#: src/dht/gnunet-service-dht_neighbours.c:1655 msgid "# FIND PEER requests ignored due to lack of HELLO" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1767 +#: src/dht/gnunet-service-dht_neighbours.c:1746 #, fuzzy msgid "# P2P GET requests received" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/dht/gnunet-service-dht_neighbours.c:1811 +#: src/dht/gnunet-service-dht_neighbours.c:1788 #, fuzzy msgid "# P2P FIND PEER requests processed" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/dht/gnunet-service-dht_neighbours.c:1825 +#: src/dht/gnunet-service-dht_neighbours.c:1802 #, fuzzy msgid "# P2P GET requests ONLY routed" msgstr "# cĂĄc yĂŞu cầu dht được định tuyáşżn" -#: src/dht/gnunet-service-dht_neighbours.c:1895 +#: src/dht/gnunet-service-dht_neighbours.c:1876 #, fuzzy msgid "# P2P RESULTS received" msgstr "# TĂ­n hiệu HTTP PUT được nháş­n" @@ -1498,29 +1518,28 @@ msgstr "" msgid "# Invalid REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:236 +#: src/dht/gnunet-service-dht_routing.c:238 msgid "# Unsupported REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:314 -#: src/dht/gnunet-service-dht_routing.c:368 +#: src/dht/gnunet-service-dht_routing.c:311 msgid "# Entries removed from routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:324 +#: src/dht/gnunet-service-dht_routing.c:352 msgid "# Entries added to routing table" msgstr "" -#: src/dht/plugin_block_dht.c:124 +#: src/dht/plugin_block_dht.c:136 #, fuzzy, c-format msgid "Block not of type %u\n" msgstr "KhĂ´ng biáşżt truyᝁn tải nĂ o kiᝃu %d.\n" -#: src/dht/plugin_block_dht.c:131 +#: src/dht/plugin_block_dht.c:143 msgid "Size mismatch for block\n" msgstr "" -#: src/dht/plugin_block_dht.c:140 +#: src/dht/plugin_block_dht.c:152 #, c-format msgid "Block of type %u is malformed\n" msgstr "" @@ -1549,68 +1568,69 @@ msgstr "" msgid "Change DNS replies to point elsewhere." msgstr "" -#: src/dns/gnunet-service-dns.c:480 +#: src/dns/gnunet-service-dns.c:485 #, fuzzy, c-format msgid "Could not bind to any port: %s\n" msgstr "KhĂ´ng tĂŹm thẼy địa chỉ IP cᝧa mĂĄy ÂŤ %s Âť: %s\n" -#: src/dns/gnunet-service-dns.c:634 +#: src/dns/gnunet-service-dns.c:639 msgid "# DNS requests answered via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:818 +#: src/dns/gnunet-service-dns.c:822 msgid "# DNS exit failed (failed to open socket)" msgstr "" -#: src/dns/gnunet-service-dns.c:1001 +#: src/dns/gnunet-service-dns.c:1005 #, c-format msgid "Received DNS response that is too small (%u bytes)" msgstr "" -#: src/dns/gnunet-service-dns.c:1046 +#: src/dns/gnunet-service-dns.c:1050 msgid "# External DNS response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1165 +#: src/dns/gnunet-service-dns.c:1168 msgid "# Client response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1198 -msgid "Changing DNS reply according to client specifications\n" -msgstr "" - -#: src/dns/gnunet-service-dns.c:1279 +#: src/dns/gnunet-service-dns.c:1281 msgid "Received malformed IPv4-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1294 +#: src/dns/gnunet-service-dns.c:1297 msgid "Received malformed IPv6-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1303 +#: src/dns/gnunet-service-dns.c:1306 #, c-format msgid "Got non-IP packet with %u bytes and protocol %u from TUN\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1312 +#: src/dns/gnunet-service-dns.c:1315 msgid "# Non-DNS UDP packet received via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:1377 +#: src/dns/gnunet-service-dns.c:1380 #, fuzzy msgid "# DNS requests received via TUN interface" msgstr "# cĂĄc đáp ᝊng lỗ hổng được gáť­i cho trĂŹnh/mĂĄy khĂĄch" -#: src/dns/gnunet-service-dns.c:1461 +#: src/dns/gnunet-service-dns.c:1465 #, c-format msgid "Configured DNS exit `%s' is not working / valid.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1493 src/exit/gnunet-daemon-exit.c:2673 +#: src/dns/gnunet-service-dns.c:1497 src/exit/gnunet-daemon-exit.c:2674 msgid "# Inbound MESH tunnels created" msgstr "" -#: src/dns/gnunet-service-dns.c:1567 +#: src/dns/gnunet-service-dns.c:1561 src/exit/gnunet-daemon-exit.c:3032 +#, c-format +msgid "`%s' must be installed SUID, refusing to run\n" +msgstr "" + +#: src/dns/gnunet-service-dns.c:1581 msgid "Configured to provide DNS exit, but no valid DNS server configured!\n" msgstr "" @@ -1634,15 +1654,15 @@ msgstr "" msgid "# Bytes transmitted via mesh tunnels" msgstr "# cĂĄc byte được gáť­i" -#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2068 -#: src/exit/gnunet-daemon-exit.c:2318 src/vpn/gnunet-service-vpn.c:1388 -#: src/vpn/gnunet-service-vpn.c:1788 src/vpn/gnunet-service-vpn.c:1951 +#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2069 +#: src/exit/gnunet-daemon-exit.c:2319 src/vpn/gnunet-service-vpn.c:1394 +#: src/vpn/gnunet-service-vpn.c:1795 src/vpn/gnunet-service-vpn.c:1958 msgid "# ICMPv4 packets dropped (type not allowed)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2127 -#: src/exit/gnunet-daemon-exit.c:2377 src/vpn/gnunet-service-vpn.c:1444 -#: src/vpn/gnunet-service-vpn.c:1847 src/vpn/gnunet-service-vpn.c:1984 +#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2128 +#: src/exit/gnunet-daemon-exit.c:2378 src/vpn/gnunet-service-vpn.c:1450 +#: src/vpn/gnunet-service-vpn.c:1854 src/vpn/gnunet-service-vpn.c:1991 msgid "# ICMPv6 packets dropped (type not allowed)" msgstr "" @@ -1691,138 +1711,138 @@ msgstr "" msgid "Packet from unknown protocol %u received. Ignored.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1470 +#: src/exit/gnunet-daemon-exit.c:1471 #, fuzzy msgid "# TCP packets sent via TUN" msgstr "# cĂĄc byte đã gáť­i qua UDP" -#: src/exit/gnunet-daemon-exit.c:1570 +#: src/exit/gnunet-daemon-exit.c:1571 #, fuzzy msgid "# TCP service creation requests received via mesh" msgstr "# cĂĄc yĂŞu cầu danh sĂĄch mĂĄy được nháş­n" -#: src/exit/gnunet-daemon-exit.c:1573 src/exit/gnunet-daemon-exit.c:1652 -#: src/exit/gnunet-daemon-exit.c:1762 src/exit/gnunet-daemon-exit.c:1992 -#: src/exit/gnunet-daemon-exit.c:2234 src/exit/gnunet-daemon-exit.c:2515 -#: src/exit/gnunet-daemon-exit.c:2615 +#: src/exit/gnunet-daemon-exit.c:1574 src/exit/gnunet-daemon-exit.c:1653 +#: src/exit/gnunet-daemon-exit.c:1763 src/exit/gnunet-daemon-exit.c:1993 +#: src/exit/gnunet-daemon-exit.c:2235 src/exit/gnunet-daemon-exit.c:2516 +#: src/exit/gnunet-daemon-exit.c:2616 #, fuzzy msgid "# Bytes received from MESH" msgstr "# cĂĄc byte đã nháş­n qua HTTP" -#: src/exit/gnunet-daemon-exit.c:1606 src/exit/gnunet-daemon-exit.c:2637 +#: src/exit/gnunet-daemon-exit.c:1607 src/exit/gnunet-daemon-exit.c:2638 #, c-format msgid "No service found for %s on port %d!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1610 +#: src/exit/gnunet-daemon-exit.c:1611 #, fuzzy msgid "# TCP requests dropped (no such service)" msgstr "# cĂĄc yĂŞu cầu lỗ hổng bị bỏ do trọng tải" -#: src/exit/gnunet-daemon-exit.c:1655 +#: src/exit/gnunet-daemon-exit.c:1656 #, fuzzy msgid "# TCP IP-exit creation requests received via mesh" msgstr "# cĂĄc yĂŞu cầu danh sĂĄch mĂĄy được nháş­n" -#: src/exit/gnunet-daemon-exit.c:1765 +#: src/exit/gnunet-daemon-exit.c:1766 #, fuzzy msgid "# TCP data requests received via mesh" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/exit/gnunet-daemon-exit.c:1779 +#: src/exit/gnunet-daemon-exit.c:1780 #, fuzzy msgid "# TCP DATA requests dropped (no session)" msgstr "# cĂĄc yĂŞu cầu lỗ hổng bị bỏ do trọng tải" -#: src/exit/gnunet-daemon-exit.c:1829 +#: src/exit/gnunet-daemon-exit.c:1830 #, fuzzy msgid "# ICMP packets sent via TUN" msgstr "# cĂĄc byte đã gáť­i qua UDP" -#: src/exit/gnunet-daemon-exit.c:1995 +#: src/exit/gnunet-daemon-exit.c:1996 #, fuzzy msgid "# ICMP IP-exit requests received via mesh" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/exit/gnunet-daemon-exit.c:2237 +#: src/exit/gnunet-daemon-exit.c:2238 #, fuzzy msgid "# ICMP service requests received via mesh" msgstr "# cĂĄc đáp ᝊng lỗ hổng được gáť­i cho trĂŹnh/mĂĄy khĂĄch" -#: src/exit/gnunet-daemon-exit.c:2303 src/vpn/gnunet-service-vpn.c:1378 -#: src/vpn/gnunet-service-vpn.c:1945 +#: src/exit/gnunet-daemon-exit.c:2304 src/vpn/gnunet-service-vpn.c:1384 +#: src/vpn/gnunet-service-vpn.c:1952 msgid "# ICMPv4 packets dropped (impossible PT to v6)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2362 src/vpn/gnunet-service-vpn.c:1414 -#: src/vpn/gnunet-service-vpn.c:1426 src/vpn/gnunet-service-vpn.c:1835 +#: src/exit/gnunet-daemon-exit.c:2363 src/vpn/gnunet-service-vpn.c:1420 +#: src/vpn/gnunet-service-vpn.c:1432 src/vpn/gnunet-service-vpn.c:1842 msgid "# ICMPv6 packets dropped (impossible PT to v4)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2412 +#: src/exit/gnunet-daemon-exit.c:2413 #, fuzzy msgid "# UDP packets sent via TUN" msgstr "# cĂĄc byte đã gáť­i qua UDP" -#: src/exit/gnunet-daemon-exit.c:2518 +#: src/exit/gnunet-daemon-exit.c:2519 #, fuzzy msgid "# UDP IP-exit requests received via mesh" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/exit/gnunet-daemon-exit.c:2618 +#: src/exit/gnunet-daemon-exit.c:2619 #, fuzzy msgid "# UDP service requests received via mesh" msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/exit/gnunet-daemon-exit.c:2641 +#: src/exit/gnunet-daemon-exit.c:2642 #, fuzzy msgid "# UDP requests dropped (no such service)" msgstr "# cĂĄc yĂŞu cầu lỗ hổng bị bỏ do trọng tải" -#: src/exit/gnunet-daemon-exit.c:2881 +#: src/exit/gnunet-daemon-exit.c:2882 #, c-format msgid "No addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2895 src/exit/gnunet-daemon-exit.c:2907 +#: src/exit/gnunet-daemon-exit.c:2896 src/exit/gnunet-daemon-exit.c:2908 #, c-format msgid "Service `%s' configured for IPv4, but IPv4 is disabled!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2918 +#: src/exit/gnunet-daemon-exit.c:2919 #, c-format msgid "No IP addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3047 +#: src/exit/gnunet-daemon-exit.c:3048 msgid "" "This system does not support IPv4, will disable IPv4 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3055 +#: src/exit/gnunet-daemon-exit.c:3056 msgid "" "This system does not support IPv6, will disable IPv6 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3062 +#: src/exit/gnunet-daemon-exit.c:3063 msgid "" "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use " "ENABLE_IPv4=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3068 +#: src/exit/gnunet-daemon-exit.c:3069 msgid "" "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use " "ENABLE_IPv6=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3074 src/pt/gnunet-daemon-pt.c:884 +#: src/exit/gnunet-daemon-exit.c:3075 src/pt/gnunet-daemon-pt.c:884 msgid "No useful service enabled. Exiting.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3235 +#: src/exit/gnunet-daemon-exit.c:3236 msgid "Daemon to run to provide an IP exit node for the VPN" msgstr "" @@ -1830,122 +1850,127 @@ msgstr "" msgid "# acknowledgements sent for fragment" msgstr "" -#: src/fragmentation/defragmentation.c:454 +#: src/fragmentation/defragmentation.c:456 #, fuzzy msgid "# fragments received" msgstr "# cĂĄc mảnh bị loấi bỏ" -#: src/fragmentation/defragmentation.c:513 +#: src/fragmentation/defragmentation.c:521 #, fuzzy msgid "# duplicate fragments received" msgstr "# cĂĄc káşżt quả dht được nháş­n" -#: src/fragmentation/defragmentation.c:526 +#: src/fragmentation/defragmentation.c:534 msgid "# messages defragmented" msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/fragmentation/fragmentation.c:188 +#: src/fragmentation/fragmentation.c:203 #, fuzzy msgid "# fragments transmitted" msgstr "# CĂĄc táťą quảng cĂĄo được truyᝁn" -#: src/fragmentation/fragmentation.c:191 +#: src/fragmentation/fragmentation.c:206 #, fuzzy msgid "# fragments retransmitted" msgstr "# CĂĄc táťą quảng cĂĄo được truyᝁn" -#: src/fragmentation/fragmentation.c:255 +#: src/fragmentation/fragmentation.c:232 +#, fuzzy +msgid "# fragments wrap arounds" +msgstr "# CĂĄc táťą quảng cĂĄo được truyᝁn" + +#: src/fragmentation/fragmentation.c:273 msgid "# messages fragmented" msgstr "# cĂĄc thĂ´ng bĂĄo bị táşż phân" -#: src/fragmentation/fragmentation.c:258 +#: src/fragmentation/fragmentation.c:276 msgid "# total size of fragmented messages" msgstr "" -#: src/fragmentation/fragmentation.c:343 +#: src/fragmentation/fragmentation.c:363 #, fuzzy msgid "# fragment acknowledgements received" msgstr "# CĂĄc quảng cĂĄo đồng đẳng được nháş­n" -#: src/fragmentation/fragmentation.c:349 +#: src/fragmentation/fragmentation.c:369 msgid "# bits removed from fragmentation ACKs" msgstr "" -#: src/fragmentation/fragmentation.c:373 +#: src/fragmentation/fragmentation.c:393 #, fuzzy msgid "# fragmentation transmissions completed" msgstr "# cĂĄc sáťą truyᝁn PONG bị lỗi" -#: src/fs/fs_api.c:284 +#: src/fs/fs_api.c:339 #, fuzzy, c-format msgid "Could not open file `%s': %s" msgstr "Lỗi mở táş­p tin theo dĂľi ÂŤ %s Âť: %s\n" -#: src/fs/fs_api.c:293 +#: src/fs/fs_api.c:348 #, fuzzy, c-format msgid "Could not read file `%s': %s" msgstr "Lỗi mở táş­p tin theo dĂľi ÂŤ %s Âť: %s\n" -#: src/fs/fs_api.c:299 +#: src/fs/fs_api.c:354 #, c-format msgid "Short read reading from file `%s'!" msgstr "" -#: src/fs/fs_api.c:877 +#: src/fs/fs_api.c:938 #, fuzzy, c-format msgid "Failed to resume publishing information `%s': %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/fs/fs_api.c:1334 +#: src/fs/fs_api.c:1395 #, c-format msgid "Failed to recover namespace `%s', cannot resume publishing operation.\n" msgstr "" -#: src/fs/fs_api.c:1376 +#: src/fs/fs_api.c:1437 #, c-format msgid "Failure while resuming publishing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:1392 +#: src/fs/fs_api.c:1453 #, fuzzy, c-format msgid "Failed to resume publishing operation `%s': %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/fs/fs_api.c:2004 +#: src/fs/fs_api.c:2106 #, c-format msgid "Failure while resuming unindexing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2014 +#: src/fs/fs_api.c:2116 #, fuzzy, c-format msgid "Failed to resume unindexing operation `%s': %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/fs/fs_api.c:2139 src/fs/fs_api.c:2378 +#: src/fs/fs_api.c:2241 src/fs/fs_api.c:2480 #, fuzzy, c-format msgid "Failed to resume sub-download `%s': %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/fs/fs_api.c:2156 +#: src/fs/fs_api.c:2258 #, fuzzy, c-format msgid "Failed to resume sub-search `%s': %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/fs/fs_api.c:2168 src/fs/fs_api.c:2187 src/fs/fs_api.c:2671 +#: src/fs/fs_api.c:2270 src/fs/fs_api.c:2289 src/fs/fs_api.c:2773 #, c-format msgid "Failure while resuming search operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2369 +#: src/fs/fs_api.c:2471 #, c-format msgid "Failed to resume sub-download `%s': could not open file `%s'\n" msgstr "" -#: src/fs/fs_api.c:2615 +#: src/fs/fs_api.c:2717 msgid "Could not resume running search, will resume as paused search\n" msgstr "" -#: src/fs/fs_api.c:2709 +#: src/fs/fs_api.c:2811 #, c-format msgid "Failure while resuming download operation `%s': %s\n" msgstr "" @@ -1955,53 +1980,58 @@ msgstr "" msgid "MAGIC mismatch. This is not a GNUnet directory.\n" msgstr "Lỗi định dấng táş­p tin (khĂ´ng phải lĂ  thĆ° m᝼c GNUnet ?)\n" -#: src/fs/fs_download.c:310 +#: src/fs/fs_download.c:311 msgid "" "Recursive downloads of directories larger than 4 GB are not supported on 32-" "bit systems\n" msgstr "" -#: src/fs/fs_download.c:330 +#: src/fs/fs_download.c:331 msgid "Directory too large for system address space\n" msgstr "" -#: src/fs/fs_download.c:488 src/fs/fs_download.c:500 +#: src/fs/fs_download.c:497 src/fs/fs_download.c:509 #, fuzzy, c-format msgid "Failed to open file `%s' for writing" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/fs/fs_download.c:870 +#: src/fs/fs_download.c:878 #, fuzzy, c-format msgid "Failed to create directory for recursive download of `%s'\n" msgstr "Lỗi cáş­p nháş­t dᝯ liệu cho mĂ´-đun ÂŤ %s Âť\n" -#: src/fs/fs_download.c:951 +#: src/fs/fs_download.c:960 #, c-format msgid "" "Internal error or bogus download URI (expected %u bytes at depth %u and " -"offset %llu/%llu, got %u bytes)\n" +"offset %llu/%llu, got %u bytes)" msgstr "" -#: src/fs/fs_download.c:977 +#: src/fs/fs_download.c:986 msgid "internal error decrypting content" msgstr "" -#: src/fs/fs_download.c:1000 +#: src/fs/fs_download.c:1009 #, fuzzy, c-format -msgid "Download failed: could not open file `%s': %s\n" +msgid "Download failed: could not open file `%s': %s" msgstr "Lỗi mở táş­p tin theo dĂľi ÂŤ %s Âť: %s\n" -#: src/fs/fs_download.c:1010 +#: src/fs/fs_download.c:1019 #, fuzzy, c-format -msgid "Failed to seek to offset %llu in file `%s': %s\n" +msgid "Failed to seek to offset %llu in file `%s': %s" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/fs/fs_download.c:1019 -#, c-format -msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s\n" -msgstr "" +#: src/fs/fs_download.c:1028 +#, fuzzy, c-format +msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s" +msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" + +#: src/fs/fs_download.c:1125 +#, fuzzy +msgid "internal error decoding tree" +msgstr "=\tLỗi đọc thĆ° m᝼c.\n" -#: src/fs/fs_download.c:1835 +#: src/fs/fs_download.c:1888 #, fuzzy msgid "Invalid URI" msgstr "Dᝯ liệu nháş­p khĂ´ng hᝣp lệ.\n" @@ -2085,64 +2115,64 @@ msgstr "Lỗi VR." msgid "Failed to connect to datastore." msgstr "KhĂ´ng káşżt nối được đến trĂŹnh nᝁn gnunetd." -#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:395 +#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:397 #, fuzzy, c-format msgid "Publishing failed: %s" msgstr "Gạp lỗi khi tải lĂŞn táş­p tin: %s\n" -#: src/fs/fs_publish.c:616 src/fs/fs_publish.c:633 src/fs/fs_publish.c:672 -#: src/fs/fs_publish.c:692 src/fs/fs_publish.c:717 src/fs/fs_publish.c:857 +#: src/fs/fs_publish.c:621 src/fs/fs_publish.c:638 src/fs/fs_publish.c:677 +#: src/fs/fs_publish.c:697 src/fs/fs_publish.c:722 src/fs/fs_publish.c:862 #, fuzzy, c-format msgid "Can not index file `%s': %s. Will try to insert instead.\n" msgstr "Lỗi đánh chỉ m᝼c táş­p tin ÂŤ %s Âť. Đᝁ nghị: tháť­ chèn táş­p tin.\n" -#: src/fs/fs_publish.c:618 +#: src/fs/fs_publish.c:623 msgid "timeout on index-start request to `fs' service" msgstr "" -#: src/fs/fs_publish.c:630 +#: src/fs/fs_publish.c:635 #, fuzzy msgid "unknown error" msgstr "Lỗi khĂ´ng rĂľ" -#: src/fs/fs_publish.c:673 +#: src/fs/fs_publish.c:678 msgid "failed to compute hash" msgstr "" -#: src/fs/fs_publish.c:693 +#: src/fs/fs_publish.c:698 #, fuzzy msgid "filename too long" msgstr "tĂŞn táş­p tin" -#: src/fs/fs_publish.c:718 +#: src/fs/fs_publish.c:723 msgid "could not connect to `fs' service" msgstr "" -#: src/fs/fs_publish.c:741 +#: src/fs/fs_publish.c:746 #, fuzzy, c-format msgid "Failed to get file identifiers for `%s'\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/fs/fs_publish.c:806 +#: src/fs/fs_publish.c:811 #, fuzzy, c-format msgid "Recursive upload failed at `%s': %s" msgstr "%s bị lỗi tấi %s:%d: ÂŤ %s Âť\n" -#: src/fs/fs_publish.c:812 +#: src/fs/fs_publish.c:817 #, fuzzy, c-format msgid "Recursive upload failed: %s" msgstr "Gạp lỗi khi tải lĂŞn táş­p tin: %s\n" -#: src/fs/fs_publish.c:858 +#: src/fs/fs_publish.c:863 msgid "needs to be an actual file" msgstr "" -#: src/fs/fs_publish.c:1067 +#: src/fs/fs_publish.c:1071 #, fuzzy, c-format msgid "Insufficient space for publishing: %s" msgstr "KhĂ´ng đủ quyᝁn truy cáş­p cho ÂŤ %s Âť: %s\n" -#: src/fs/fs_publish.c:1138 +#: src/fs/fs_publish.c:1142 #, c-format msgid "Reserving space for %u entries and %llu bytes for publication\n" msgstr "" @@ -2152,7 +2182,7 @@ msgstr "" msgid "Could not connect to datastore." msgstr "ÂŤ %s Âť: KhĂ´ng thᝃ káşżt nối.\n" -#: src/fs/fs_search.c:810 +#: src/fs/fs_search.c:829 #, c-format msgid "Got result with unknown block type `%d', ignoring" msgstr "" @@ -2162,44 +2192,64 @@ msgstr "" msgid "Failed to start daemon: %s\n" msgstr "Lỗi bắt đầu thu tháş­p.\n" -#: src/fs/fs_unindex.c:57 +#: src/fs/fs_unindex.c:58 msgid "Failed to find given position in file" msgstr "" -#: src/fs/fs_unindex.c:62 +#: src/fs/fs_unindex.c:63 #, fuzzy msgid "Failed to read file" msgstr "Lỗi gáť­i tin nháşłn.\n" -#: src/fs/fs_unindex.c:231 +#: src/fs/fs_unindex.c:233 msgid "Unexpected time for a response from `fs' service." msgstr "" -#: src/fs/fs_unindex.c:239 +#: src/fs/fs_unindex.c:241 msgid "Timeout waiting for `fs' service." msgstr "" -#: src/fs/fs_unindex.c:247 +#: src/fs/fs_unindex.c:249 #, fuzzy msgid "Invalid response from `fs' service." msgstr "Đối số khĂ´ng hᝣp lệ cho ÂŤ %s Âť.\n" -#: src/fs/fs_unindex.c:292 +#: src/fs/fs_unindex.c:293 #, fuzzy msgid "Failed to connect to FS service for unindexing." msgstr "KhĂ´ng káşżt nối được đến trĂŹnh nᝁn gnunetd." -#: src/fs/fs_unindex.c:325 +#: src/fs/fs_unindex.c:344 +#, fuzzy +msgid "Failed to get KSKs from directory scan." +msgstr "Lỗi truy cáş­p đến thĆ° m᝼c nhĂ  GNUnet ÂŤ %s Âť\n" + +#: src/fs/fs_unindex.c:356 +#, fuzzy, c-format +msgid "Internal error scanning `%s'.\n" +msgstr "=\tLỗi đọc thĆ° m᝼c.\n" + +#: src/fs/fs_unindex.c:411 +#, fuzzy, c-format +msgid "Failed to remove KBlock: %s\n" +msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" + +#: src/fs/fs_unindex.c:501 +#, fuzzy, c-format +msgid "Failed to parse URI `%s' from KBlock!\n" +msgstr "Táş­p tin ÂŤ %s Âť cĂł URI: %s\n" + +#: src/fs/fs_unindex.c:553 src/fs/fs_unindex.c:618 #, fuzzy msgid "Failed to connect to `datastore' service." msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" -#: src/fs/fs_unindex.c:338 +#: src/fs/fs_unindex.c:631 #, fuzzy msgid "Failed to open file for unindexing." msgstr "KhĂ´ng káşżt nối được đến trĂŹnh nᝁn gnunetd." -#: src/fs/fs_unindex.c:372 +#: src/fs/fs_unindex.c:665 #, fuzzy msgid "Failed to compute hash of file." msgstr "KhĂ´ng káşżt nối được đến trĂŹnh nᝁn gnunetd." @@ -2311,95 +2361,95 @@ msgstr "Lỗi định dấng táş­p tin (khĂ´ng phải lĂ  thĆ° m᝼c GNUnet ?)\n msgid "Display contents of a GNUnet directory" msgstr "Lỗi định dấng táş­p tin (khĂ´ng phải lĂ  thĆ° m᝼c GNUnet ?)\n" -#: src/fs/gnunet-download.c:100 +#: src/fs/gnunet-download.c:101 #, fuzzy, c-format msgid "Starting download `%s'.\n" msgstr "Đang bắt đầu tĂ i vᝁ ÂŤ %s Âť\n" -#: src/fs/gnunet-download.c:109 +#: src/fs/gnunet-download.c:110 #, fuzzy msgid "" msgstr "Lỗi khĂ´ng rĂľ" -#: src/fs/gnunet-download.c:118 +#: src/fs/gnunet-download.c:119 #, c-format msgid "" "Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to " "download\n" msgstr "" -#: src/fs/gnunet-download.c:128 +#: src/fs/gnunet-download.c:129 #, fuzzy, c-format msgid "Error downloading: %s.\n" msgstr "Gạp lỗi khi tải xuống: %s\n" -#: src/fs/gnunet-download.c:136 +#: src/fs/gnunet-download.c:137 #, fuzzy, c-format msgid "Downloading `%s' done (%s/s).\n" msgstr "Tiáşżn trĂŹnh tải lĂŞn ÂŤ %s Âť đã tiáşżp t᝼c lấi.\n" -#: src/fs/gnunet-download.c:151 src/fs/gnunet-publish.c:190 +#: src/fs/gnunet-download.c:152 src/fs/gnunet-publish.c:190 #: src/fs/gnunet-search.c:190 src/fs/gnunet-unindex.c:109 #, fuzzy, c-format msgid "Unexpected status: %d\n" msgstr "Gạp sáťą kiện bẼt thường: %d\n" -#: src/fs/gnunet-download.c:176 +#: src/fs/gnunet-download.c:177 #, fuzzy msgid "You need to specify a URI argument.\n" msgstr "KHÔNG cho phĂŠp ghi rĂľ cả hai địa chỉ URI vĂ  tĂŞn táş­p tin.\n" -#: src/fs/gnunet-download.c:182 src/fs/gnunet-publish.c:618 +#: src/fs/gnunet-download.c:183 src/fs/gnunet-publish.c:624 #, fuzzy, c-format msgid "Failed to parse URI: %s\n" msgstr "Táş­p tin ÂŤ %s Âť cĂł URI: %s\n" -#: src/fs/gnunet-download.c:189 +#: src/fs/gnunet-download.c:190 msgid "Only CHK or LOC URIs supported.\n" msgstr "" -#: src/fs/gnunet-download.c:196 +#: src/fs/gnunet-download.c:197 msgid "Target filename must be specified.\n" msgstr "" -#: src/fs/gnunet-download.c:210 src/fs/gnunet-publish.c:596 +#: src/fs/gnunet-download.c:211 src/fs/gnunet-publish.c:602 #: src/fs/gnunet-search.c:241 src/fs/gnunet-unindex.c:141 #, fuzzy, c-format msgid "Could not initialize `%s' subsystem.\n" msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" -#: src/fs/gnunet-download.c:247 src/fs/gnunet-search.c:285 +#: src/fs/gnunet-download.c:248 src/fs/gnunet-search.c:285 #, fuzzy msgid "set the desired LEVEL of receiver-anonymity" msgstr "đặt CẤP mong muốn cᝧa tĂŹnh trấng nạc danh cᝧa người gáť­i" -#: src/fs/gnunet-download.c:250 +#: src/fs/gnunet-download.c:251 msgid "delete incomplete downloads (when aborted with CTRL-C)" msgstr "xoĂĄ việc tải vᝁ khĂ´ng hoĂ n thĂ nh (khi hᝧy bở dĂšng CTRL-C)" -#: src/fs/gnunet-download.c:253 src/fs/gnunet-search.c:288 +#: src/fs/gnunet-download.c:254 src/fs/gnunet-search.c:288 msgid "only search the local peer (no P2P network search)" msgstr "" -#: src/fs/gnunet-download.c:256 +#: src/fs/gnunet-download.c:257 msgid "write the file to FILENAME" msgstr "ghi táş­p tin vĂ o TÊN_TẏP_TIN" -#: src/fs/gnunet-download.c:260 +#: src/fs/gnunet-download.c:261 #, fuzzy msgid "set the maximum number of parallel downloads that is allowed" msgstr "đặt số tối đa cĂĄc việc tải xuống đồng thời được phĂŠp" -#: src/fs/gnunet-download.c:264 +#: src/fs/gnunet-download.c:265 #, fuzzy msgid "set the maximum number of parallel requests for blocks that is allowed" msgstr "đặt số tối đa cĂĄc việc tải xuống đồng thời được phĂŠp" -#: src/fs/gnunet-download.c:267 +#: src/fs/gnunet-download.c:268 msgid "download a GNUnet directory recursively" msgstr "tải xuống đệ quy một thĆ° m᝼c GNUnet" -#: src/fs/gnunet-download.c:277 +#: src/fs/gnunet-download.c:278 msgid "" "Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/" "chk/...)" @@ -2414,35 +2464,30 @@ msgstr "" msgid "Special file-sharing operations" msgstr "TĂšy chọn chia sáşť táş­p tin" -#: src/fs/gnunet-pseudonym.c:151 src/statistics/gnunet-statistics.c:126 +#: src/fs/gnunet-pseudonym.c:160 src/statistics/gnunet-statistics.c:167 #, fuzzy, c-format msgid "Invalid argument `%s'\n" msgstr "Đối số khĂ´ng hᝣp lệ cho ÂŤ %s Âť.\n" -#: src/fs/gnunet-pseudonym.c:165 -#, fuzzy, c-format -msgid "Namespace `%s' unknown.\n" -msgstr "KhĂ´ng gian tĂŞn ÂŤ %s Âť cĂł đánh giĂĄ %d.\n" - -#: src/fs/gnunet-pseudonym.c:240 src/fs/gnunet-pseudonym.c:247 -#: src/fs/gnunet-pseudonym.c:249 +#: src/fs/gnunet-pseudonym.c:250 src/fs/gnunet-pseudonym.c:257 +#: src/fs/gnunet-pseudonym.c:259 #, fuzzy, c-format msgid "Option `%s' ignored\n" msgstr "%s: tĂšy chọn ÂŤ %s Âť lĂ  mĆĄ hồ\n" -#: src/fs/gnunet-pseudonym.c:269 src/fs/gnunet-publish.c:672 +#: src/fs/gnunet-pseudonym.c:279 src/fs/gnunet-publish.c:678 msgid "set the desired LEVEL of sender-anonymity" msgstr "đặt CẤP mong muốn cᝧa tĂŹnh trấng nạc danh cᝧa người gáť­i" -#: src/fs/gnunet-pseudonym.c:272 +#: src/fs/gnunet-pseudonym.c:282 msgid "create or advertise namespace NAME" msgstr "" -#: src/fs/gnunet-pseudonym.c:275 +#: src/fs/gnunet-pseudonym.c:285 msgid "delete namespace NAME " msgstr "" -#: src/fs/gnunet-pseudonym.c:278 +#: src/fs/gnunet-pseudonym.c:288 #, fuzzy msgid "" "add an additional keyword for the advertisment (this option can be specified " @@ -2451,38 +2496,38 @@ msgstr "" "thĂŞm một tᝍ khĂła bổ sung cho tẼt cả táş­p tin vĂ  thĆ° m᝼c (cĂł thᝃ chỉ ra tĂšy " "chọn nĂ y nhiᝁu lần)" -#: src/fs/gnunet-pseudonym.c:282 src/fs/gnunet-publish.c:691 +#: src/fs/gnunet-pseudonym.c:292 src/fs/gnunet-publish.c:697 msgid "set the meta-data for the given TYPE to the given VALUE" msgstr "đặt siĂŞu dᝯ liệu cho KIỂU đưa ra thĂ nh GIÁ_TRỊ chỉ ra" -#: src/fs/gnunet-pseudonym.c:285 +#: src/fs/gnunet-pseudonym.c:295 #, fuzzy msgid "print names of local namespaces" msgstr "đặt đánh giĂĄ cᝧa một khĂ´ng gian tĂŞn" -#: src/fs/gnunet-pseudonym.c:288 +#: src/fs/gnunet-pseudonym.c:298 msgid "use the given PRIORITY for the advertisments" msgstr "" -#: src/fs/gnunet-pseudonym.c:291 +#: src/fs/gnunet-pseudonym.c:301 msgid "do not print names of remote namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:294 src/fs/gnunet-publish.c:710 +#: src/fs/gnunet-pseudonym.c:304 src/fs/gnunet-publish.c:716 msgid "set the desired replication LEVEL" msgstr "" -#: src/fs/gnunet-pseudonym.c:297 +#: src/fs/gnunet-pseudonym.c:307 #, fuzzy msgid "specify ID of the root of the namespace" msgstr "đặt đánh giĂĄ cᝧa một khĂ´ng gian tĂŞn" -#: src/fs/gnunet-pseudonym.c:300 +#: src/fs/gnunet-pseudonym.c:310 #, fuzzy msgid "change rating of namespace ID by VALUE" msgstr "đặt đánh giĂĄ cᝧa một khĂ´ng gian tĂŞn" -#: src/fs/gnunet-pseudonym.c:308 +#: src/fs/gnunet-pseudonym.c:318 msgid "Manage GNUnet pseudonyms." msgstr "" @@ -2511,115 +2556,115 @@ msgstr "TĂ´i lĂ  đồng đẳng ÂŤ %s Âť.\n" msgid "Cleanup after abort complete.\n" msgstr "HoĂ n thĂ nh khởi chấy ÂŤ %s Âť.\n" -#: src/fs/gnunet-publish.c:299 +#: src/fs/gnunet-publish.c:305 #, fuzzy, c-format msgid "Meta data for file `%s' (%s)\n" msgstr "Đang cáş­p nháş­t dᝯ liệu cho mĂ´-đun ÂŤ %s Âť\n" -#: src/fs/gnunet-publish.c:301 +#: src/fs/gnunet-publish.c:307 #, fuzzy, c-format msgid "Keywords for file `%s' (%s)\n" msgstr "Tᝍ khoĂĄ cho táş­p tin ÂŤ %s Âť:\n" -#: src/fs/gnunet-publish.c:352 +#: src/fs/gnunet-publish.c:358 #, fuzzy, c-format msgid "Failed to create namespace `%s'\n" msgstr "KhĂ´ng thᝃ tấo miᝁn tĂŞn.\n" -#: src/fs/gnunet-publish.c:427 +#: src/fs/gnunet-publish.c:433 #, fuzzy msgid "Could not publish\n" msgstr "KhĂ´ng thᝃ truy cáş­p đến ÂŤ %s Âť: %s\n" -#: src/fs/gnunet-publish.c:454 +#: src/fs/gnunet-publish.c:460 #, fuzzy msgid "Could not start publishing.\n" msgstr "KhĂ´ng thᝃ nấp phần bổ sung truyᝁn tải ÂŤ %s Âť\n" -#: src/fs/gnunet-publish.c:485 +#: src/fs/gnunet-publish.c:491 #, fuzzy, c-format msgid "Scanning directory `%s'.\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/fs/gnunet-publish.c:487 +#: src/fs/gnunet-publish.c:493 #, fuzzy, c-format msgid "Scanning file `%s'.\n" msgstr "Đang bắt đầu tĂ i vᝁ ÂŤ %s Âť\n" -#: src/fs/gnunet-publish.c:492 +#: src/fs/gnunet-publish.c:498 #, c-format msgid "There was trouble processing file `%s', skipping it.\n" msgstr "" -#: src/fs/gnunet-publish.c:497 +#: src/fs/gnunet-publish.c:503 msgid "Preprocessing complete.\n" msgstr "" -#: src/fs/gnunet-publish.c:501 +#: src/fs/gnunet-publish.c:507 #, fuzzy, c-format msgid "Extracting meta data from file `%s' complete.\n" msgstr "Đang cáş­p nháş­t dᝯ liệu cho mĂ´-đun ÂŤ %s Âť\n" -#: src/fs/gnunet-publish.c:505 +#: src/fs/gnunet-publish.c:511 msgid "Meta data extraction has finished.\n" msgstr "" -#: src/fs/gnunet-publish.c:512 +#: src/fs/gnunet-publish.c:518 #, fuzzy msgid "Internal error scanning directory.\n" msgstr "=\tLỗi đọc thĆ° m᝼c.\n" -#: src/fs/gnunet-publish.c:546 +#: src/fs/gnunet-publish.c:552 #, c-format msgid "Cannot extract metadata from a URI!\n" msgstr "KhĂ´ng thᝃ trĂ­ch siĂŞu dᝯ liệu ra một địa chỉ URI.\n" -#: src/fs/gnunet-publish.c:553 +#: src/fs/gnunet-publish.c:559 #, c-format msgid "You must specify one and only one filename for insertion.\n" msgstr "Phải ghi rĂľ chỉ một tĂŞn táş­p tin để chèn.\n" -#: src/fs/gnunet-publish.c:559 +#: src/fs/gnunet-publish.c:565 #, c-format msgid "You must NOT specify an URI and a filename.\n" msgstr "KHÔNG cho phĂŠp ghi rĂľ cả hai địa chỉ URI vĂ  tĂŞn táş­p tin.\n" -#: src/fs/gnunet-publish.c:567 src/vpn/gnunet-vpn.c:214 +#: src/fs/gnunet-publish.c:573 src/vpn/gnunet-vpn.c:214 #, c-format msgid "Option `%s' is required when using option `%s'.\n" msgstr "TĂšy chọn ÂŤ %s Âť cần thiáşżt khi dĂšng tĂšy chọn ÂŤ %s Âť.\n" -#: src/fs/gnunet-publish.c:577 src/fs/gnunet-publish.c:584 -#: src/transport/gnunet-transport.c:530 +#: src/fs/gnunet-publish.c:583 src/fs/gnunet-publish.c:590 +#: src/transport/gnunet-transport.c:560 #, c-format msgid "Option `%s' makes no sense without option `%s'.\n" msgstr "TĂšy chọn ÂŤ %s Âť khĂ´ng cĂł nghÄŠa khi khĂ´ng cĂł tĂšy chọn ÂŤ %s Âť.\n" -#: src/fs/gnunet-publish.c:606 +#: src/fs/gnunet-publish.c:612 #, fuzzy, c-format msgid "Could not create namespace `%s'\n" msgstr "KhĂ´ng thᝃ tấo miᝁn tĂŞn.\n" -#: src/fs/gnunet-publish.c:639 +#: src/fs/gnunet-publish.c:645 #, fuzzy, c-format msgid "Failed to access `%s': %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/fs/gnunet-publish.c:651 +#: src/fs/gnunet-publish.c:657 msgid "" "Failed to start meta directory scanner. Is gnunet-helper-publish-fs " "installed?\n" msgstr "" -#: src/fs/gnunet-publish.c:676 +#: src/fs/gnunet-publish.c:682 msgid "disable adding the creation time to the metadata of the uploaded file" msgstr "tắt thĂŞm giờ tấo vĂ o siĂŞu dᝯ liệu cᝧa táş­p tin đã tải lĂŞn" -#: src/fs/gnunet-publish.c:679 +#: src/fs/gnunet-publish.c:685 msgid "do not use libextractor to add keywords or metadata" msgstr "" -#: src/fs/gnunet-publish.c:683 +#: src/fs/gnunet-publish.c:689 msgid "" "print list of extracted keywords that would be used, but do not perform " "upload" @@ -2627,7 +2672,7 @@ msgstr "" "in ra danh sĂĄch cĂĄc tᝍ khĂła đã giải phĂłng cần sáť­ d᝼ng, nhĆ°ng khĂ´ng tháťąc hiện " "tải lĂŞn" -#: src/fs/gnunet-publish.c:687 +#: src/fs/gnunet-publish.c:693 msgid "" "add an additional keyword for the top-level file or directory (this option " "can be specified multiple times)" @@ -2635,7 +2680,7 @@ msgstr "" "thĂŞm một tᝍ khoĂĄ bổ sung cho táş­p tin hoạc thĆ° m᝼c ở cẼp đầu (cĂł thᝃ chỉ ra " "tĂšy chọn nĂ y nhiᝁu lần)" -#: src/fs/gnunet-publish.c:694 +#: src/fs/gnunet-publish.c:700 msgid "" "do not index, perform full insertion (stores entire file in encrypted form " "in GNUnet database)" @@ -2643,7 +2688,7 @@ msgstr "" "khĂ´ng đánh chỉ m᝼c, tháťąc hiện việc chèn đầy đủ (chᝊa toĂ n bộ táş­p tin ở dấng " "mĂŁ hĂła trong cĆĄ sở dᝯ liệu GNUnet)" -#: src/fs/gnunet-publish.c:699 +#: src/fs/gnunet-publish.c:705 msgid "" "specify ID of an updated version to be published in the future (for " "namespace insertions only)" @@ -2651,16 +2696,16 @@ msgstr "" "chỉ ra mĂŁ số cᝧa một phiĂŞn bản đã cáş­p nháş­t để cĂ´ng bố trong tĆ°ĆĄng lai (chỉ " "cho sáťą chèn khĂ´ng gian tĂŞn)" -#: src/fs/gnunet-publish.c:703 +#: src/fs/gnunet-publish.c:709 msgid "specify the priority of the content" msgstr "xĂĄc định mᝊc Ć°u tiĂŞn cᝧa nội dung" -#: src/fs/gnunet-publish.c:707 +#: src/fs/gnunet-publish.c:713 msgid "publish the files under the pseudonym NAME (place file into namespace)" msgstr "" "cĂ´ng bố cĂĄc táş­p tin dưới biệt hiệu TÊN (đặt táş­p tin vĂ o khĂ´ng gian tĂŞn)" -#: src/fs/gnunet-publish.c:713 +#: src/fs/gnunet-publish.c:719 #, fuzzy msgid "" "only simulate the process but do not do any actual publishing (useful to " @@ -2668,13 +2713,13 @@ msgid "" msgstr "" "chỉ mĂ´ phỏng tiáşżn trĂŹnh, khĂ´ng tháş­t cĂ´ng bố (cĂł Ă­ch để tĂ­nh địa chỉ URI)" -#: src/fs/gnunet-publish.c:717 +#: src/fs/gnunet-publish.c:723 msgid "" "set the ID of this version of the publication (for namespace insertions only)" msgstr "" "đặt mĂŁ số cᝧa phiĂŞn bản nĂ y cᝧa sáťą cĂ´ng bố (chỉ cho chèn khĂ´ng gian tĂŞn)" -#: src/fs/gnunet-publish.c:721 +#: src/fs/gnunet-publish.c:727 msgid "" "URI to be published (can be used instead of passing a file to add keywords " "to the file with the respective URI)" @@ -2682,7 +2727,7 @@ msgstr "" "Địa chỉ URI cần cĂ´ng bố (cĂł thᝃ được dĂšng thay vĂ o gáť­i một táş­p tin để thĂŞm " "tᝍ khoĂĄ vĂ o táş­p tin cĂł địa chỉ URI tĆ°ĆĄng ᝊng)" -#: src/fs/gnunet-publish.c:736 +#: src/fs/gnunet-publish.c:742 msgid "Publish a file or directory on GNUnet" msgstr "" @@ -2733,24 +2778,12 @@ msgid "# Loopback routes suppressed" msgstr "# tổng số định tuyáşżn lỗ hổng thĂ nh cĂ´ng" #: src/fs/gnunet-service-fs.c:581 src/hostlist/gnunet-daemon-hostlist.c:297 -#: src/topology/gnunet-daemon-topology.c:1290 -#: src/topology/gnunet-daemon-topology.c:1297 +#: src/topology/gnunet-daemon-topology.c:1330 +#: src/topology/gnunet-daemon-topology.c:1337 #, fuzzy, c-format msgid "Failed to connect to `%s' service.\n" msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" -#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 -#: src/topology/gnunet-daemon-topology.c:654 -#: src/topology/gnunet-daemon-topology.c:756 -#: src/transport/gnunet-service-transport_neighbours.c:960 -#: src/transport/gnunet-service-transport_neighbours.c:1289 -#: src/transport/gnunet-service-transport_neighbours.c:1841 -#: src/transport/gnunet-service-transport_neighbours.c:2499 -#: src/transport/gnunet-service-transport_neighbours.c:2566 -#, fuzzy -msgid "# peers connected" -msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" - #: src/fs/gnunet-service-fs_cp.c:696 #, fuzzy msgid "# migration stop messages received" @@ -3106,15 +3139,133 @@ msgstr "" msgid "Reply mismatched in terms of namespace. Discarded.\n" msgstr "" -#: src/gns/gns_api.c:221 +#: src/gns/gnunet-gns.c:191 #, fuzzy -msgid "Failed to connect to the GNS service!\n" +msgid "Failed to connect to GNS\n" msgstr "Lỗi káşżt nối đến gnunetd.\n" -#: src/gns/gnunet-gns-lookup.c:210 -msgid "Issue a request to the GNUnet Naming System, prints results." +#: src/gns/gnunet-gns.c:232 +msgid "try to shorten a given GNS name" +msgstr "" + +#: src/gns/gnunet-gns.c:235 +msgid "Lookup a record using GNS (NOT IMPLEMENTED)" +msgstr "" + +#: src/gns/gnunet-gns.c:238 +msgid "Get the authority of a particular name" +msgstr "" + +#: src/gns/gnunet-gns.c:241 +#, fuzzy +msgid "Specify the type of the record lookup" +msgstr "xĂĄc định mᝊc Ć°u tiĂŞn cᝧa nội dung" + +#: src/gns/gnunet-gns.c:244 +msgid "No unneeded output" +msgstr "" + +#: src/gns/gnunet-gns.c:255 +msgid "GNUnet GNS access tool" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:280 +#, fuzzy, c-format +msgid "Unsupported form value `%s'\n" +msgstr "Lệnh khĂ´ng được hỗ trᝣ ÂŤ %s Âť. Đang hᝧy bỏ.\n" + +#: src/gns/gnunet-gns-fcfsd.c:333 +#, fuzzy, c-format +msgid "Failed to create record for domain `%s': %s\n" +msgstr "KhĂ´ng thᝃ truy cáş­p đến táş­p tin gnunet-directory ÂŤ %s Âť\n" + +#: src/gns/gnunet-gns-fcfsd.c:377 +#, c-format +msgid "Found existing name `%s' for the given key\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:439 +#, c-format +msgid "Found %u existing records for domain `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:498 +#, fuzzy, c-format +msgid "Failed to create page for `%s'\n" +msgstr "KhĂ´ng thᝃ tấo miᝁn tĂŞn.\n" + +#: src/gns/gnunet-gns-fcfsd.c:514 +#, fuzzy, c-format +msgid "Failed to setup post processor for `%s'\n" +msgstr "Lỗi cáş­p nháş­t dᝯ liệu cho mĂ´-đun ÂŤ %s Âť\n" + +#: src/gns/gnunet-gns-fcfsd.c:725 src/gns/gnunet-gns-fcfsd.c:737 +#, fuzzy, c-format +msgid "Option `%s' not specified in configuration section `%s'\n" +msgstr "" +"Đạc tả mấng dấng sai trong cẼu hĂŹnh phần ÂŤ %s Âť cho m᝼c nháş­p ÂŤ %s Âť: %s\n" + +#: src/gns/gnunet-gns-fcfsd.c:747 src/namestore/gnunet-namestore.c:299 +#, fuzzy +msgid "Failed to read or create private zone key\n" +msgstr "Lỗi cáş­p nháş­t dᝯ liệu cho mĂ´-đun ÂŤ %s Âť\n" + +#: src/gns/gnunet-gns-fcfsd.c:757 src/namestore/gnunet-namestore.c:310 +#, fuzzy +msgid "Failed to connect to namestore\n" +msgstr "KhĂ´ng káşżt nối được đến trĂŹnh nᝁn gnunetd." + +#: src/gns/gnunet-gns-fcfsd.c:773 src/gns/gnunet-gns-proxy.c:525 +#, fuzzy +msgid "Failed to start HTTP server\n" +msgstr "Lỗi bắt đầu thu tháş­p.\n" + +#: src/gns/gnunet-gns-fcfsd.c:804 +msgid "GNUnet GNS first come first serve registration service" msgstr "" +#: src/gns/gnunet-gns-proxy.c:800 +msgid "listen on specified port" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:811 +msgid "GNUnet GNS proxy" +msgstr "" + +#: src/hello/gnunet-hello.c:122 +msgid "Call with name of HELLO file to modify.\n" +msgstr "" + +#: src/hello/gnunet-hello.c:128 +#, fuzzy, c-format +msgid "Error accessing file `%s': %s\n" +msgstr "Gạp lỗi khi tấo người dĂšng" + +#: src/hello/gnunet-hello.c:136 +#, c-format +msgid "File `%s' is too big to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:143 +#, c-format +msgid "File `%s' is too small to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:153 src/hello/gnunet-hello.c:181 +#, fuzzy, c-format +msgid "Error opening file `%s': %s\n" +msgstr "Gạp lỗi khi tấo người dĂšng" + +#: src/hello/gnunet-hello.c:169 +#, fuzzy, c-format +msgid "Did not find well-formed HELLO in file `%s'\n" +msgstr "KhĂ´ng tĂŹm thẼy táş­p tin nĂ o trong thĆ° m᝼c ÂŤ %s Âť\n" + +#: src/hello/gnunet-hello.c:193 +#, fuzzy, c-format +msgid "Error writing HELLO to file `%s': %s\n" +msgstr "Gạp lỗi khi tấo người dĂšng" + #: src/hostlist/gnunet-daemon-hostlist.c:264 msgid "" "None of the functions for the hostlist daemon were enabled. I have no " @@ -3146,199 +3297,199 @@ msgstr "trĂŹnh ph᝼c v᝼ danh sĂĄch mĂĄy HTTP hᝣp nhẼt" msgid "GNUnet hostlist server and client" msgstr "" -#: src/hostlist/hostlist-client.c:286 +#: src/hostlist/hostlist-client.c:289 #, fuzzy msgid "# bytes downloaded from hostlist servers" msgstr "trĂŹnh ph᝼c v᝼ danh sĂĄch mĂĄy HTTP hᝣp nhẼt" -#: src/hostlist/hostlist-client.c:307 src/hostlist/hostlist-client.c:339 +#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:340 #, fuzzy msgid "# invalid HELLOs downloaded from hostlist servers" msgstr "# cĂĄc HELLO tải xuống qua HTTP" -#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:342 +#: src/hostlist/hostlist-client.c:313 src/hostlist/hostlist-client.c:343 #, fuzzy, c-format msgid "Invalid `%s' message received from hostlist at `%s'\n" msgstr "Nháş­n được thĂ´ng bĂĄo ÂŤ %s Âť sai tᝍ đồng đẳng ÂŤ %s Âť.\n" -#: src/hostlist/hostlist-client.c:330 +#: src/hostlist/hostlist-client.c:331 #, fuzzy msgid "# valid HELLOs downloaded from hostlist servers" msgstr "# cĂĄc HELLO tải xuống qua HTTP" -#: src/hostlist/hostlist-client.c:374 src/hostlist/hostlist-client.c:395 +#: src/hostlist/hostlist-client.c:375 src/hostlist/hostlist-client.c:396 #, fuzzy, c-format msgid "No `%s' specified in `%s' configuration, will not bootstrap.\n" msgstr "" "ChĆ°a ghi rĂľ địa chỉ URL cᝧa danh sĂĄch cĂĄc mĂĄy nĂŞn khĂ´ng nấp vĂ  khởi động.\n" -#: src/hostlist/hostlist-client.c:472 src/hostlist/hostlist-client.c:682 -#: src/hostlist/hostlist-client.c:688 src/hostlist/hostlist-client.c:740 -#: src/hostlist/hostlist-client.c:749 src/hostlist/hostlist-client.c:877 -#: src/hostlist/hostlist-client.c:967 src/hostlist/hostlist-client.c:972 -#: src/transport/plugin_transport_http_client.c:108 -#: src/transport/plugin_transport_http_client.c:123 +#: src/hostlist/hostlist-client.c:473 src/hostlist/hostlist-client.c:683 +#: src/hostlist/hostlist-client.c:689 src/hostlist/hostlist-client.c:741 +#: src/hostlist/hostlist-client.c:750 src/hostlist/hostlist-client.c:871 +#: src/hostlist/hostlist-client.c:961 src/hostlist/hostlist-client.c:966 +#: src/transport/plugin_transport_http_client.c:110 +#: src/transport/plugin_transport_http_client.c:125 #, c-format msgid "%s failed at %s:%d: `%s'\n" msgstr "%s bị lỗi tấi %s:%d: ÂŤ %s Âť\n" -#: src/hostlist/hostlist-client.c:592 src/hostlist/hostlist-client.c:1342 +#: src/hostlist/hostlist-client.c:593 src/hostlist/hostlist-client.c:1331 msgid "# advertised hostlist URIs" msgstr "" -#: src/hostlist/hostlist-client.c:622 +#: src/hostlist/hostlist-client.c:623 #, c-format msgid "# advertised URI `%s' downloaded" msgstr "" -#: src/hostlist/hostlist-client.c:663 +#: src/hostlist/hostlist-client.c:664 #, c-format msgid "" "Advertised hostlist with URI `%s' could not be downloaded. Advertised URI " "gets dismissed.\n" msgstr "" -#: src/hostlist/hostlist-client.c:805 +#: src/hostlist/hostlist-client.c:802 #, fuzzy, c-format msgid "Timeout trying to download hostlist from `%s'\n" msgstr "Đang tháť­ tải danh sĂĄch cĂĄc mĂĄy xuống ÂŤ %s Âť\n" -#: src/hostlist/hostlist-client.c:822 +#: src/hostlist/hostlist-client.c:816 #, c-format msgid "Download limit of %u bytes exceeded, stopping download\n" msgstr "" -#: src/hostlist/hostlist-client.c:842 +#: src/hostlist/hostlist-client.c:836 #, fuzzy, c-format -msgid "%s failed for `%s' at %s:%d: `%s'\n" -msgstr "%s bị lỗi tấi %s:%d: ÂŤ %s Âť\n" +msgid "Download of hostlist from `%s' failed: `%s'\n" +msgstr "Tải lĂŞn ÂŤ %s Âť hoĂ n thĂ nh, địa chỉ URI lĂ  ÂŤ %s Âť.\n" -#: src/hostlist/hostlist-client.c:848 +#: src/hostlist/hostlist-client.c:842 #, fuzzy, c-format msgid "Download of hostlist `%s' completed.\n" msgstr "Tải lĂŞn ÂŤ %s Âť hoĂ n thĂ nh, địa chỉ URI lĂ  ÂŤ %s Âť.\n" -#: src/hostlist/hostlist-client.c:856 +#: src/hostlist/hostlist-client.c:850 #, c-format msgid "Adding successfully tested hostlist `%s' datastore.\n" msgstr "" -#: src/hostlist/hostlist-client.c:909 +#: src/hostlist/hostlist-client.c:903 #, fuzzy, c-format msgid "Bootstrapping using hostlist at `%s'.\n" msgstr "Đang nấp vĂ  khởi động dĂšng ÂŤ %s Âť.\n" -#: src/hostlist/hostlist-client.c:917 +#: src/hostlist/hostlist-client.c:911 msgid "# hostlist downloads initiated" msgstr "" -#: src/hostlist/hostlist-client.c:1045 src/hostlist/hostlist-client.c:1515 +#: src/hostlist/hostlist-client.c:1037 src/hostlist/hostlist-client.c:1505 msgid "# milliseconds between hostlist downloads" msgstr "" -#: src/hostlist/hostlist-client.c:1054 +#: src/hostlist/hostlist-client.c:1046 #, c-format msgid "Have %u/%u connections. Will consider downloading hostlist in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1092 +#: src/hostlist/hostlist-client.c:1084 msgid "Scheduled saving of hostlists\n" msgstr "" -#: src/hostlist/hostlist-client.c:1096 +#: src/hostlist/hostlist-client.c:1088 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1119 src/hostlist/hostlist-client.c:1135 +#: src/hostlist/hostlist-client.c:1111 src/hostlist/hostlist-client.c:1127 #, fuzzy msgid "# active connections" msgstr "# cĂĄc káşżt nối dht" -#: src/hostlist/hostlist-client.c:1253 +#: src/hostlist/hostlist-client.c:1242 #, c-format msgid "Initial time between hostlist downloads is %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1284 +#: src/hostlist/hostlist-client.c:1273 #, fuzzy, c-format msgid "" "No `%s' specified in `%s' configuration, cannot load hostlists from file.\n" msgstr "" "ChĆ°a ghi rĂľ địa chỉ URL cᝧa danh sĂĄch cĂĄc mĂĄy nĂŞn khĂ´ng nấp vĂ  khởi động.\n" -#: src/hostlist/hostlist-client.c:1290 +#: src/hostlist/hostlist-client.c:1279 #, fuzzy, c-format msgid "Loading saved hostlist entries from file `%s' \n" msgstr "Đang tháť­ tải danh sĂĄch cĂĄc mĂĄy xuống ÂŤ %s Âť\n" -#: src/hostlist/hostlist-client.c:1294 +#: src/hostlist/hostlist-client.c:1283 #, c-format msgid "Hostlist file `%s' is not existing\n" msgstr "" -#: src/hostlist/hostlist-client.c:1305 +#: src/hostlist/hostlist-client.c:1294 #, fuzzy, c-format msgid "Could not open file `%s' for reading to load hostlists: %s\n" msgstr "Lỗi mở táş­p tin theo dĂľi ÂŤ %s Âť: %s\n" -#: src/hostlist/hostlist-client.c:1338 +#: src/hostlist/hostlist-client.c:1327 #, c-format msgid "%u hostlist URIs loaded from file\n" msgstr "" -#: src/hostlist/hostlist-client.c:1340 +#: src/hostlist/hostlist-client.c:1329 #, fuzzy msgid "# hostlist URIs read from file" msgstr "# cĂĄc byte danh sĂĄch mĂĄy được trả vᝁ" -#: src/hostlist/hostlist-client.c:1373 +#: src/hostlist/hostlist-client.c:1362 #, fuzzy, c-format msgid "" "No `%s' specified in `%s' configuration, cannot save hostlists to file.\n" msgstr "" "ChĆ°a ghi rĂľ địa chỉ URL cᝧa danh sĂĄch cĂĄc mĂĄy nĂŞn khĂ´ng nấp vĂ  khởi động.\n" -#: src/hostlist/hostlist-client.c:1387 +#: src/hostlist/hostlist-client.c:1376 #, fuzzy, c-format msgid "Could not open file `%s' for writing to save hostlists: %s\n" msgstr "Lỗi mở táş­p tin theo dĂľi ÂŤ %s Âť: %s\n" -#: src/hostlist/hostlist-client.c:1392 +#: src/hostlist/hostlist-client.c:1381 #, fuzzy, c-format msgid "Writing %u hostlist URIs to `%s'\n" msgstr "Đang tháť­ tải danh sĂĄch cĂĄc mĂĄy xuống ÂŤ %s Âť\n" -#: src/hostlist/hostlist-client.c:1416 src/hostlist/hostlist-client.c:1433 +#: src/hostlist/hostlist-client.c:1405 src/hostlist/hostlist-client.c:1422 #, c-format msgid "Error writing hostlist URIs to file `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:1428 +#: src/hostlist/hostlist-client.c:1417 #, fuzzy msgid "# hostlist URIs written to file" msgstr "# cĂĄc byte danh sĂĄch mĂĄy được trả vᝁ" -#: src/hostlist/hostlist-client.c:1480 +#: src/hostlist/hostlist-client.c:1470 msgid "Learning is enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1483 +#: src/hostlist/hostlist-client.c:1473 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1492 +#: src/hostlist/hostlist-client.c:1482 msgid "Learning is not enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1504 +#: src/hostlist/hostlist-client.c:1494 #, c-format msgid "" "Since learning is not enabled on this peer, hostlist file `%s' was removed\n" msgstr "" -#: src/hostlist/hostlist-client.c:1508 +#: src/hostlist/hostlist-client.c:1498 #, fuzzy, c-format msgid "Hostlist file `%s' could not be removed\n" msgstr "KhoĂĄ phiĂŞn chấy tᝍ đồng đẳng ÂŤ %s Âť khĂ´ng thᝃ được thẊm tra.\n" @@ -3352,8 +3503,10 @@ msgstr "# cĂĄc byte trong kho dᝯ liệu" msgid "expired addresses encountered" msgstr "" -#: src/hostlist/hostlist-server.c:184 -#: src/topology/gnunet-daemon-topology.c:875 +#: src/hostlist/hostlist-server.c:184 src/hostlist/hostlist-server.c:425 +#: src/peerinfo-tool/gnunet-peerinfo.c:403 +#: src/peerinfo-tool/gnunet-peerinfo.c:519 +#: src/topology/gnunet-daemon-topology.c:927 #, fuzzy, c-format msgid "Error in communication with PEERINFO service: %s\n" msgstr "Cổng để liĂŞn lấc với giao diện người dĂšng GNUnet" @@ -3362,188 +3515,402 @@ msgstr "Cổng để liĂŞn lấc với giao diện người dĂšng GNUnet" msgid "HELLOs without addresses encountered (ignored)" msgstr "" -#: src/hostlist/hostlist-server.c:221 +#: src/hostlist/hostlist-server.c:219 msgid "bytes not included in hostlist (size limit)" msgstr "" -#: src/hostlist/hostlist-server.c:269 +#: src/hostlist/hostlist-server.c:263 #, fuzzy, c-format msgid "Refusing `%s' request to hostlist server\n" msgstr "trĂŹnh ph᝼c v᝼ danh sĂĄch mĂĄy HTTP hᝣp nhẼt" -#: src/hostlist/hostlist-server.c:272 +#: src/hostlist/hostlist-server.c:266 #, fuzzy msgid "hostlist requests refused (not HTTP GET)" msgstr "# cĂĄc yĂŞu cầu danh sĂĄch mĂĄy được nháş­n" -#: src/hostlist/hostlist-server.c:280 +#: src/hostlist/hostlist-server.c:273 msgid "Sending 100 CONTINUE reply\n" msgstr "" -#: src/hostlist/hostlist-server.c:287 +#: src/hostlist/hostlist-server.c:279 #, c-format msgid "Refusing `%s' request with %llu bytes of upload data\n" msgstr "" -#: src/hostlist/hostlist-server.c:291 +#: src/hostlist/hostlist-server.c:283 #, fuzzy msgid "hostlist requests refused (upload data)" msgstr "# cĂĄc yĂŞu cầu danh sĂĄch mĂĄy được nháş­n" -#: src/hostlist/hostlist-server.c:299 +#: src/hostlist/hostlist-server.c:291 msgid "Could not handle hostlist request since I do not have a response yet\n" msgstr "" -#: src/hostlist/hostlist-server.c:302 +#: src/hostlist/hostlist-server.c:294 #, fuzzy msgid "hostlist requests refused (not ready)" msgstr "# cĂĄc yĂŞu cầu danh sĂĄch mĂĄy được nháş­n" -#: src/hostlist/hostlist-server.c:306 +#: src/hostlist/hostlist-server.c:298 #, fuzzy msgid "Received request for our hostlist\n" msgstr "Nháş­n yĂŞu cầu định tuyáşżn\n" -#: src/hostlist/hostlist-server.c:307 +#: src/hostlist/hostlist-server.c:299 #, fuzzy msgid "hostlist requests processed" msgstr "# cĂĄc yĂŞu cầu danh sĂĄch mĂĄy được nháş­n" -#: src/hostlist/hostlist-server.c:350 +#: src/hostlist/hostlist-server.c:341 #, fuzzy msgid "# hostlist advertisements send" msgstr "# CĂĄc quảng cĂĄo ngoấi được chuyᝃn tiáşżp" -#: src/hostlist/hostlist-server.c:397 +#: src/hostlist/hostlist-server.c:388 msgid "Advertisement message could not be queued by core\n" msgstr "" -#: src/hostlist/hostlist-server.c:565 +#: src/hostlist/hostlist-server.c:561 #, c-format msgid "Invalid port number %llu. Exiting.\n" msgstr "" -#: src/hostlist/hostlist-server.c:574 +#: src/hostlist/hostlist-server.c:570 #, c-format msgid "Hostlist service starts on %s:%llu\n" msgstr "" -#: src/hostlist/hostlist-server.c:588 +#: src/hostlist/hostlist-server.c:584 #, fuzzy, c-format msgid "Address to obtain hostlist: `%s'\n" msgstr "Đang tháť­ tải danh sĂĄch cĂĄc mĂĄy xuống ÂŤ %s Âť\n" -#: src/hostlist/hostlist-server.c:626 +#: src/hostlist/hostlist-server.c:624 +#, fuzzy, c-format +msgid "`%s' is not a valid IP address! Ignoring BINDTOIP.\n" +msgstr "ÂŤ %s Âť khĂ´ng sáşľn sĂ ng.\n" + +#: src/hostlist/hostlist-server.c:666 #, fuzzy, c-format msgid "Could not start hostlist HTTP server on port %u\n" msgstr "Cổng cho trĂŹnh ph᝼c v᝼ HTTP danh sĂĄch mĂĄy chᝧ thống nhẼt" -#: src/mesh/gnunet-service-mesh.c:4595 +#: src/integration-tests/connection_watchdog.c:997 +#, fuzzy, c-format +msgid "Transport plugin: `%s' port %llu\n" +msgstr "Đang nấp cĂĄc truyᝁn tải ÂŤ %s Âť\n" + +#: src/integration-tests/connection_watchdog.c:1030 +#, fuzzy, c-format +msgid "Found %u transport plugins: `%s'\n" +msgstr "Đang nấp cĂĄc truyᝁn tải ÂŤ %s Âť\n" + +#: src/integration-tests/connection_watchdog.c:1089 +msgid "Send ping messages to test connectivity (default == NO)" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1095 +#: src/template/gnunet-template.c:68 +msgid "help text" +msgstr "" + +#: src/mesh/gnunet-service-mesh.c:4590 msgid "Wrong CORE service\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4789 +#: src/mesh/gnunet-service-mesh.c:4784 #, fuzzy msgid "Mesh service is lacking key configuration settings. Exiting.\n" msgstr "LĆ°u cẼu hĂŹnh ngay bây giờ khĂ´ng?" -#: src/mesh/gnunet-service-mesh.c:4798 +#: src/mesh/gnunet-service-mesh.c:4793 #, fuzzy msgid "Mesh service could not access hostkey. Exiting.\n" msgstr "KhĂ´ng thᝃ truy cáş­p đến thĂ´ng tin vᝁ khĂ´ng gian tĂŞn.\n" -#: src/namestore/namestore_api.c:272 src/namestore/namestore_api.c:313 -msgid "Namestore added record successfully" -msgstr "" - -#: src/namestore/namestore_api.c:281 src/namestore/namestore_api.c:322 -msgid "Namestore failed to add record" -msgstr "" - -#: src/nat/gnunet-nat-server.c:289 +#: src/mysql/mysql.c:174 #, c-format -msgid "Please pass valid port number as the first argument! (got `%s')\n" -msgstr "" - -#: src/nat/gnunet-nat-server.c:328 -msgid "GNUnet NAT traversal test helper daemon" -msgstr "" +msgid "Trying to use file `%s' for MySQL configuration.\n" +msgstr "Đang tháť­ dĂšng táş­p tin ÂŤ %s Âť cho cẼu hĂŹnh MySQL.\n" -#: src/nat/nat.c:803 -#, c-format -msgid "gnunet-helper-nat-server generated malformed address `%s'\n" -msgstr "" +#: src/mysql/mysql.c:181 +#, fuzzy, c-format +msgid "Could not access file `%s': %s\n" +msgstr "KhĂ´ng thᝃ truy cáş­p đến ÂŤ %s Âť: %s\n" -#: src/nat/nat.c:852 +#: src/namestore/gnunet-namestore.c:157 #, fuzzy, c-format -msgid "Failed to start %s\n" -msgstr "Lỗi bắt đầu thu tháş­p.\n" +msgid "Adding record failed: %s\n" +msgstr "Gạp lỗi khi tải lĂŞn táş­p tin: %s\n" -#: src/nat/nat.c:1121 +#: src/namestore/gnunet-namestore.c:183 #, fuzzy, c-format -msgid "Malformed %s `%s' given in configuration!\n" -msgstr "Lỗi lĆ°u cẼu hĂŹnh." +msgid "Deleting record failed: %s\n" +msgstr "Gạp lỗi khi tải lĂŞn táş­p tin: %s\n" -#: src/nat/nat.c:1187 src/nat/nat.c:1197 +#: src/namestore/gnunet-namestore.c:239 #, c-format -msgid "" -"Configuration requires `%s', but binary is not installed properly (SUID bit " -"not set). Option disabled.\n" +msgid "\tCorrupt or unsupported record of type %u\n" msgstr "" -#: src/nat/nat.c:1329 -msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" -msgstr "" - -#: src/nat/nat.c:1341 +#: src/namestore/gnunet-namestore.c:276 #, c-format -msgid "Running gnunet-helper-nat-client %s %s %u\n" +msgid "Option `%s' not given, but I need a zone key file!\n" msgstr "" -#: src/nat/nat_test.c:348 +#: src/namestore/gnunet-namestore.c:281 +#, fuzzy, c-format +msgid "Using default zone file `%s'\n" +msgstr "Đang bắt đầu tĂ i vᝁ ÂŤ %s Âť\n" + +#: src/namestore/gnunet-namestore.c:291 +#, fuzzy, c-format +msgid "No options given\n" +msgstr "chĆ°a đưa ra tĂŞn" + +#: src/namestore/gnunet-namestore.c:321 +#, fuzzy, c-format +msgid "Unsupported type `%s'\n" +msgstr "Lệnh khĂ´ng được hỗ trᝣ ÂŤ %s Âť. Đang hᝧy bỏ.\n" + +#: src/namestore/gnunet-namestore.c:328 src/namestore/gnunet-namestore.c:350 +#: src/namestore/gnunet-namestore.c:374 src/namestore/gnunet-namestore.c:384 +#: src/namestore/gnunet-namestore.c:409 +#, fuzzy, c-format +msgid "Missing option `%s' for operation `%s'\n" +msgstr "GiĂĄ trị cẼu hĂŹnh ÂŤ %s Âť cho ÂŤ %s Âť trong phần ÂŤ %s Âť nĂŞn lĂ  con số\n" + +#: src/namestore/gnunet-namestore.c:329 src/namestore/gnunet-namestore.c:351 +msgid "add/del" +msgstr "" + +#: src/namestore/gnunet-namestore.c:341 +#, c-format +msgid "Value `%s' invalid for record type `%s'\n" +msgstr "" + +#: src/namestore/gnunet-namestore.c:366 +#, fuzzy, c-format +msgid "Invalid time format `%s'\n" +msgstr "Địa chỉ IP định dấng sai: %s\n" + +#: src/namestore/gnunet-namestore.c:375 src/namestore/gnunet-namestore.c:385 +msgid "add" +msgstr "" + +#: src/namestore/gnunet-namestore.c:410 +msgid "del" +msgstr "" + +#: src/namestore/gnunet-namestore.c:462 +msgid "add record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:465 +msgid "delete record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:468 +msgid "display records" +msgstr "" + +#: src/namestore/gnunet-namestore.c:471 +msgid "" +"expiration time for record to use (for adding only), \"never\" is possible" +msgstr "" + +#: src/namestore/gnunet-namestore.c:474 +msgid "name of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:477 +msgid "type of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:480 +msgid "value of the record to add/delete" +msgstr "" + +#: src/namestore/gnunet-namestore.c:483 +msgid "create or list public record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:486 +msgid "create or list non-authority record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:489 +#, fuzzy +msgid "filename with the zone key" +msgstr "tĂŞn táş­p tin" + +#: src/namestore/gnunet-namestore.c:500 +#, fuzzy +msgid "GNUnet zone manipulation tool" +msgstr "CẼu hĂŹnh GNUnet" + +#: src/namestore/gnunet-service-namestore.c:143 +#, c-format +msgid "File zone `%s' but corrupt content already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:154 +#, c-format +msgid "File zone `%s' containing this key already exists\n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:160 +#, c-format +msgid "" +"File zone `%s' but different zone key already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:198 +#, fuzzy, c-format +msgid "Stored zonekey for zone `%s' in file `%s'\n" +msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" + +#: src/namestore/gnunet-service-namestore.c:1909 +msgid "No directory to load zonefiles specified in configuration\n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:1918 +#, c-format +msgid "Creating directory `%s' for zone files failed!\n" +msgstr "" + +#: src/namestore/namestore_api.c:315 src/namestore/namestore_api.c:353 +msgid "Namestore added record successfully" +msgstr "" + +#: src/namestore/namestore_api.c:323 +msgid "Namestore failed to add record" +msgstr "" + +#: src/namestore/namestore_api.c:361 +msgid "Namestore record already existed" +msgstr "" + +#: src/namestore/namestore_api.c:368 +msgid "Namestore failed to add record\n" +msgstr "" + +#: src/namestore/namestore_api.c:401 +#, fuzzy +msgid "Namestore removed record successfully" +msgstr "Dịch v᝼ GNUnet đã được cĂ i đặt.\n" + +#: src/namestore/namestore_api.c:408 +msgid "No records for entry" +msgstr "" + +#: src/namestore/namestore_api.c:415 +#, fuzzy +msgid "Could not find record to remove" +msgstr "KhĂ´ng thᝃ káşżt nối tới %s:%u: %s\n" + +#: src/namestore/namestore_api.c:422 +#, fuzzy +msgid "Failed to create new signature" +msgstr "KhĂ´ng thᝃ tấo miᝁn tĂŞn.\n" + +#: src/namestore/namestore_api.c:429 +#, fuzzy +msgid "Failed to put new set of records in database" +msgstr "" +"\n" +"KhĂ´ng nháş­n được đáp ᝊng tᝍ gnunetd.\n" + +#: src/nat/gnunet-nat-server.c:279 +#, c-format +msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgstr "" + +#: src/nat/gnunet-nat-server.c:318 +msgid "GNUnet NAT traversal test helper daemon" +msgstr "" + +#: src/nat/nat.c:799 +#, c-format +msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgstr "" + +#: src/nat/nat.c:844 +#, fuzzy, c-format +msgid "Failed to start %s\n" +msgstr "Lỗi bắt đầu thu tháş­p.\n" + +#: src/nat/nat.c:1111 +#, fuzzy, c-format +msgid "Malformed %s `%s' given in configuration!\n" +msgstr "Lỗi lĆ°u cẼu hĂŹnh." + +#: src/nat/nat.c:1177 src/nat/nat.c:1187 +#, c-format +msgid "" +"Configuration requires `%s', but binary is not installed properly (SUID bit " +"not set). Option disabled.\n" +msgstr "" + +#: src/nat/nat.c:1321 +msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" +msgstr "" + +#: src/nat/nat.c:1332 +#, c-format +msgid "Running gnunet-helper-nat-client %s %s %u\n" +msgstr "" + +#: src/nat/nat_test.c:341 #, fuzzy msgid "Failed to connect to `gnunet-nat-server'\n" msgstr "Lỗi káşżt nối đến gnunetd.\n" -#: src/nat/nat_test.c:418 +#: src/nat/nat_test.c:411 #, c-format msgid "Failed to create listen socket bound to `%s' for NAT test: %s\n" msgstr "" -#: src/nse/gnunet-nse-profiler.c:926 +#: src/nse/gnunet-nse-profiler.c:928 #, fuzzy msgid "Measure quality and performance of the NSE service." msgstr "KhĂ´ng thᝃ truy cáş­p đến dịch v᝼" -#: src/nse/gnunet-service-nse.c:936 +#: src/nse/gnunet-service-nse.c:925 #, c-format msgid "Proof of work invalid: %llu!\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1391 src/nse/gnunet-service-nse.c:1410 -#: src/nse/gnunet-service-nse.c:1431 +#: src/nse/gnunet-service-nse.c:1381 src/nse/gnunet-service-nse.c:1400 +#: src/nse/gnunet-service-nse.c:1421 msgid "NSE service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1398 +#: src/nse/gnunet-service-nse.c:1388 msgid "Invalid work requirement for NSE service. Exiting.\n" msgstr "" -#: src/nse/gnunet-service-nse.c:1419 +#: src/nse/gnunet-service-nse.c:1409 #, fuzzy msgid "NSE service could not access hostkey. Exiting.\n" msgstr "KhĂ´ng thᝃ truy cáş­p đến thĂ´ng tin vᝁ khĂ´ng gian tĂŞn.\n" -#: src/peerinfo/gnunet-service-peerinfo.c:133 +#: src/peerinfo/gnunet-service-peerinfo.c:134 #, fuzzy, c-format msgid "Removing expired address of transport `%s'\n" msgstr "Đã nấp truyᝁn tải ÂŤ %s Âť\n" -#: src/peerinfo/gnunet-service-peerinfo.c:195 +#: src/peerinfo/gnunet-service-peerinfo.c:203 +#, fuzzy, c-format +msgid "Failed to parse HELLO in file `%s'\n" +msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" + +#: src/peerinfo/gnunet-service-peerinfo.c:229 msgid "# peers known" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:239 +#: src/peerinfo/gnunet-service-peerinfo.c:254 #, c-format msgid "" "File `%s' in directory `%s' does not match naming convention. Removed.\n" @@ -3551,69 +3918,169 @@ msgstr "" "Táş­p tin ÂŤ %s Âť trong thĆ° m᝼c ÂŤ %s Âť khĂ´ng tĂšy theo quy ước đặt tĂŞn. Bị gᝥ " "bỏ.\n" -#: src/peerinfo/gnunet-service-peerinfo.c:305 +#: src/peerinfo/gnunet-service-peerinfo.c:353 #, c-format msgid "Still no peers found in `%s'!\n" msgstr "Vẍn còn khĂ´ng tĂŹm thẼy đồng đẳng trong ÂŤ %s Âť.\n" -#: src/peerinfo/peerinfo_api.c:279 -#, fuzzy, c-format -msgid "Failed to transmit message to `%s' service.\n" -msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" +#: src/peerinfo/gnunet-service-peerinfo.c:710 +#, c-format +msgid "Importing HELLOs from `%s'\n" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:238 +msgid "aborted due to explicit disconnect request" +msgstr "" + +#: src/peerinfo/peerinfo_api.c:358 +#, fuzzy +msgid "failed to transmit request (service down?)" +msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/peerinfo/peerinfo_api.c:435 +#: src/peerinfo/peerinfo_api.c:505 #, fuzzy msgid "Failed to receive response from `PEERINFO' service." msgstr "" "\n" "KhĂ´ng nháş­n được đáp ᝊng tᝍ gnunetd.\n" -#: src/peerinfo/peerinfo_api.c:463 src/peerinfo/peerinfo_api.c:481 -msgid "Received invalid message from `PEERINFO' service.\n" +#: src/peerinfo/peerinfo_api.c:531 src/peerinfo/peerinfo_api.c:550 +#: src/peerinfo/peerinfo_api.c:565 src/peerinfo/peerinfo_api.c:576 +#: src/peerinfo/peerinfo_api.c:587 +#, fuzzy +msgid "Received invalid message from `PEERINFO' service." msgstr "" +"\n" +"KhĂ´ng nháş­n được đáp ᝊng tᝍ gnunetd.\n" -#: src/peerinfo/peerinfo_api.c:523 +#: src/peerinfo/peerinfo_api.c:663 #, fuzzy -msgid "Failed to transmit iteration request to `PEERINFO' service\n" +msgid "Timeout transmitting iteration request to `PEERINFO' service." msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" -#: src/peerinfo/peerinfo_api.c:557 -msgid "Timeout transmitting iteration request to `PEERINFO' service.\n" -msgstr "" - -#: src/peerinfo/peerinfo_api_notify.c:258 +#: src/peerinfo/peerinfo_api_notify.c:256 #, fuzzy, c-format msgid "Could not connect to `%s' service.\n" msgstr "KhĂ´ng thᝃ káşżt nối tới %s:%u: %s\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:216 +#: src/peerinfo-tool/gnunet-peerinfo.c:581 +#, fuzzy +msgid "Failed to parse HELLO message: missing expiration time\n" +msgstr "Lỗi lĆ°u cẼu hĂŹnh." + +#: src/peerinfo-tool/gnunet-peerinfo.c:589 +#, fuzzy +msgid "Failed to parse HELLO message: invalid expiration time\n" +msgstr "Lỗi lĆ°u cẼu hĂŹnh." + +#: src/peerinfo-tool/gnunet-peerinfo.c:598 +#, fuzzy +msgid "Failed to parse HELLO message: malformed\n" +msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:608 +#, fuzzy +msgid "Failed to parse HELLO message: missing transport plugin\n" +msgstr "KhĂ´ng thᝃ nấp phần bổ sung truyᝁn tải ÂŤ %s Âť\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:625 +#, c-format +msgid "Plugin `%s' not found\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:634 +#, c-format +msgid "Plugin `%s' does not support URIs yet\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:653 +#, fuzzy, c-format +msgid "Failed to parse `%s' as an address for plugin `%s'\n" +msgstr "Lỗi đóng káşżt đến cổng %s %d.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:685 +#, c-format +msgid "Failure adding HELLO: %s\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:833 #, fuzzy, c-format msgid "Could not find option `%s:%s' in configuration.\n" msgstr "KhĂ´ng tĂŹm thẼy phĆ°ĆĄng phĂĄp ÂŤ %s%s Âť trong thĆ° viện ÂŤ %s Âť.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:223 +#: src/peerinfo-tool/gnunet-peerinfo.c:840 #, c-format msgid "Loading hostkey from `%s' failed.\n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:235 +#: src/peerinfo-tool/gnunet-peerinfo.c:875 +#, fuzzy, c-format +msgid "Invalid URI `%s'\n" +msgstr "Dᝯ liệu nháş­p khĂ´ng hᝣp lệ.\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:899 #, c-format msgid "I am peer `%s'.\n" msgstr "TĂ´i lĂ  đồng đẳng ÂŤ %s Âť.\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:255 +#: src/peerinfo-tool/gnunet-peerinfo.c:936 +msgid "don't resolve host names" +msgstr "khĂ´ng quyáşżt định cĂĄc tĂŞn mĂĄy" + +#: src/peerinfo-tool/gnunet-peerinfo.c:939 msgid "output only the identity strings" msgstr "chỉ xuẼt nhᝯng chuỗi nháş­n diện" -#: src/peerinfo-tool/gnunet-peerinfo.c:258 +#: src/peerinfo-tool/gnunet-peerinfo.c:942 msgid "output our own identity only" msgstr "chỉ xuẼt nháş­n diện mĂŹnh" -#: src/peerinfo-tool/gnunet-peerinfo.c:264 +#: src/peerinfo-tool/gnunet-peerinfo.c:945 +#, fuzzy +msgid "list all known peers" +msgstr "liệt kĂŞ mọi bộ tiáşżp hᝣp mấng" + +#: src/peerinfo-tool/gnunet-peerinfo.c:948 +msgid "also output HELLO uri(s)" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:951 +msgid "add given HELLO uri to the database" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:957 #, fuzzy msgid "Print information about peers." msgstr "In ra thĂ´ng tin vᝁ cĂĄc đồng đẳng GNUnet." +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:105 +#: src/transport/gnunet-service-transport_plugins.c:118 +#, fuzzy, c-format +msgid "Starting transport plugins `%s'\n" +msgstr "Đang nấp cĂĄc truyᝁn tải ÂŤ %s Âť\n" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:109 +#: src/transport/gnunet-service-transport_plugins.c:122 +#, fuzzy, c-format +msgid "Loading `%s' transport plugin\n" +msgstr "Đang nấp cĂĄc truyᝁn tải ÂŤ %s Âť\n" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:129 +#: src/transport/gnunet-service-transport_plugins.c:150 +#, fuzzy, c-format +msgid "Failed to load transport plugin for `%s'\n" +msgstr "KhĂ´ng thᝃ nấp phần bổ sung truyᝁn tải ÂŤ %s Âť\n" + +#: src/postgres/postgres.c:59 +#, fuzzy, c-format +msgid "`%s:%s' failed at %s:%d with error: %s" +msgstr "ÂŤ %s Âť bị lỗi tấi %s:%d với lỗi: %s" + +#: src/postgres/postgres.c:148 +#, fuzzy, c-format +msgid "Unable to initialize Postgres: %s" +msgstr "KhĂ´ng thᝃ sĆĄ khởi SQLite: %s.\n" + #: src/pt/gnunet-daemon-pt.c:264 msgid "Failed to pack DNS request. Dropping.\n" msgstr "" @@ -3680,48 +4147,64 @@ msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" msgid "Daemon to run to perform IP protocol translation to GNUnet" msgstr "" -#: src/statistics/gnunet-service-statistics.c:209 +#: src/statistics/gnunet-service-statistics.c:271 #, fuzzy, c-format msgid "Loading %llu bytes of statistics from `%s'\n" msgstr "Đã tải %llu byte xuống ÂŤ %s Âť.\n" -#: src/statistics/gnunet-service-statistics.c:267 +#: src/statistics/gnunet-service-statistics.c:330 #, fuzzy, c-format msgid "Wrote %llu bytes of statistics to `%s'\n" msgstr "Đã tải %llu byte xuống ÂŤ %s Âť.\n" -#: src/statistics/gnunet-statistics.c:98 +#: src/statistics/gnunet-statistics.c:122 #, fuzzy msgid "Failed to obtain statistics.\n" msgstr "Lỗi lẼy thĂ´ng kĂŞ vᝁ truyᝁn tải.\n" -#: src/statistics/gnunet-statistics.c:164 +#: src/statistics/gnunet-statistics.c:199 +#, fuzzy, c-format +msgid "No subsystem or name given\n" +msgstr "chĆ°a đưa ra tĂŞn" + +#: src/statistics/gnunet-statistics.c:207 +#, fuzzy, c-format +msgid "Failed to initialize watch routine\n" +msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" + +#: src/statistics/gnunet-statistics.c:227 msgid "limit output to statistics for the given NAME" msgstr "" -#: src/statistics/gnunet-statistics.c:167 +#: src/statistics/gnunet-statistics.c:230 msgid "make the value being set persistent" msgstr "" -#: src/statistics/gnunet-statistics.c:170 +#: src/statistics/gnunet-statistics.c:233 msgid "limit output to the given SUBSYSTEM" msgstr "" -#: src/statistics/gnunet-statistics.c:173 +#: src/statistics/gnunet-statistics.c:236 msgid "just print the statistics value" msgstr "" -#: src/statistics/gnunet-statistics.c:180 +#: src/statistics/gnunet-statistics.c:239 +msgid "watch value continously" +msgstr "" + +#: src/statistics/gnunet-statistics.c:246 msgid "Print statistics about GNUnet operations." msgstr "In ra thống kĂŞ vᝁ cĂĄc thao tĂĄc GNUnet." -#: src/statistics/statistics_api.c:390 +#: src/statistics/statistics_api.c:456 #, fuzzy -msgid "Failed to connect to statistics service!\n" -msgstr "Lỗi káşżt nối đến gnunetd.\n" +msgid "Could not save some persistent statistics\n" +msgstr "KhĂ´ng thᝃ tấo miᝁn tĂŞn.\n" -#: src/template/gnunet-template.c:68 -msgid "help text" +#: src/statistics/statistics_api.c:999 +msgid "" +"Failed to receive acknowledgement from statistics service, some statistics " +"might have been lost!\n" msgstr "" #: src/testing/gnunet-testing.c:157 @@ -3771,200 +4254,168 @@ msgstr "LĆ°u cẼu hĂŹnh ngay bây giờ khĂ´ng?" msgid "Could not access hostkey.\n" msgstr "KhĂ´ng thᝃ truy cáş­p đến táş­p tin gnunet-directory ÂŤ %s Âť\n" -#: src/testing/testing.c:204 +#: src/testing/testing.c:200 msgid "`scp' does not seem to terminate (timeout copying config).\n" msgstr "" -#: src/testing/testing.c:218 src/testing/testing.c:808 +#: src/testing/testing.c:214 src/testing/testing.c:798 #, fuzzy msgid "`scp' did not complete cleanly.\n" msgstr "ÂŤ %s Âť khĂ´ng phải được káşżt nối tới đồng đẳng nĂ o.\n" -#: src/testing/testing.c:239 +#: src/testing/testing.c:237 #, fuzzy msgid "Failed to create pipe for `gnunet-peerinfo' process.\n" msgstr "Lỗi bắt đầu thu tháş­p.\n" -#: src/testing/testing.c:240 +#: src/testing/testing.c:238 #, fuzzy msgid "Failed to create pipe for `ssh' process.\n" msgstr "Lỗi tấo thĆ° m᝼c tấm thời." -#: src/testing/testing.c:292 +#: src/testing/testing.c:286 #, fuzzy, c-format msgid "Could not start `%s' process to create hostkey.\n" msgstr "Lỗi bắt đầu thu tháş­p.\n" -#: src/testing/testing.c:299 +#: src/testing/testing.c:293 #, fuzzy msgid "Failed to start `gnunet-peerinfo' process.\n" msgstr "Lỗi bắt đầu thu tháş­p.\n" -#: src/testing/testing.c:300 src/testing/testing.c:488 +#: src/testing/testing.c:294 src/testing/testing.c:471 #, fuzzy msgid "Failed to start `ssh' process.\n" msgstr "Lỗi bắt đầu thu tháş­p.\n" -#: src/testing/testing.c:360 +#: src/testing/testing.c:354 #, fuzzy, c-format msgid "Error reading from gnunet-peerinfo: %s\n" msgstr "Gạp lỗi khi đọc thĂ´ng tin tᝍ gnunetd.\n" -#: src/testing/testing.c:364 +#: src/testing/testing.c:358 #, fuzzy msgid "Malformed output from gnunet-peerinfo!\n" msgstr "Gạp lỗi khi đọc thĂ´ng tin tᝍ gnunetd.\n" -#: src/testing/testing.c:374 +#: src/testing/testing.c:368 #, fuzzy msgid "Failed to get hostkey!\n" msgstr "Lỗi lẼy thĂ´ng kĂŞ vᝁ truyᝁn tải.\n" -#: src/testing/testing.c:406 +#: src/testing/testing.c:400 msgid "`Failed while waiting for topology setup!\n" msgstr "" -#: src/testing/testing.c:480 +#: src/testing/testing.c:463 #, fuzzy, c-format msgid "Could not start `%s' process to start GNUnet.\n" msgstr "KhĂ´ng thᝃ tấo miᝁn tĂŞn.\n" -#: src/testing/testing.c:487 +#: src/testing/testing.c:470 #, fuzzy msgid "Failed to start `gnunet-arm' process.\n" msgstr "Lỗi dᝍng chấy gnunet-auto-share.\n" -#: src/testing/testing.c:509 src/testing/testing.c:612 +#: src/testing/testing.c:493 src/testing/testing.c:600 msgid "`gnunet-arm' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:510 src/testing/testing.c:613 -#: src/testing/testing.c:633 +#: src/testing/testing.c:494 src/testing/testing.c:601 +#: src/testing/testing.c:621 msgid "`ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:582 +#: src/testing/testing.c:570 msgid "Unable to get HELLO for peer!\n" msgstr "" -#: src/testing/testing.c:632 +#: src/testing/testing.c:620 msgid "`gnunet-arm' terminated with non-zero exit status (or timed out)!\n" msgstr "" -#: src/testing/testing.c:653 src/testing/testing.c:685 +#: src/testing/testing.c:643 src/testing/testing.c:675 msgid "either `gnunet-arm' or `ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:668 src/testing/testing.c:723 +#: src/testing/testing.c:658 src/testing/testing.c:713 #, fuzzy msgid "shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n" msgstr "ÂŤ %s Âť khĂ´ng phải được káşżt nối tới đồng đẳng nĂ o.\n" -#: src/testing/testing.c:796 +#: src/testing/testing.c:786 msgid "`scp' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:966 +#: src/testing/testing.c:948 #, fuzzy, c-format msgid "Starting service %s for peer `%4s'\n" msgstr "Đang bắt đầu tĂ i vᝁ ÂŤ %s Âť\n" -#: src/testing/testing.c:1237 src/testing/testing_group.c:6278 +#: src/testing/testing.c:1207 src/testing/testing_group.c:6154 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration directory.\n" msgstr "KhĂ´ng thᝃ truy cáş­p đến thĂ´ng tin vᝁ khĂ´ng gian tĂŞn.\n" -#: src/testing/testing.c:1322 src/testing/testing.c:1397 +#: src/testing/testing.c:1292 src/testing/testing.c:1359 #, fuzzy, c-format msgid "Terminating peer `%4s'\n" msgstr "KhĂ´ng đủ quyᝁn cho ÂŤ %s Âť.\n" -#: src/testing/testing.c:1480 +#: src/testing/testing.c:1448 #, fuzzy, c-format msgid "Setting d->dead on peer `%4s'\n" msgstr "Đang bắt đầu tĂ i lĂŞn ÂŤ %s Âť.\n" -#: src/testing/testing.c:1610 +#: src/testing/testing.c:1601 msgid "Peer not yet running, can not change configuration at this point." msgstr "" -#: src/testing/testing.c:1618 +#: src/testing/testing.c:1609 #, fuzzy msgid "Failed to write new configuration to disk." msgstr "Lỗi lĆ°u cẼu hĂŹnh." -#: src/testing/testing.c:1647 +#: src/testing/testing.c:1636 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration file.\n" msgstr "KhĂ´ng tĂŹm thẼy phĆ°ĆĄng phĂĄp ÂŤ %s%s Âť trong thĆ° viện ÂŤ %s Âť.\n" -#: src/testing/testing.c:1650 +#: src/testing/testing.c:1639 #, fuzzy msgid "Failed to copy new configuration to remote machine." msgstr "Lỗi lĆ°u cẼu hĂŹnh." -#: src/testing/testing.c:1805 +#: src/testing/testing.c:1794 #, fuzzy msgid "Peers failed to connect" msgstr "KhĂ´ng káşżt nối được đến trĂŹnh nᝁn gnunetd." -#: src/testing/testing.c:1933 +#: src/testing/testing.c:1922 #, fuzzy msgid "Failed to connect to core service of first peer!\n" msgstr "Lỗi nấp dịch v᝼ sqstore. HĂŁy kiᝃm tra lấi cẼu hĂŹnh.\n" -#: src/testing/testing.c:2156 +#: src/testing/testing.c:2145 msgid "Peers are not fully running yet, can not connect!\n" msgstr "" -#: src/testing/testing_group.c:1910 src/testing/testing_group.c:1922 -#: src/testing/testing_group.c:2023 src/testing/testing_group.c:2082 -#: src/testing/testing_group.c:2171 src/testing/testing_group.c:2191 -#: src/testing/testing_group.c:2328 src/testing/testing_peergroup.c:940 +#: src/testing/testing_group.c:1895 src/testing/testing_group.c:1907 +#: src/testing/testing_group.c:2008 src/testing/testing_group.c:2065 +#: src/testing/testing_group.c:2152 src/testing/testing_group.c:2172 +#: src/testing/testing_group.c:2302 src/testing/testing_peergroup.c:950 #, fuzzy, c-format msgid "Invalid value `%s' for option `%s' in section `%s': expected float\n" msgstr "GiĂĄ trị cẼu hĂŹnh ÂŤ %s Âť cho ÂŤ %s Âť trong phần ÂŤ %s Âť nĂŞn lĂ  con số\n" -#: src/testing/testing_group.c:1932 -#, fuzzy, c-format -msgid "Target is %d connections per peer." -msgstr "Lỗi thiáşżt láş­p káşżt nối với đồng đẳng.\n" - -#: src/testing/testing_group.c:2179 +#: src/testing/testing_group.c:2160 #, fuzzy, c-format msgid "" "Invalid value `%s' for option `%s' in section `%s': got %f, needed value " "greater than 0\n" msgstr "GiĂĄ trị cẼu hĂŹnh ÂŤ %s Âť cho ÂŤ %s Âť trong phần ÂŤ %s Âť nĂŞn lĂ  con số\n" -#: src/testing/testing_group.c:2209 src/testing/testing_group.c:2402 -#, c-format -msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n" -msgstr "" -"Đang káşżt nối cĂĄc điᝃm nĂşt theo địa hĂŹnh học hĂŹnh xuyáşżn hai chiᝁu: %u hĂ ng, " -"%u cột\n" - -#: src/testing/testing_group.c:2246 -#, c-format -msgid "natural log of %d is %d, will run %d iterations\n" -msgstr "" - -#: src/testing/testing_group.c:2249 -#, c-format -msgid "Total connections added thus far: %u!\n" -msgstr "" - -#: src/testing/testing_group.c:2290 -#, c-format -msgid "Total connections added for small world: %d!\n" -msgstr "" - -#: src/testing/testing_group.c:2342 -#, c-format -msgid "rand is %f probability is %f\n" -msgstr "" - -#: src/testing/testing_group.c:2919 src/testing/testing_group.c:3118 +#: src/testing/testing_group.c:2877 src/testing/testing_group.c:3063 #, fuzzy, c-format msgid "" "No `%s' specified in peer configuration in section `%s', cannot copy friends " @@ -3972,411 +4423,279 @@ msgid "" msgstr "" "Đạc tả mấng dấng sai trong cẼu hĂŹnh phần ÂŤ %s Âť cho m᝼c nháş­p ÂŤ %s Âť: %s\n" -#: src/testing/testing_group.c:3020 -msgid "Finished copying all friend files!\n" -msgstr "" - -#: src/testing/testing_group.c:3133 -#, fuzzy, c-format -msgid "Copying file with command cp %s %s\n" -msgstr "ÂŤ %s Âť thẼt bấi với mĂŁ lỗi %s: %s\n" - -#: src/testing/testing_group.c:3156 -#, fuzzy, c-format -msgid "Copying file with command scp %s %s\n" -msgstr "ÂŤ %s Âť thẼt bấi với mĂŁ lỗi %s: %s\n" - -#: src/testing/testing_group.c:3173 -#, c-format -msgid "Checking copy status of file %d\n" +#: src/testing/testing_group.c:3957 +msgid "Creating no allowed topology (all peers can connect at core level)\n" msgstr "" -#: src/testing/testing_group.c:3191 -#, c-format -msgid "File %d copied\n" -msgstr "" +#: src/testing/testing_group.c:5226 +#, fuzzy +msgid "Unknown topology specification, can't connect peers!\n" +msgstr "Lỗi cĂş phĂĄp trong sáťą xĂĄc định địa hĂŹnh học, đang bỏ qua cĂĄc byte.\n" -#: src/testing/testing_group.c:3206 +#: src/testing/testing_group.c:5944 src/transport/transport-testing.c:636 #, fuzzy -msgid "Finished copying all blacklist files!\n" +msgid "Could not read hostkeys file!\n" msgstr "KhĂ´ng thᝃ đọc danh sĂĄch bấn bè ÂŤ %s Âť\n" -#: src/testing/testing_group.c:3586 src/testing/testing_group.c:3723 -#: src/testing/testing_group.c:4884 src/testing/testing_group.c:5025 -msgid "Delaying connect, we have too many outstanding connections!\n" +#: src/testing/testing_group.c:6011 +#, fuzzy, c-format +msgid "Could not create configuration for peer number %u on `%s'!\n" +msgstr "KhĂ´ng thᝃ truy cáş­p đến thĂ´ng tin vᝁ khĂ´ng gian tĂŞn.\n" + +#: src/testing/testing_new.c:169 +msgid "tmppath cannot be NULL\n" msgstr "" -#: src/testing/testing_group.c:3596 src/testing/testing_group.c:4894 -#: src/testing/testing_group.c:5035 +#: src/testing/testing_new.c:356 #, c-format -msgid "Creating connection, outstanding_connections is %d\n" +msgid "Hostkeys file not found: %s\n" msgstr "" -#: src/testing/testing_group.c:3608 +#: src/testing/testing_new.c:365 #, fuzzy, c-format -msgid "Offering HELLO of peer %s to peer %s\n" -msgstr "đang káşżt nối đồng đẳng %s:%d tới đồng đẳng %s:%d\n" +msgid "Could not open hostkeys file: %s\n" +msgstr "KhĂ´ng thᝃ đọc danh sĂĄch bấn bè ÂŤ %s Âť\n" -#: src/testing/testing_group.c:3734 +#: src/testing/testing_new.c:380 #, c-format -msgid "Creating connection, outstanding_connections is %d (max %d)\n" -msgstr "" - -#: src/testing/testing_group.c:3988 -msgid "Creating clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:3993 -msgid "Creating small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:3998 -msgid "Creating small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4002 -msgid "Creating ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4006 -msgid "Creating 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4010 -msgid "Creating Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4014 -msgid "Creating InterNAT topology\n" -msgstr "" - -#: src/testing/testing_group.c:4018 -msgid "Creating Scale Free topology\n" -msgstr "" - -#: src/testing/testing_group.c:4023 -msgid "Creating straight line topology\n" -msgstr "" - -#: src/testing/testing_group.c:4027 -msgid "Creating topology from file!\n" -msgstr "" - -#: src/testing/testing_group.c:4043 -msgid "Creating no allowed topology (all peers can connect at core level)\n" -msgstr "" - -#: src/testing/testing_group.c:4058 -msgid "Failed during friend file copying!\n" -msgstr "" - -#: src/testing/testing_group.c:4064 -msgid "Friend files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:4081 -msgid "Blacklisting all but clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:4087 -msgid "Blacklisting all but small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4093 -msgid "Blacklisting all but small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4099 -msgid "Blacklisting all but ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4105 -msgid "Blacklisting all but 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4111 -msgid "Blacklisting all but Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4117 -msgid "Blacklisting all but InterNAT topology\n" +msgid "Incorrect hostkey file format: %s\n" msgstr "" -#: src/testing/testing_group.c:4152 -msgid "Blacklisting all but Scale Free topology\n" -msgstr "" - -#: src/testing/testing_group.c:4158 -msgid "Blacklisting all but straight line topology\n" -msgstr "" - -#: src/testing/testing_group.c:4173 -#, fuzzy -msgid "Failed during blacklist file copying!\n" -msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" - -#: src/testing/testing_group.c:4179 -msgid "Blacklist files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:5263 -msgid "Creating clique CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5270 -msgid "Creating small world (ring) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5277 -msgid "Creating small world (2d-torus) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5283 -msgid "Creating ring CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5290 -msgid "Creating 2d torus CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5297 -msgid "Creating Erdos-Renyi CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5304 -msgid "Creating InterNAT CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5311 -msgid "Creating Scale Free CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5318 -msgid "Creating straight line CONNECT topology\n" -msgstr "" +#: src/testing/testing_new.c:437 +#, fuzzy, c-format +msgid "Key number %u does not exist\n" +msgstr "đặt số trĂŹnh nᝁn cần khởi chấy" -#: src/testing/testing_group.c:5324 -msgid "Creating no CONNECT topology\n" -msgstr "" +#: src/testing/testing_new.c:446 +#, fuzzy, c-format +msgid "Error while decoding key %u\n" +msgstr "Gạp lỗi khi tải xuống: %s\n" -#: src/testing/testing_group.c:5330 +#: src/testing/testing_new.c:680 #, fuzzy -msgid "Unknown topology specification, can't connect peers!\n" -msgstr "Lỗi cĂş phĂĄp trong sáťą xĂĄc định địa hĂŹnh học, đang bỏ qua cĂĄc byte.\n" +msgid "Failed to create configuration for peer (not enough free ports?)\n" +msgstr "KhĂ´ng thᝃ truy cáş­p đến thĂ´ng tin vᝁ khĂ´ng gian tĂŞn.\n" -#: src/testing/testing_group.c:5340 +#: src/testing/testing_new.c:691 #, c-format -msgid "Connecting random subset (%'.2f percent) of possible peers\n" +msgid "" +"You attempted to create a testbed with more than %u hosts. Please " +"precompute more hostkeys first.\n" msgstr "" -#: src/testing/testing_group.c:5348 -#, c-format -msgid "Connecting a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:704 +#, fuzzy, c-format +msgid "Failed to initialize hostkey for peer %u\n" +msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" -#: src/testing/testing_group.c:5357 -#, c-format -msgid "Using DFS to connect a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:734 +#, fuzzy, c-format +msgid "Failed to write hostkey file for peer %u: %s\n" +msgstr "Lỗi tấo thĆ° m᝼c tấm thời." -#: src/testing/testing_group.c:5367 -#, c-format -msgid "Finding additional %u closest peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:751 +#, fuzzy, c-format +msgid "Failed to write configuration file `%s' for peer %u: %s\n" +msgstr "KhĂ´ng thᝃ lĆ°u táş­p tin cẼu hĂŹnh ÂŤ %s Âť:" -#: src/testing/testing_group.c:6062 src/transport/transport-testing.c:650 -#, fuzzy -msgid "Could not read hostkeys file!\n" -msgstr "KhĂ´ng thᝃ đọc danh sĂĄch bấn bè ÂŤ %s Âť\n" +#: src/testing/testing_new.c:791 +#, fuzzy, c-format +msgid "Failed to start `%s': %s\n" +msgstr "Lỗi chấy %s: %s %d\n" -#: src/testing/testing_group.c:6131 +#: src/testing/testing_new.c:959 #, fuzzy, c-format -msgid "Could not create configuration for peer number %u on `%s'!\n" -msgstr "KhĂ´ng thᝃ truy cáş­p đến thĂ´ng tin vᝁ khĂ´ng gian tĂŞn.\n" +msgid "Failed to load configuration from %s\n" +msgstr "KhĂ´ng thᝃ lĆ°u táş­p tin cẼu hĂŹnh ÂŤ %s Âť:" -#: src/topology/gnunet-daemon-topology.c:244 +#: src/topology/gnunet-daemon-topology.c:259 msgid "# peers blacklisted" msgstr "" -#: src/topology/gnunet-daemon-topology.c:380 +#: src/topology/gnunet-daemon-topology.c:392 #, fuzzy msgid "# connect requests issued to transport" msgstr "# cĂĄc yĂŞu cầu mĂĄy/trĂŹnh khĂĄch lỗ hổng được phun vĂ o" -#: src/topology/gnunet-daemon-topology.c:675 -#: src/topology/gnunet-daemon-topology.c:761 +#: src/topology/gnunet-daemon-topology.c:730 +#: src/topology/gnunet-daemon-topology.c:815 #, fuzzy msgid "# friends connected" msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" -#: src/topology/gnunet-daemon-topology.c:950 +#: src/topology/gnunet-daemon-topology.c:996 msgid "Failed to connect to core service, can not manage topology!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:982 +#: src/topology/gnunet-daemon-topology.c:1026 #, fuzzy, c-format msgid "Option `%s' in section `%s' not specified!\n" msgstr "Bị tᝍ chối đặt tĂšy chọn ÂŤ %s Âť trong phần ÂŤ %s Âť thĂ nh ÂŤ %s Âť.\n" -#: src/topology/gnunet-daemon-topology.c:994 +#: src/topology/gnunet-daemon-topology.c:1039 #, c-format msgid "Could not read friends list `%s'\n" msgstr "KhĂ´ng thᝃ đọc danh sĂĄch bấn bè ÂŤ %s Âť\n" -#: src/topology/gnunet-daemon-topology.c:1000 +#: src/topology/gnunet-daemon-topology.c:1045 #, fuzzy, c-format msgid "Friends file `%s' is empty.\n" msgstr "Định dấng cᝧa táş­p tin ÂŤ %s Âť lĂ  khĂ´ng hᝣp lệ.\n" -#: src/topology/gnunet-daemon-topology.c:1009 +#: src/topology/gnunet-daemon-topology.c:1054 #, fuzzy, c-format msgid "Failed to read friends list from `%s': out of memory\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/topology/gnunet-daemon-topology.c:1017 +#: src/topology/gnunet-daemon-topology.c:1062 #, c-format msgid "Failed to read friends list from `%s'\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/topology/gnunet-daemon-topology.c:1037 +#: src/topology/gnunet-daemon-topology.c:1082 #, fuzzy, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes.\n" msgstr "Lỗi cĂş phĂĄp trong sáťą xĂĄc định địa hĂŹnh học, đang bỏ qua cĂĄc byte.\n" -#: src/topology/gnunet-daemon-topology.c:1050 +#: src/topology/gnunet-daemon-topology.c:1095 #, fuzzy, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n" msgstr "" "Lỗi cĂş phĂĄp trong sáťą xĂĄc định địa hĂŹnh học, đang bỏ qua cĂĄc byte ÂŤ %s Âť.\n" -#: src/topology/gnunet-daemon-topology.c:1060 +#: src/topology/gnunet-daemon-topology.c:1105 #, fuzzy, c-format msgid "Found friend `%s' in configuration\n" msgstr "" "\n" "Káşżt thĂşc cẼu hĂŹnh.\n" -#: src/topology/gnunet-daemon-topology.c:1066 +#: src/topology/gnunet-daemon-topology.c:1111 #, c-format msgid "Found myself `%s' in friend list (useless, ignored)\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1076 +#: src/topology/gnunet-daemon-topology.c:1121 #, fuzzy msgid "# friends in configuration" msgstr "" "\n" "Káşżt thĂşc cẼu hĂŹnh.\n" -#: src/topology/gnunet-daemon-topology.c:1082 +#: src/topology/gnunet-daemon-topology.c:1127 msgid "" "Fewer friends specified than required by minimum friend count. Will only " "connect to friends.\n" msgstr "" "XĂĄc định quĂĄ Ă­t bấn bè (dưới số tối thiᝃu). Sáş˝ chỉ káşżt nối tới bấn bè.\n" -#: src/topology/gnunet-daemon-topology.c:1089 +#: src/topology/gnunet-daemon-topology.c:1134 msgid "" "More friendly connections required than target total number of connections.\n" msgstr "Cần thiáşżt nhiᝁu káşżt nối bấn bè hĆĄn tổng số káşżt nối đích.\n" -#: src/topology/gnunet-daemon-topology.c:1126 +#: src/topology/gnunet-daemon-topology.c:1169 #, fuzzy msgid "# HELLO messages received" msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/topology/gnunet-daemon-topology.c:1183 +#: src/topology/gnunet-daemon-topology.c:1224 #, fuzzy msgid "# HELLO messages gossipped" msgstr "# cĂĄc thĂ´ng bĂĄo gáť­i đi bị loấi bỏ" -#: src/topology/gnunet-daemon-topology.c:1323 +#: src/topology/gnunet-daemon-topology.c:1363 msgid "GNUnet topology control (maintaining P2P mesh and F2F constraints)" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:247 +#: src/transport/gnunet-service-transport_blacklist.c:246 #, fuzzy, c-format msgid "Could not read blacklist file `%s'\n" msgstr "KhĂ´ng thᝃ đọc danh sĂĄch bấn bè ÂŤ %s Âť\n" -#: src/transport/gnunet-service-transport_blacklist.c:254 +#: src/transport/gnunet-service-transport_blacklist.c:252 #, c-format msgid "Blacklist file `%s' is empty.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:266 +#: src/transport/gnunet-service-transport_blacklist.c:263 #, fuzzy, c-format msgid "Failed to read blacklist from `%s'\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/transport/gnunet-service-transport_blacklist.c:287 -#: src/transport/gnunet-service-transport_blacklist.c:311 +#: src/transport/gnunet-service-transport_blacklist.c:284 +#: src/transport/gnunet-service-transport_blacklist.c:308 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, giving up!\n" msgstr "Gạp lỗi cĂş phĂĄp trong táş­p tin cẼu hĂŹnh ÂŤ %s Âť tấi dòng %d.\n" -#: src/transport/gnunet-service-transport_blacklist.c:298 -#: src/transport/gnunet-service-transport_blacklist.c:336 +#: src/transport/gnunet-service-transport_blacklist.c:295 +#: src/transport/gnunet-service-transport_blacklist.c:331 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes.\n" msgstr "Lỗi cĂş phĂĄp trong sáťą xĂĄc định địa hĂŹnh học, đang bỏ qua cĂĄc byte.\n" -#: src/transport/gnunet-service-transport_blacklist.c:350 +#: src/transport/gnunet-service-transport_blacklist.c:345 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n" msgstr "" "Lỗi cĂş phĂĄp trong sáťą xĂĄc định địa hĂŹnh học, đang bỏ qua cĂĄc byte ÂŤ %s Âť.\n" -#: src/transport/gnunet-service-transport_blacklist.c:364 +#: src/transport/gnunet-service-transport_blacklist.c:359 #, c-format msgid "Found myself `%s' in blacklist (useless, ignored)\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:523 -#: src/transport/gnunet-service-transport_blacklist.c:764 +#: src/transport/gnunet-service-transport_blacklist.c:514 +#: src/transport/gnunet-service-transport_blacklist.c:747 msgid "# disconnects due to blacklist" msgstr "" -#: src/transport/gnunet-service-transport.c:158 +#: src/transport/gnunet-service-transport.c:163 #, fuzzy msgid "# bytes payload discarded due to not connected peer " msgstr "# CĂĄc quảng cĂĄo đồng đẳng bị hᝧy do trọng tải" -#: src/transport/gnunet-service-transport.c:572 +#: src/transport/gnunet-service-transport.c:237 +#, fuzzy +msgid "# bytes total received" +msgstr "# tổng số nội dung lỗ hổng được nháş­n" + +#: src/transport/gnunet-service-transport.c:284 +#, fuzzy +msgid "# bytes payload received" +msgstr "# cĂĄc byte đã giải mĂŁ" + +#: src/transport/gnunet-service-transport.c:582 msgid "Transport service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport.c:581 +#: src/transport/gnunet-service-transport.c:591 msgid "Transport service could not access hostkey. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:353 +#: src/transport/gnunet-service-transport_clients.c:352 #, c-format msgid "Dropping message of type %u and size %u, have %u/%u messages pending\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:358 +#: src/transport/gnunet-service-transport_clients.c:357 #, fuzzy msgid "# messages dropped due to slow client" msgstr "# cĂĄc yĂŞu cầu lỗ hổng bị bỏ do trọng tải" -#: src/transport/gnunet-service-transport_clients.c:510 +#: src/transport/gnunet-service-transport_clients.c:503 #, c-format msgid "Rejecting control connection from peer `%s', which is not me!\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:628 -#, fuzzy -msgid "# bytes payload received for other peers" -msgstr "# cĂĄc byte kiᝃu %d được nháş­n" - -#: src/transport/gnunet-service-transport_clients.c:645 +#: src/transport/gnunet-service-transport_clients.c:631 msgid "# bytes payload dropped (other peer was not connected)" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:696 +#: src/transport/gnunet-service-transport_clients.c:682 #, fuzzy msgid "# REQUEST CONNECT messages received" msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" @@ -4385,616 +4704,565 @@ msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" msgid "# refreshed my HELLO" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:482 -msgid "# failed connection attempts due to timeout" -msgstr "" +#: src/transport/gnunet-service-transport_neighbours.c:1032 +#, fuzzy +msgid "# DISCONNECT messages sent" +msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/transport/gnunet-service-transport_neighbours.c:883 +#: src/transport/gnunet-service-transport_neighbours.c:1148 +#: src/transport/gnunet-service-transport_neighbours.c:1482 #, fuzzy -msgid "# peers disconnected due to external request" -msgstr "# cĂĄc yĂŞu cầu lỗ hổng bị bỏ do trọng tải" +msgid "# bytes in message queue for other peers" +msgstr "# cĂĄc byte thĂ´ng bĂĄo gáť­i đi bị loấi bỏ" -#: src/transport/gnunet-service-transport_neighbours.c:966 +#: src/transport/gnunet-service-transport_neighbours.c:1153 #, fuzzy -msgid "# fast reconnects failed" -msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" +msgid "# messages transmitted to other peers" +msgstr "# cĂĄc byte kiᝃu %d được gáť­i " -#: src/transport/gnunet-service-transport_neighbours.c:1022 +#: src/transport/gnunet-service-transport_neighbours.c:1158 #, fuzzy -msgid "# peers disconnected due to timeout" -msgstr "# cĂĄc káşżt nối bị đóng (vẼn đề truyᝁn tải)" +msgid "# transmission failures for messages to other peers" +msgstr "# cĂĄc byte thĂ´ng bĂĄo gáť­i đi bị loấi bỏ" + +#: src/transport/gnunet-service-transport_neighbours.c:1215 +msgid "# messages timed out while in transport queue" +msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1047 +#: src/transport/gnunet-service-transport_neighbours.c:1254 #, fuzzy msgid "# keepalives sent" msgstr "# cĂĄc khoĂĄ phiĂŞn chấy được gáť­i" -#: src/transport/gnunet-service-transport_neighbours.c:1088 +#: src/transport/gnunet-service-transport_neighbours.c:1278 #, fuzzy -msgid "# peers disconnected due to global disconnect" -msgstr "# CĂĄc quảng cĂĄo đồng đẳng bị hᝧy do trọng tải" +msgid "# KEEPALIVE messages discarded (peer unknown)" +msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/transport/gnunet-service-transport_neighbours.c:1888 -#: src/transport/gnunet-service-transport_neighbours.c:1909 +#: src/transport/gnunet-service-transport_neighbours.c:1286 #, fuzzy -msgid "# messages not sent (no such peer or not connected)" +msgid "# KEEPALIVE messages discarded (no session)" msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/transport/gnunet-service-transport_neighbours.c:1925 +#: src/transport/gnunet-service-transport_neighbours.c:1323 #, fuzzy -msgid "# bytes in message queue for other peers" -msgstr "# cĂĄc byte thĂ´ng bĂĄo gáť­i đi bị loấi bỏ" +msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" +msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/transport/gnunet-service-transport_neighbours.c:1977 +#: src/transport/gnunet-service-transport_neighbours.c:1332 +#, fuzzy +msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" +msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" + +#: src/transport/gnunet-service-transport_neighbours.c:1388 #, fuzzy msgid "# messages discarded due to lack of neighbour record" msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/transport/gnunet-service-transport_neighbours.c:2013 +#: src/transport/gnunet-service-transport_neighbours.c:1422 #, fuzzy msgid "# bandwidth quota violations by other peers" msgstr "theo dĂľi gnunetd sáť­ d᝼ng dải thĂ´ng" -#: src/transport/gnunet-service-transport_neighbours.c:2031 +#: src/transport/gnunet-service-transport_neighbours.c:1438 msgid "# ms throttling suggested" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2060 +#: src/transport/gnunet-service-transport_neighbours.c:2544 #, fuzzy -msgid "# KEEPALIVE messages discarded (not connected)" -msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" +msgid "# unexpected CONNECT_ACK messages (no peer)" +msgstr "gáť­i ĐẞM thĂ´ng bĂĄo" + +#: src/transport/gnunet-service-transport_neighbours.c:2559 +#: src/transport/gnunet-service-transport_neighbours.c:2585 +#, fuzzy +msgid "# unexpected CONNECT_ACK messages (not ready)" +msgstr "gáť­i ĐẞM thĂ´ng bĂĄo" + +#: src/transport/gnunet-service-transport_neighbours.c:2598 +#, fuzzy +msgid "# unexpected CONNECT_ACK messages (waiting on ATS)" +msgstr "gáť­i ĐẞM thĂ´ng bĂĄo" -#: src/transport/gnunet-service-transport_neighbours.c:2113 +#: src/transport/gnunet-service-transport_neighbours.c:2627 #, fuzzy -msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" -msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" +msgid "# unexpected CONNECT_ACK messages (disconnecting)" +msgstr "gáť­i ĐẞM thĂ´ng bĂĄo" -#: src/transport/gnunet-service-transport_neighbours.c:2121 +#: src/transport/gnunet-service-transport_neighbours.c:2807 #, fuzzy -msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" -msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" +msgid "# unexpected SESSION ACK messages" +msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được gáť­i" -#: src/transport/gnunet-service-transport_neighbours.c:2187 +#: src/transport/gnunet-service-transport_neighbours.c:2856 msgid "# SET QUOTA messages ignored (no such peer)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2205 +#: src/transport/gnunet-service-transport_neighbours.c:2870 msgid "# disconnects due to quota of 0" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2323 +#: src/transport/gnunet-service-transport_neighbours.c:2901 msgid "# disconnect messages ignored (old format)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2336 +#: src/transport/gnunet-service-transport_neighbours.c:2912 msgid "# disconnect messages ignored (timestamp)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2411 -#, fuzzy -msgid "# unexpected CONNECT_ACK messages (no peer)" -msgstr "gáť­i ĐẞM thĂ´ng bĂĄo" - -#: src/transport/gnunet-service-transport_neighbours.c:2453 -#, fuzzy -msgid "# unexpected CONNECT_ACK messages" -msgstr "gáť­i ĐẞM thĂ´ng bĂĄo" +#: src/transport/gnunet-service-transport_neighbours.c:2943 +msgid "# other peer asked to disconnect from us" +msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2544 +#: src/transport/gnunet-service-transport_neighbours.c:3020 #, fuzzy -msgid "# unexpected ACK messages" -msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được gáť­i" +msgid "# disconnected from peer upon explicit request" +msgstr "# cĂĄc yĂŞu cầu lỗ hổng bị bỏ do trọng tải" #: src/transport/gnunet-service-transport_plugins.c:111 msgid "Transport service is lacking NEIGHBOUR_LIMIT option.\n" msgstr "" -#: src/transport/gnunet-service-transport_plugins.c:118 -#, fuzzy, c-format -msgid "Starting transport plugins `%s'\n" -msgstr "Đang nấp cĂĄc truyᝁn tải ÂŤ %s Âť\n" - -#: src/transport/gnunet-service-transport_plugins.c:122 -#, fuzzy, c-format -msgid "Loading `%s' transport plugin\n" -msgstr "Đang nấp cĂĄc truyᝁn tải ÂŤ %s Âť\n" - -#: src/transport/gnunet-service-transport_plugins.c:150 -#, fuzzy, c-format -msgid "Failed to load transport plugin for `%s'\n" -msgstr "KhĂ´ng thᝃ nấp phần bổ sung truyᝁn tải ÂŤ %s Âť\n" - -#: src/transport/gnunet-service-transport_validation.c:410 +#: src/transport/gnunet-service-transport_validation.c:414 msgid "# address records discarded" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:459 +#: src/transport/gnunet-service-transport_validation.c:463 #, c-format msgid "" "Not transmitting `%s' with `%s', message too big (%u bytes!). This should " "not happen.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:508 +#: src/transport/gnunet-service-transport_validation.c:512 #, fuzzy msgid "# PING without HELLO messages sent" msgstr "# cĂĄc thĂ´ng bĂĄo PONG nháş­p thĂ´ được gáť­i" -#: src/transport/gnunet-service-transport_validation.c:566 +#: src/transport/gnunet-service-transport_validation.c:570 msgid "# address revalidations started" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:798 +#: src/transport/gnunet-service-transport_validation.c:805 #, fuzzy msgid "# PING message for different peer received" msgstr "# cĂĄc thĂ´ng bĂĄo PING được tấo" -#: src/transport/gnunet-service-transport_validation.c:833 +#: src/transport/gnunet-service-transport_validation.c:840 #, c-format msgid "" "Not confirming PING with address `%s' since I cannot confirm having this " "address.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:919 +#: src/transport/gnunet-service-transport_validation.c:924 msgid "# PONGs unicast via reliable transport" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:928 +#: src/transport/gnunet-service-transport_validation.c:933 msgid "# PONGs multicast to all available addresses" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1050 +#: src/transport/gnunet-service-transport_validation.c:1055 msgid "# PONGs dropped, no matching pending validation" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1075 +#: src/transport/gnunet-service-transport_validation.c:1080 msgid "# PONGs dropped, signature expired" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1134 +#: src/transport/gnunet-service-transport_validation.c:1136 #, fuzzy, c-format msgid "Adding `%s' without addresses for peer `%s'\n" msgstr "KhĂ´ng thᝃ lẼy địa chỉ cᝧa đồng đẳng ÂŤ %s Âť.\n" -#: src/transport/gnunet-transport.c:256 +#: src/transport/gnunet-transport.c:260 msgid "No transport plugins configured, peer will never communicate\n" msgstr "" -#: src/transport/gnunet-transport.c:269 +#: src/transport/gnunet-transport.c:273 #, c-format msgid "No port configured for plugin `%s', cannot test it\n" msgstr "" -#: src/transport/gnunet-transport.c:319 +#: src/transport/gnunet-transport.c:323 #, c-format msgid "Received %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:326 +#: src/transport/gnunet-transport.c:330 #, c-format msgid "Transmitted %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:359 +#: src/transport/gnunet-transport.c:363 #, fuzzy, c-format msgid "Transmitting %u bytes to %s\n" msgstr "Đang tháť­ tải danh sĂĄch cĂĄc mĂĄy xuống ÂŤ %s Âť\n" -#: src/transport/gnunet-transport.c:379 +#: src/transport/gnunet-transport.c:383 #, fuzzy, c-format msgid "Connected to %s\n" msgstr "ÂŤ %s Âť được káşżt nối tới ÂŤ %s Âť.\n" -#: src/transport/gnunet-transport.c:410 +#: src/transport/gnunet-transport.c:414 #, fuzzy, c-format msgid "Disconnected from %s\n" msgstr "ÂŤ %.*s Âť được káşżt nối tới ÂŤ %.*s Âť.\n" -#: src/transport/gnunet-transport.c:439 +#: src/transport/gnunet-transport.c:443 #, fuzzy, c-format msgid "Received %u bytes from %s\n" msgstr "Nháş­n yĂŞu cầu định tuyáşżn\n" -#: src/transport/gnunet-transport.c:453 +#: src/transport/gnunet-transport.c:466 #, fuzzy, c-format msgid "Peer `%s': %s %s\n" msgstr "TĂ´i lĂ  đồng đẳng ÂŤ %s Âť.\n" -#: src/transport/gnunet-transport.c:483 +#: src/transport/gnunet-transport.c:473 +#, c-format +msgid "Peer `%s': %s \n" +msgstr "" + +#: src/transport/gnunet-transport.c:501 #, fuzzy, c-format msgid "Peer `%s' disconnected\n" msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" -#: src/transport/gnunet-transport.c:539 +#: src/transport/gnunet-transport.c:569 #, fuzzy, c-format msgid "Failed to parse peer identity `%s'\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/transport/gnunet-transport.c:587 +#: src/transport/gnunet-transport.c:618 msgid "measure how fast we are receiving data (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:590 +#: src/transport/gnunet-transport.c:621 #, fuzzy msgid "try to connect to the given peer" msgstr "Lỗi káşżt nối đến gnunetd.\n" -#: src/transport/gnunet-transport.c:593 +#: src/transport/gnunet-transport.c:624 #, fuzzy msgid "provide information about all current connections (once)" msgstr "In ra thĂ´ng tin vᝁ cĂĄc đồng đẳng GNUnet." -#: src/transport/gnunet-transport.c:596 +#: src/transport/gnunet-transport.c:627 #, fuzzy msgid "provide information about all current connections (continuously)" msgstr "In ra thĂ´ng tin vᝁ cĂĄc đồng đẳng GNUnet." -#: src/transport/gnunet-transport.c:599 +#: src/transport/gnunet-transport.c:630 #, fuzzy msgid "do not resolve hostnames" msgstr "khĂ´ng quyáşżt định cĂĄc tĂŞn mĂĄy" -#: src/transport/gnunet-transport.c:603 +#: src/transport/gnunet-transport.c:634 msgid "send data for benchmarking to the other peer (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:606 +#: src/transport/gnunet-transport.c:637 msgid "test transport configuration (involves external server)" msgstr "" -#: src/transport/gnunet-transport.c:614 +#: src/transport/gnunet-transport.c:645 #, fuzzy msgid "Direct access to transport service." msgstr "Lỗi káşżt nối đến gnunetd.\n" -#: src/transport/plugin_transport_http.c:981 +#: src/transport/plugin_transport_http.c:1100 msgid "Disabling IPv6 since it is not supported on this system!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1029 +#: src/transport/plugin_transport_http.c:1149 #, fuzzy msgid "Require valid port number for service in configuration!\n" msgstr "Lỗi lĆ°u cẼu hĂŹnh." -#: src/transport/plugin_transport_http.c:1054 src/util/service.c:986 +#: src/transport/plugin_transport_http.c:1174 src/util/service.c:1036 #, fuzzy, c-format msgid "Failed to resolve `%s': %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/transport/plugin_transport_http.c:1071 src/util/service.c:1003 +#: src/transport/plugin_transport_http.c:1191 src/util/service.c:1053 #, fuzzy, c-format msgid "Failed to find %saddress for `%s'.\n" msgstr "Lỗi đóng káşżt đến cổng %s %d.\n" -#: src/transport/plugin_transport_http.c:1176 +#: src/transport/plugin_transport_http.c:1296 #, c-format msgid "Found %u addresses to report to NAT service\n" msgstr "" -#: src/transport/plugin_transport_http.c:1189 +#: src/transport/plugin_transport_http.c:1309 #, c-format msgid "FREEING %s\n" msgstr "" -#: src/transport/plugin_transport_http.c:1264 +#: src/transport/plugin_transport_http.c:1386 msgid "Neither IPv4 nor IPv6 are enabled! Fix in configuration\n" msgstr "" -#: src/transport/plugin_transport_http.c:1277 +#: src/transport/plugin_transport_http.c:1399 #, fuzzy msgid "Port is required! Fix in configuration\n" msgstr "" "\n" "Káşżt thĂşc cẼu hĂŹnh.\n" -#: src/transport/plugin_transport_http.c:1288 +#: src/transport/plugin_transport_http.c:1410 msgid "Port 0, client only mode\n" msgstr "" -#: src/transport/plugin_transport_http.c:1308 +#: src/transport/plugin_transport_http.c:1430 #, c-format msgid "" "Specific IPv4 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1338 +#: src/transport/plugin_transport_http.c:1460 #, c-format msgid "" "Specific IPv6 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http_client.c:621 +#: src/transport/plugin_transport_http_client.c:624 #, c-format msgid "Could not initialize curl multi handle, failed to start %s plugin!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:189 +#: src/transport/plugin_transport_http_server.c:178 msgid "" "Could not create a new TLS certificate, program `gnunet-transport-" "certificate-creation' could not be started!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:213 +#: src/transport/plugin_transport_http_server.c:202 msgid "No usable TLS certificate found and creating one failed!\n" msgstr "" -#: src/transport/plugin_transport_smtp.c:370 -#, c-format -msgid "Received malformed message via %s. Ignored.\n" -msgstr "Nháş­n được thĂ´ng bĂĄo dấng sai qua %s. Bị bỏ qua.\n" - -#: src/transport/plugin_transport_smtp.c:457 -msgid "SMTP filter string to invalid, lacks ': '\n" -msgstr "Chuỗi lọc vĂ o SMTP khĂ´ng hᝣp lệ, còn thiáşżu ÂŤ : Âť\n" - -#: src/transport/plugin_transport_smtp.c:466 -#, c-format -msgid "SMTP filter string to long, capped to `%s'\n" -msgstr "Chuỗi lọc vĂ o SMTP quĂĄ dĂ i, tối đa ÂŤ %s Âť\n" - -#: src/transport/plugin_transport_smtp.c:561 -#: src/transport/plugin_transport_smtp.c:571 -#: src/transport/plugin_transport_smtp.c:584 -#: src/transport/plugin_transport_smtp.c:603 -#: src/transport/plugin_transport_smtp.c:626 -#: src/transport/plugin_transport_smtp.c:634 -#: src/transport/plugin_transport_smtp.c:647 -#: src/transport/plugin_transport_smtp.c:658 -#, c-format -msgid "SMTP: `%s' failed: %s.\n" -msgstr "SMTP: ÂŤ %s Âť bị lỗi: %s\n" - -#: src/transport/plugin_transport_smtp.c:801 -msgid "No email-address specified, can not start SMTP transport.\n" -msgstr "ChĆ°a ghi rĂľ địa chỉ thĆ° điện táť­ nĂŞn khĂ´ng tấo được truyᝁn tải SMTP.\n" - -#: src/transport/plugin_transport_smtp.c:813 -msgid "# bytes received via SMTP" -msgstr "# cĂĄc byte đã nháş­n qua SMTP" - -#: src/transport/plugin_transport_smtp.c:814 -msgid "# bytes sent via SMTP" -msgstr "# cĂĄc byte đã gáť­i qua SMTP" - -#: src/transport/plugin_transport_smtp.c:816 -msgid "# bytes dropped by SMTP (outgoing)" -msgstr "# cĂĄc byte loấi đi bởi SMTP (đi ra)" - -#: src/transport/plugin_transport_tcp.c:512 +#: src/transport/plugin_transport_tcp.c:591 #, fuzzy, c-format msgid "Unexpected address length: %u bytes\n" msgstr "Gạp sáťą kiện bẼt thường: %d\n" -#: src/transport/plugin_transport_tcp.c:616 -#: src/transport/plugin_transport_tcp.c:705 -#: src/transport/plugin_transport_tcp.c:757 -#: src/transport/plugin_transport_tcp.c:830 -#: src/transport/plugin_transport_tcp.c:909 +#: src/transport/plugin_transport_tcp.c:767 +#: src/transport/plugin_transport_tcp.c:856 +#: src/transport/plugin_transport_tcp.c:906 +#: src/transport/plugin_transport_tcp.c:992 +#: src/transport/plugin_transport_tcp.c:1086 +#: src/transport/plugin_transport_tcp.c:1103 #, fuzzy msgid "# bytes currently in TCP buffers" msgstr "# cĂĄc byte đã gᝍi qua TCP" -#: src/transport/plugin_transport_tcp.c:622 -#: src/transport/plugin_transport_tcp.c:856 -#: src/transport/plugin_transport_tcp.c:1561 +#: src/transport/plugin_transport_tcp.c:774 +#: src/transport/plugin_transport_tcp.c:963 +#: src/transport/plugin_transport_tcp.c:1761 +#: src/transport/plugin_transport_tcp.c:2390 #, fuzzy msgid "# TCP sessions active" msgstr "# cĂĄc khoĂĄ phiĂŞn chấy được chẼp nháş­n" -#: src/transport/plugin_transport_tcp.c:709 +#: src/transport/plugin_transport_tcp.c:860 #, fuzzy msgid "# bytes discarded by TCP (timeout)" msgstr "# cĂĄc byte loấi đi bởi TCP (đi ra)" -#: src/transport/plugin_transport_tcp.c:760 +#: src/transport/plugin_transport_tcp.c:909 #, fuzzy msgid "# bytes transmitted via TCP" msgstr "# cĂĄc byte được gáť­i" -#: src/transport/plugin_transport_tcp.c:834 +#: src/transport/plugin_transport_tcp.c:996 #, fuzzy msgid "# bytes discarded by TCP (disconnect)" msgstr "# cĂĄc byte loấi đi bởi TCP (đi ra)" -#: src/transport/plugin_transport_tcp.c:1081 +#: src/transport/plugin_transport_tcp.c:1290 #, fuzzy, c-format msgid "Address of unexpected length: %u\n" msgstr "Gạp sáťą kiện bẼt thường: %d\n" -#: src/transport/plugin_transport_tcp.c:1116 -msgid "Found valid IPv4 NAT address (creating session)!\n" -msgstr "" - -#: src/transport/plugin_transport_tcp.c:1186 +#: src/transport/plugin_transport_tcp.c:1401 msgid "# transport-service disconnect requests for TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:1603 +#: src/transport/plugin_transport_tcp.c:1802 #, fuzzy msgid "# TCP WELCOME messages received" msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/transport/plugin_transport_tcp.c:1756 +#: src/transport/plugin_transport_tcp.c:1973 msgid "# bytes received via TCP" msgstr "# cĂĄc byte đã nháş­n qua TCP" -#: src/transport/plugin_transport_tcp.c:1823 +#: src/transport/plugin_transport_tcp.c:2043 msgid "# network-level TCP disconnect events" msgstr "" -#: src/transport/plugin_transport_tcp.c:1962 src/util/service.c:889 +#: src/transport/plugin_transport_tcp.c:2279 src/util/service.c:940 #, c-format msgid "Require valid port number for service `%s' in configuration!\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1976 +#: src/transport/plugin_transport_tcp.c:2293 #, fuzzy msgid "Failed to start service.\n" msgstr "Lỗi bắt đầu thu tháş­p.\n" -#: src/transport/plugin_transport_tcp.c:2039 +#: src/transport/plugin_transport_tcp.c:2355 #, fuzzy, c-format msgid "Failed to find option %s in section %s!\n" msgstr "Lỗi đóng káşżt đến cổng %s %d.\n" -#: src/transport/plugin_transport_tcp.c:2062 +#: src/transport/plugin_transport_tcp.c:2378 #, c-format msgid "TCP transport listening on port %llu\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2066 +#: src/transport/plugin_transport_tcp.c:2382 msgid "TCP transport not listening on any port (client only)\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2070 +#: src/transport/plugin_transport_tcp.c:2386 #, c-format msgid "TCP transport advertises itself as being on port %llu\n" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:130 +#: src/transport/plugin_transport_udp_broadcasting.c:128 #, fuzzy msgid "# IPv6 multicast HELLO beacons received via udp" msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/transport/plugin_transport_udp_broadcasting.c:172 +#: src/transport/plugin_transport_udp_broadcasting.c:169 #, fuzzy msgid "# IPv4 broadcast HELLO beacons received via udp" msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/transport/plugin_transport_udp_broadcasting.c:393 +#: src/transport/plugin_transport_udp_broadcasting.c:367 #, c-format msgid "Failed to set IPv4 broadcast option for broadcast socket on port %d\n" msgstr "" -#: src/transport/plugin_transport_udp.c:1985 +#: src/transport/plugin_transport_udp.c:1894 +#, c-format +msgid "" +"UDP could not message to `%s': `%s'. Please check your network configuration " +"and disable IPv6 if your connection does not have a global IPv6 address\n" +msgstr "" + +#: src/transport/plugin_transport_udp.c:2138 #, fuzzy msgid "Failed to open UDP sockets\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/transport/plugin_transport_udp.c:2068 +#: src/transport/plugin_transport_udp.c:2306 #, c-format msgid "Given `%s' option is out of range: %llu > %u\n" msgstr "" -#: src/transport/plugin_transport_udp.c:2112 +#: src/transport/plugin_transport_udp.c:2349 #, fuzzy, c-format msgid "Invalid IPv6 address: `%s'\n" msgstr "Mᝊc Ć°u tiĂŞn tiáşżn trĂŹnh khĂ´ng hᝣp lĂŞ ÂŤ %s Âť.\n" -#: src/transport/plugin_transport_unix.c:1051 +#: src/transport/plugin_transport_unix.c:1356 #, fuzzy msgid "Failed to open UNIX sockets\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/transport/plugin_transport_wlan.c:875 +#: src/transport/plugin_transport_wlan.c:561 +msgid "# WLAN ACKs sent" +msgstr "" + +#: src/transport/plugin_transport_wlan.c:580 #, fuzzy -msgid "# wlan session timeouts" -msgstr "# cĂĄc khoĂĄ phiĂŞn chấy được chẼp nháş­n" +msgid "# WLAN messages defragmented" +msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/transport/plugin_transport_wlan.c:899 +#: src/transport/plugin_transport_wlan.c:626 +#: src/transport/plugin_transport_wlan.c:676 +#: src/transport/plugin_transport_wlan.c:1696 #, fuzzy -msgid "# wlan session created" +msgid "# WLAN sessions allocated" msgstr "# cĂĄc khoĂĄ phiĂŞn chấy được chẼp nháş­n" -#: src/transport/plugin_transport_wlan.c:980 -#: src/transport/plugin_transport_wlan.c:1138 -#: src/transport/plugin_transport_wlan.c:1159 -#: src/transport/plugin_transport_wlan.c:1190 -#: src/transport/plugin_transport_wlan.c:2334 -#: src/transport/plugin_transport_wlan.c:3142 -msgid "# wlan pending sessions" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:1233 -#: src/transport/plugin_transport_wlan.c:1888 +#: src/transport/plugin_transport_wlan.c:749 #, fuzzy -msgid "# wlan pending fragments" -msgstr "# cĂĄc mảnh bị loấi bỏ" - -#: src/transport/plugin_transport_wlan.c:1388 -#, c-format -msgid "" -"Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n" -msgstr "" +msgid "# WLAN message fragments sent" +msgstr "# cĂĄc thĂ´ng bĂĄo bị táşż phân" -#: src/transport/plugin_transport_wlan.c:1732 -msgid "# wlan hello beacons send" +#: src/transport/plugin_transport_wlan.c:767 +msgid "# WLAN messages pending (with fragmentation)" msgstr "" -#: src/transport/plugin_transport_wlan.c:1765 -#: src/transport/plugin_transport_wlan.c:1968 -#: src/transport/plugin_transport_wlan.c:2059 -#, c-format -msgid "Error writing to wlan helper. errno == %d, ERROR: %s\n" -msgstr "" +#: src/transport/plugin_transport_wlan.c:867 +#: src/transport/plugin_transport_wlan.c:948 +#: src/transport/plugin_transport_wlan.c:1698 +#, fuzzy +msgid "# WLAN MAC endpoints allocated" +msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" -#: src/transport/plugin_transport_wlan.c:1954 -msgid "# wlan acks send" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1119 +#, fuzzy +msgid "# HELLO messages received via WLAN" +msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/transport/plugin_transport_wlan.c:2025 +#: src/transport/plugin_transport_wlan.c:1140 #, fuzzy -msgid "# wlan fragments send" +msgid "# fragments received via WLAN" msgstr "# cĂĄc mảnh bị loấi bỏ" -#: src/transport/plugin_transport_wlan.c:2161 -#, c-format -msgid "Wlan Address len %d is wrong\n" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:2295 -#: src/transport/plugin_transport_wlan.c:2919 -#: src/transport/plugin_transport_wlan.c:3145 -msgid "# wlan mac endpoints" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1150 +#, fuzzy +msgid "# ACKs received via WLAN" +msgstr "# cĂĄc byte đã nháş­n qua TCP" -#: src/transport/plugin_transport_wlan.c:2517 +#: src/transport/plugin_transport_wlan.c:1207 #, fuzzy -msgid "# wlan whole messages received" -msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" +msgid "# WLAN DATA messages discarded due to CRC32 error" +msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" -#: src/transport/plugin_transport_wlan.c:2708 +#: src/transport/plugin_transport_wlan.c:1306 #, fuzzy -msgid "# wlan hello messages received" -msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" +msgid "# DATA messages received via WLAN" +msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/transport/plugin_transport_wlan.c:2742 +#: src/transport/plugin_transport_wlan.c:1341 #, fuzzy -msgid "# wlan fragments received" -msgstr "# cĂĄc mảnh bị loấi bỏ" +msgid "# WLAN DATA messages processed" +msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" -#: src/transport/plugin_transport_wlan.c:2790 +#: src/transport/plugin_transport_wlan.c:1402 #, fuzzy -msgid "# wlan acks received" -msgstr "# cĂĄc yĂŞu cầu khĂĄch lỗ hổng được nháş­n" +msgid "# HELLO beacons sent via WLAN" +msgstr "# cĂĄc byte đã gáť­i qua UDP" -#: src/transport/plugin_transport_wlan.c:2879 -msgid "# wlan mac endpoints timeouts" +#: src/transport/plugin_transport_wlan.c:1511 +msgid "WLAN address with invalid size encountered\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:2903 -#, fuzzy -msgid "# wlan mac endpoints created" -msgstr "# cĂĄc yĂŞu cầu get (lẼy) dht được nháş­n" +#: src/transport/plugin_transport_wlan.c:1668 +#, fuzzy, c-format +msgid "Invalid configuration option `%s' in section `%s'\n" +msgstr "GiĂĄ trị cẼu hĂŹnh ÂŤ %s Âť cho ÂŤ %s Âť trong phần ÂŤ %s Âť nĂŞn lĂ  con số\n" -#: src/transport/plugin_transport_wlan.c:2956 -msgid "# wlan WLAN_HELPER_DATA received" +#: src/transport/plugin_transport_wlan.c:1677 +#, c-format +msgid "Helper binary `%s' not SUID, cannot run WLAN transport\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:3010 -#, fuzzy -msgid "# wlan messages for this client received" -msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" - -#: src/transport/plugin_transport_wlan.c:3021 -#, fuzzy -msgid "# wlan messages inside WLAN_HELPER_DATA received" -msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" +#: src/transport/plugin_transport_wlan.c:1687 +#, fuzzy, c-format +msgid "Missing configuration option `%s' in section `%s'\n" +msgstr "GiĂĄ trị cẼu hĂŹnh ÂŤ %s Âť cho ÂŤ %s Âť trong phần ÂŤ %s Âť nĂŞn lĂ  con số\n" -#: src/transport/transport_api.c:588 +#: src/transport/transport_api.c:570 #, fuzzy, c-format msgid "Received unexpected message of type %u in %s:%u\n" msgstr "Nháş­n được thĂ´ng bĂĄo bị hỏng tᝍ đồng đẳng ÂŤ %s Âť trong %s:%d.\n" @@ -5028,89 +5296,89 @@ msgstr "" msgid "Metadata `%s' failed to deserialize" msgstr "" -#: src/util/client.c:304 +#: src/util/client.c:359 #, c-format msgid "" "Could not determine valid hostname and port for service `%s' from " "configuration.\n" msgstr "" -#: src/util/client.c:312 +#: src/util/client.c:367 #, c-format msgid "Need a non-empty hostname for service `%s'.\n" msgstr "" -#: src/util/client.c:657 +#: src/util/client.c:685 msgid "Failure to transmit TEST request.\n" msgstr "" -#: src/util/client.c:717 src/util/service.c:919 +#: src/util/client.c:740 src/util/service.c:970 #, c-format msgid "UNIXPATH `%s' too long, maximum length is %llu\n" msgstr "" -#: src/util/client.c:859 +#: src/util/client.c:882 #, c-format msgid "Could not connect to service `%s', must not be running.\n" msgstr "" -#: src/util/client.c:875 +#: src/util/client.c:896 #, fuzzy, c-format msgid "Failure to transmit request to service `%s'\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/util/client.c:1143 +#: src/util/client.c:1149 msgid "Could not submit request, not expecting to receive a response.\n" msgstr "" -#: src/util/common_logging.c:239 src/util/common_logging.c:889 +#: src/util/common_logging.c:239 src/util/common_logging.c:890 msgid "DEBUG" msgstr "Gáť  LỖI" -#: src/util/common_logging.c:241 src/util/common_logging.c:887 +#: src/util/common_logging.c:241 src/util/common_logging.c:888 msgid "INFO" msgstr "TIN" -#: src/util/common_logging.c:243 src/util/common_logging.c:885 +#: src/util/common_logging.c:243 src/util/common_logging.c:886 msgid "WARNING" msgstr "CẢNH BÁO" -#: src/util/common_logging.c:245 src/util/common_logging.c:883 +#: src/util/common_logging.c:245 src/util/common_logging.c:884 msgid "ERROR" msgstr "LỖI" -#: src/util/common_logging.c:247 src/util/common_logging.c:891 +#: src/util/common_logging.c:247 src/util/common_logging.c:892 msgid "NONE" msgstr "" -#: src/util/common_logging.c:609 +#: src/util/common_logging.c:610 #, fuzzy, c-format msgid "Failed to create or access directory for log file `%s'\n" msgstr "KhĂ´ng thᝃ truy cáş­p đến táş­p tin gnunet-directory ÂŤ %s Âť\n" -#: src/util/common_logging.c:724 +#: src/util/common_logging.c:725 #, fuzzy, c-format msgid "Message `%.*s' repeated %u times in the last %s\n" msgstr "ThĂ´ng điệp ÂŤ %.*s Âť đã lạp lấi %u lần trong %llu giây trước\n" -#: src/util/common_logging.c:892 +#: src/util/common_logging.c:893 msgid "INVALID" msgstr "" -#: src/util/common_logging.c:991 +#: src/util/common_logging.c:992 msgid "unknown address" msgstr "" -#: src/util/common_logging.c:1029 +#: src/util/common_logging.c:1030 msgid "invalid address" msgstr "" -#: src/util/configuration.c:245 +#: src/util/configuration.c:244 #, fuzzy, c-format msgid "Syntax error in configuration file `%s' at line %u.\n" msgstr "Gạp lỗi cĂş phĂĄp trong táş­p tin cẼu hĂŹnh ÂŤ %s Âť tấi dòng %d.\n" -#: src/util/configuration.c:817 +#: src/util/configuration.c:816 #, c-format msgid "" "Configuration value '%s' for '%s' in section '%s' is not in set of legal " @@ -5119,45 +5387,38 @@ msgstr "" "GiĂĄ trị cẼu hĂŹnh ÂŤ %s Âť cho ÂŤ %s Âť trong phần ÂŤ %s Âť khĂ´ng phải náşąm trong " "táş­p hᝣp cĂĄc sáťą chọn được phĂŠp\n" -#: src/util/connection.c:460 +#: src/util/connection.c:420 #, fuzzy, c-format msgid "Access denied to `%s'\n" msgstr "KhĂ´ng đủ quyᝁn cho ÂŤ %s Âť.\n" -#: src/util/connection.c:475 +#: src/util/connection.c:435 #, c-format msgid "Accepting connection from `%s': %p\n" msgstr "" -#: src/util/connection.c:629 +#: src/util/connection.c:550 #, fuzzy, c-format msgid "" "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n" msgstr "Lỗi thiáşżt láş­p káşżt nối với đồng đẳng.\n" -#: src/util/connection.c:821 src/util/connection.c:992 +#: src/util/connection.c:739 src/util/connection.c:909 #, fuzzy, c-format msgid "Trying to connect to `%s' (%p)\n" msgstr "KhĂ´ng thᝃ káşżt nối tới %s:%u: %s\n" -#: src/util/connection.c:830 +#: src/util/connection.c:748 #, fuzzy, c-format msgid "Failed to connect to `%s' (%p)\n" msgstr "KhĂ´ng thᝃ káşżt nối tới %s:%u: %s\n" -#: src/util/connection.c:983 +#: src/util/connection.c:900 #, fuzzy, c-format msgid "Attempt to connect to `%s' failed\n" msgstr " Lỗi káşżt nối\n" -#: src/util/connection.c:1465 -#, c-format -msgid "" -"Could not satisfy pending transmission request, socket closed or connect " -"failed (%p).\n" -msgstr "" - -#: src/util/container_bloomfilter.c:507 +#: src/util/container_bloomfilter.c:510 #, c-format msgid "" "Size of file on disk is incorrect for this Bloom filter (want %llu, have " @@ -5174,129 +5435,129 @@ msgstr "" msgid "libgcrypt has not the expected version (version %s is required).\n" msgstr "libgcrypt khĂ´ng cĂł phiĂŞn bản mong đợi (yĂŞu cầu phiĂŞn bản %s).\n" -#: src/util/crypto_rsa.c:618 src/util/crypto_rsa.c:665 +#: src/util/crypto_rsa.c:661 src/util/crypto_rsa.c:708 #, fuzzy, c-format msgid "Could not aquire lock on file `%s': %s...\n" msgstr "Lỗi mở táş­p tin theo dĂľi ÂŤ %s Âť: %s\n" -#: src/util/crypto_rsa.c:623 +#: src/util/crypto_rsa.c:666 #, fuzzy msgid "Creating a new private key. This may take a while.\n" msgstr "Đang tấo khoĂĄ mĂĄy mới (cĂł thᝃ hĆĄi lâu).\n" -#: src/util/crypto_rsa.c:641 +#: src/util/crypto_rsa.c:684 #, c-format msgid "I am host `%s'. Stored new private key in `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:669 src/util/crypto_rsa.c:705 +#: src/util/crypto_rsa.c:712 src/util/crypto_rsa.c:748 msgid "This may be ok if someone is currently generating a hostkey.\n" msgstr "" -#: src/util/crypto_rsa.c:700 +#: src/util/crypto_rsa.c:743 #, c-format msgid "" "When trying to read hostkey file `%s' I found %u bytes but I need at least " "%u.\n" msgstr "" -#: src/util/crypto_rsa.c:720 +#: src/util/crypto_rsa.c:763 #, fuzzy, c-format msgid "File `%s' does not contain a valid private key. Deleting it.\n" msgstr "Táş­p tin ÂŤ %s Âť khĂ´ng chᝊa biệt hiệu nĂŞn tháť­ gᝥ bỏ.\n" -#: src/util/crypto_rsa.c:738 +#: src/util/crypto_rsa.c:781 #, c-format msgid "I am host `%s'. Read private key from `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:959 +#: src/util/crypto_rsa.c:1032 #, c-format msgid "RSA signature verification failed at %s:%d: %s\n" msgstr "Lỗi thẊm tra chᝯ kĂ˝ RSA tấi %s:%d: %s\n" -#: src/util/disk.c:479 +#: src/util/disk.c:498 #, fuzzy, c-format msgid "`%s' failed for drive `%S': %u\n" msgstr "ÂŤ %s Âť thẼt bấi cho ổ đĩa ÂŤ %s Âť: %u\n" -#: src/util/disk.c:1087 +#: src/util/disk.c:1062 #, c-format msgid "Expected `%s' to be a directory!\n" msgstr "Mong đợi ÂŤ %s Âť lĂ  một thĆ° m᝼c.\n" -#: src/util/disk.c:1441 src/util/service.c:1580 +#: src/util/disk.c:1416 src/util/service.c:1650 #, c-format msgid "Cannot obtain information about user `%s': %s\n" msgstr "KhĂ´ng thᝃ lẼy thĂ´ng tin vᝁ người dĂšng ÂŤ %s Âť: %s\n" -#: src/util/disk.c:1759 +#: src/util/disk.c:1734 #, c-format msgid "No `%s' specified for service `%s' in configuration.\n" msgstr "" -#: src/util/getopt.c:672 +#: src/util/getopt.c:669 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "%s: tĂšy chọn ÂŤ %s Âť lĂ  mĆĄ hồ\n" -#: src/util/getopt.c:696 +#: src/util/getopt.c:693 #, c-format msgid "%s: option `--%s' does not allow an argument\n" msgstr "%s: tĂšy chọn ÂŤ --%s Âť khĂ´ng cho phĂŠp đối số\n" -#: src/util/getopt.c:701 +#: src/util/getopt.c:698 #, c-format msgid "%s: option `%c%s' does not allow an argument\n" msgstr "%s: tĂšy chọn ÂŤ %c%s Âť khĂ´ng cho phĂŠp đối số\n" -#: src/util/getopt.c:718 src/util/getopt.c:886 +#: src/util/getopt.c:715 src/util/getopt.c:883 #, c-format msgid "%s: option `%s' requires an argument\n" msgstr "%s: tĂšy chọn ÂŤ %s Âť cần thiáşżt đối số\n" -#: src/util/getopt.c:747 +#: src/util/getopt.c:744 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "%s: khĂ´ng nháş­n ra tĂšy chọn ÂŤ --%s Âť\n" -#: src/util/getopt.c:751 +#: src/util/getopt.c:748 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "%s: khĂ´ng nháş­n ra tĂšy chọn ÂŤ %c%s Âť\n" -#: src/util/getopt.c:776 +#: src/util/getopt.c:773 #, c-format msgid "%s: illegal option -- %c\n" msgstr "%s: tĂšy chọn khĂ´ng được phĂŠp -- %c\n" -#: src/util/getopt.c:778 +#: src/util/getopt.c:775 #, c-format msgid "%s: invalid option -- %c\n" msgstr "%s: tĂšy chọn khĂ´ng hᝣp lệ -- %c\n" -#: src/util/getopt.c:806 src/util/getopt.c:934 +#: src/util/getopt.c:803 src/util/getopt.c:931 #, c-format msgid "%s: option requires an argument -- %c\n" msgstr "%s: tĂšy chọn cần thiáşżt đối số -- %c\n" -#: src/util/getopt.c:854 +#: src/util/getopt.c:851 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "%s: tĂšy chọn ÂŤ -W %s Âť lĂ  mĆĄ hồ\n" -#: src/util/getopt.c:872 +#: src/util/getopt.c:869 #, c-format msgid "%s: option `-W %s' does not allow an argument\n" msgstr "%s: tĂšy chọn ÂŤ -W %s Âť khĂ´ng cho phĂŠp đối số\n" -#: src/util/getopt.c:1038 +#: src/util/getopt.c:1035 #, fuzzy, c-format msgid "Use %s to get a list of options.\n" msgstr "" "HĂŁy sáť­ d᝼ng câu lệnh trᝣ giĂşp ÂŤ --help Âť để xem danh sĂĄch cĂĄc tĂšy chọn.\n" -#: src/util/getopt_helpers.c:84 +#: src/util/getopt_helpers.c:86 #, c-format msgid "" "Arguments mandatory for long options are also mandatory for short options.\n" @@ -5304,7 +5565,7 @@ msgstr "" "Mọi đối số bắt buộc phải sáť­ d᝼ng với tĂšy chọn dĂ i cĹŠng bắt buộc với tĂšy chọn " "ngắn.\n" -#: src/util/getopt_helpers.c:255 src/util/getopt_helpers.c:283 +#: src/util/getopt_helpers.c:258 src/util/getopt_helpers.c:286 #, c-format msgid "You must pass a number to the `%s' option.\n" msgstr "Phải gáť­i một con số cho tĂšy chọn ÂŤ %s Âť.\n" @@ -5317,6 +5578,27 @@ msgstr "" msgid "Use build-in GNUnet stub resolver" msgstr "" +#: src/util/gnunet-rsa.c:64 +#, c-format +msgid "No hostkey file specified on command line\n" +msgstr "" + +#: src/util/gnunet-rsa.c:112 +msgid "print the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:115 +msgid "print the hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:118 +msgid "print the short hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:124 +msgid "Manipulate GNUnet private RSA key files" +msgstr "" + #: src/util/gnunet-service-resolver.c:288 #, c-format msgid "Could not resolve `%s' (%s): %s\n" @@ -5328,42 +5610,37 @@ msgstr "KhĂ´ng thᝃ giải quyáşżt ÂŤ %s Âť (%s): %s\n" msgid "Could not find IP of host `%s': %s\n" msgstr "KhĂ´ng tĂŹm thẼy địa chỉ IP cᝧa mĂĄy ÂŤ %s Âť: %s\n" -#: src/util/gnunet-service-resolver.c:494 -#, c-format -msgid "Resolver asked to look up `%s'.\n" -msgstr "" - -#: src/util/gnunet-service-resolver.c:529 -#, c-format -msgid "Resolver asked to look up IP address `%s'.\n" -msgstr "" - -#: src/util/helper.c:239 +#: src/util/helper.c:244 #, fuzzy, c-format msgid "Error reading from `%s': %s\n" msgstr "Gạp lỗi khi tấo người dĂšng" -#: src/util/helper.c:254 +#: src/util/helper.c:259 #, c-format msgid "Got 0 bytes from helper `%s' (EOF)\n" msgstr "" -#: src/util/helper.c:264 +#: src/util/helper.c:269 #, fuzzy, c-format msgid "Got %u bytes from helper `%s'\n" msgstr "Nháş­n yĂŞu cầu định tuyáşżn\n" -#: src/util/helper.c:273 +#: src/util/helper.c:278 #, fuzzy, c-format msgid "Failed to parse inbound message from helper `%s'\n" msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#: src/util/helper.c:432 +#: src/util/helper.c:310 +#, fuzzy, c-format +msgid "Starting HELPER process `%s'\n" +msgstr "Đang bắt đầu tĂ i vᝁ ÂŤ %s Âť\n" + +#: src/util/helper.c:440 #, fuzzy, c-format msgid "Error writing to `%s': %s\n" msgstr "Gạp lỗi khi tấo người dĂšng" -#: src/util/network.c:1196 +#: src/util/network.c:1200 #, c-format msgid "" "Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n" @@ -5391,12 +5668,12 @@ msgstr "SMTP: ÂŤ %s Âť bị lỗi: %s\n" msgid "stat (%s) failed: %s\n" msgstr "SMTP: ÂŤ %s Âť bị lỗi: %s\n" -#: src/util/os_priority.c:304 +#: src/util/os_priority.c:305 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for reading: %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" -#: src/util/os_priority.c:305 +#: src/util/os_priority.c:306 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for writing: %s\n" msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" @@ -5421,12 +5698,12 @@ msgstr "ÂŤ %s Âť thẼt bấi cho thĆ° viện ÂŤ %s Âť với lỗi: %s\n" msgid "Could not determine plugin installation path.\n" msgstr "KhĂ´ng thᝃ truy cáş­p đến thĂ´ng tin vᝁ khĂ´ng gian tĂŞn.\n" -#: src/util/pseudonym.c:273 +#: src/util/pseudonym.c:276 #, fuzzy, c-format msgid "Failed to parse metadata about pseudonym from file `%s': %s\n" msgstr "Lỗi phân tĂ­ch dᝯ liệu giao diện tᝍ ÂŤ %s Âť.\n" -#: src/util/pseudonym.c:338 +#: src/util/pseudonym.c:407 src/util/pseudonym.c:433 msgid "no-name" msgstr "khĂ´ng-tĂŞn" @@ -5441,187 +5718,167 @@ msgid "" "Must specify `%s' or numeric IP address for `%s' of `%s' in configuration!\n" msgstr "" -#: src/util/resolver_api.c:351 +#: src/util/resolver_api.c:347 #, fuzzy, c-format msgid "Timeout trying to resolve IP address `%s'.\n" msgstr "GNUnet bây giờ sáť­ d᝼ng địa chỉ IP %s.\n" -#: src/util/resolver_api.c:355 +#: src/util/resolver_api.c:351 #, fuzzy, c-format msgid "Timeout trying to resolve hostname `%s'.\n" msgstr "khĂ´ng quyáşżt định cĂĄc tĂŞn mĂĄy" -#: src/util/resolver_api.c:426 -#, c-format -msgid "Resolver returns `%s' for IP `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:807 -#, c-format -msgid "Resolver returns `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:901 -#, c-format -msgid "Resolving our FQDN `%s'\n" -msgstr "" - -#: src/util/resolver_api.c:906 +#: src/util/resolver_api.c:890 #, fuzzy, c-format msgid "Could not resolve our FQDN : %s\n" msgstr "KhĂ´ng thᝃ giải quyáşżt ÂŤ %s Âť (%s): %s\n" -#: src/util/resolver_api.c:938 -#, c-format -msgid "Resolving our hostname `%s'\n" -msgstr "" - -#: src/util/scheduler.c:866 +#: src/util/scheduler.c:786 msgid "Looks like we're busy waiting...\n" msgstr "" -#: src/util/scheduler.c:996 +#: src/util/scheduler.c:916 #, c-format msgid "Attempt to cancel dead task %llu!\n" msgstr "" -#: src/util/server.c:397 +#: src/util/server.c:483 #, fuzzy, c-format msgid "`%s' failed for port %d (%s).\n" msgstr "ÂŤ %s Âť thẼt bấi cho ổ đĩa ÂŤ %s Âť: %u\n" -#: src/util/server.c:406 +#: src/util/server.c:492 #, fuzzy, c-format msgid "`%s' failed for port %d (%s): address already in use\n" msgstr "ÂŤ %s Âť bị lỗi cho cổng %d. TrĂŹnh gnunetd cĂł chấy chĆ°a?\n" -#: src/util/server.c:411 +#: src/util/server.c:497 #, fuzzy, c-format msgid "`%s' failed for `%s': address already in use\n" msgstr "ÂŤ %s Âť bị lỗi cho cổng %d. TrĂŹnh gnunetd cĂł chấy chĆ°a?\n" -#: src/util/server.c:640 +#: src/util/server.c:827 #, c-format msgid "" "Processing code for message of type %u did not call " "GNUNET_SERVER_receive_done after %llums\n" msgstr "" -#: src/util/service.c:117 src/util/service.c:143 src/util/service.c:186 -#: src/util/service.c:207 src/util/service.c:214 +#: src/util/service.c:135 src/util/service.c:161 src/util/service.c:204 +#: src/util/service.c:225 src/util/service.c:232 #, c-format msgid "Invalid format for IP: `%s'\n" msgstr "Địa chỉ IP định dấng sai: %s\n" -#: src/util/service.c:170 +#: src/util/service.c:188 #, c-format msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)." msgstr "KĂ˝ hiệu mấng sai (ÂŤ /%d Âť khĂ´ng hᝣp lệ trong CIDR IPv4)." -#: src/util/service.c:263 +#: src/util/service.c:281 #, c-format msgid "Invalid network notation (does not end with ';': `%s')\n" msgstr "KĂ˝ hiệu mấng sai (khĂ´ng káşżt thĂşc với ÂŤ ; Âť: ÂŤ %s Âť)\n" -#: src/util/service.c:296 +#: src/util/service.c:313 #, fuzzy, c-format msgid "Wrong format `%s' for netmask\n" msgstr "Mạt nấ mấng cĂł định dấng sai ÂŤ %s Âť: %s\n" -#: src/util/service.c:326 +#: src/util/service.c:343 #, fuzzy, c-format msgid "Wrong format `%s' for network\n" msgstr "Mấng cĂł định dấng sai ÂŤ %s Âť: %s\n" -#: src/util/service.c:668 +#: src/util/service.c:698 #, c-format msgid "Access denied to UID %d / GID %d\n" msgstr "" -#: src/util/service.c:673 +#: src/util/service.c:703 #, fuzzy, c-format msgid "Unknown address family %d\n" msgstr "\tKhĂ´ng rĂľ miᝁn tĂŞn ÂŤ %s Âť\n" -#: src/util/service.c:680 +#: src/util/service.c:710 #, c-format msgid "Access from `%s' denied to service `%s'\n" msgstr "" -#: src/util/service.c:724 +#: src/util/service.c:765 #, c-format msgid "Could not parse IPv4 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:752 +#: src/util/service.c:802 #, c-format msgid "Could not parse IPv6 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:869 +#: src/util/service.c:920 #, c-format msgid "" "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n" msgstr "" -#: src/util/service.c:939 +#: src/util/service.c:990 #, c-format msgid "" "Disabling UNIX domain socket support for service `%s', failed to create UNIX " "domain socket: %s\n" msgstr "" -#: src/util/service.c:956 +#: src/util/service.c:1007 #, c-format msgid "Have neither PORT nor UNIXPATH for service `%s', but one is required\n" msgstr "" -#: src/util/service.c:1191 +#: src/util/service.c:1241 msgid "Could not access a pre-bound socket, will try to bind myself\n" msgstr "" -#: src/util/service.c:1242 src/util/service.c:1260 +#: src/util/service.c:1292 src/util/service.c:1310 #, c-format msgid "Specified value for `%s' of service `%s' is invalid\n" msgstr "" -#: src/util/service.c:1287 +#: src/util/service.c:1337 #, c-format msgid "Could not access pre-bound socket %u, will try to bind myself\n" msgstr "" -#: src/util/service.c:1442 +#: src/util/service.c:1506 #, fuzzy, c-format msgid "Failed to start `%s' at `%s'\n" msgstr "Lỗi chấy %s: %s %d\n" -#: src/util/service.c:1475 +#: src/util/service.c:1539 #, fuzzy, c-format msgid "Service `%s' runs at %s\n" msgstr "Đồng đẳng ÂŤ %s Âť cĂł mᝊc tin cáş­y %8u\n" -#: src/util/service.c:1521 +#: src/util/service.c:1588 msgid "Service process failed to initialize\n" msgstr "" -#: src/util/service.c:1525 +#: src/util/service.c:1592 msgid "Service process could not initialize server function\n" msgstr "" -#: src/util/service.c:1529 +#: src/util/service.c:1596 msgid "Service process failed to report status\n" msgstr "" -#: src/util/service.c:1581 +#: src/util/service.c:1651 msgid "No such user" msgstr "KhĂ´ng cĂł người dĂšng nhĆ° váş­y" -#: src/util/service.c:1594 +#: src/util/service.c:1664 #, c-format msgid "Cannot change user/group to `%s': %s\n" msgstr "KhĂ´ng thᝃ thay đổi người dĂšng/nhĂłm thĂ nh ÂŤ %s Âť: %s\n" -#: src/util/service.c:1657 +#: src/util/service.c:1729 msgid "do daemonize (detach from terminal)" msgstr "" @@ -5630,56 +5887,77 @@ msgstr "" msgid "signal (%d, %p) returned %d.\n" msgstr "" -#: src/util/strings.c:143 +#: src/util/strings.c:144 msgid "b" msgstr "b" -#: src/util/strings.c:354 +#: src/util/strings.c:334 #, c-format msgid "Character sets requested were `%s'->`%s'\n" msgstr "" -#: src/util/strings.c:462 +#: src/util/strings.c:481 msgid "Failed to expand `$HOME': environment variable `HOME' not set" msgstr "" "Lỗi mở rộng biáşżn mĂ´i trường ÂŤ $HOME Âť: chĆ°a đặt biáşżn mĂ´i trường ÂŤ HOME Âť" -#: src/util/strings.c:554 +#: src/util/strings.c:573 msgid "ms" msgstr "mg" -#: src/util/strings.c:559 +#: src/util/strings.c:578 msgid "eternity" msgstr "" -#: src/util/strings.c:563 +#: src/util/strings.c:582 msgid "s" msgstr "g" -#: src/util/strings.c:567 +#: src/util/strings.c:586 msgid "m" msgstr "p" -#: src/util/strings.c:571 +#: src/util/strings.c:590 msgid "h" msgstr "g" -#: src/util/strings.c:575 +#: src/util/strings.c:594 msgid " days" msgstr " ngĂ y" -#: src/util/strings.c:599 +#: src/util/strings.c:618 msgid "end of time" msgstr "" -#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1065 +#: src/util/strings.c:1012 +msgid "IPv6 address did not start with `['\n" +msgstr "" + +#: src/util/strings.c:1020 +msgid "IPv6 address did contain ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1026 +msgid "IPv6 address did contain ']' before ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1033 +msgid "IPv6 address did contain a valid port number after the last ':'\n" +msgstr "" + +#: src/util/strings.c:1042 +#, fuzzy, c-format +msgid "Invalid IPv6 address `%s': %s\n" +msgstr "Mᝊc Ć°u tiĂŞn tiáşżn trĂŹnh khĂ´ng hᝣp lĂŞ ÂŤ %s Âť.\n" + +#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1071 #, fuzzy msgid "# Active tunnels" msgstr "# cĂĄc káşżt nối dht" #: src/vpn/gnunet-service-vpn.c:608 src/vpn/gnunet-service-vpn.c:645 #, fuzzy -msgid "# Peers connected to mesh tunnels" +msgid "# peers connected to mesh tunnels" msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" #: src/vpn/gnunet-service-vpn.c:699 @@ -5702,75 +5980,75 @@ msgstr "# cĂĄc truy vẼn lỗ hổng được định tuyáşżn" msgid "Failed to setup mesh tunnel!\n" msgstr "Lỗi lẼy thĂ´ng kĂŞ vᝁ truyᝁn tải.\n" -#: src/vpn/gnunet-service-vpn.c:967 +#: src/vpn/gnunet-service-vpn.c:973 #, c-format msgid "Protocol %u not supported, dropping\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1285 +#: src/vpn/gnunet-service-vpn.c:1291 msgid "# ICMPv4 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1306 +#: src/vpn/gnunet-service-vpn.c:1312 msgid "# ICMPv6 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1511 +#: src/vpn/gnunet-service-vpn.c:1517 #, fuzzy msgid "# Packets received from TUN interface" msgstr "# cĂĄc đáp ᝊng lỗ hổng được gáť­i cho trĂŹnh/mĂĄy khĂĄch" -#: src/vpn/gnunet-service-vpn.c:1549 src/vpn/gnunet-service-vpn.c:1590 +#: src/vpn/gnunet-service-vpn.c:1555 src/vpn/gnunet-service-vpn.c:1596 #, c-format msgid "Packet received for unmapped destination `%s' (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1600 +#: src/vpn/gnunet-service-vpn.c:1606 msgid "Received IPv4 packet with options (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1614 +#: src/vpn/gnunet-service-vpn.c:1620 #, c-format msgid "Received packet of unknown protocol %d from TUN (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1697 +#: src/vpn/gnunet-service-vpn.c:1704 #, fuzzy msgid "# ICMP packets received from mesh" msgstr "# cĂĄc đáp ᝊng lỗ hổng được gáť­i cho trĂŹnh/mĂĄy khĂĄch" -#: src/vpn/gnunet-service-vpn.c:2038 +#: src/vpn/gnunet-service-vpn.c:2045 #, fuzzy msgid "# UDP packets received from mesh" msgstr "# cĂĄc đáp ᝊng lỗ hổng được gáť­i cho trĂŹnh/mĂĄy khĂĄch" -#: src/vpn/gnunet-service-vpn.c:2196 +#: src/vpn/gnunet-service-vpn.c:2203 #, fuzzy msgid "# TCP packets received from mesh" msgstr "# cĂĄc đáp ᝊng lỗ hổng được gáť­i cho trĂŹnh/mĂĄy khĂĄch" -#: src/vpn/gnunet-service-vpn.c:2347 +#: src/vpn/gnunet-service-vpn.c:2354 msgid "Failed to find unallocated IPv4 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2402 +#: src/vpn/gnunet-service-vpn.c:2409 msgid "Failed to find unallocated IPv6 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2441 src/vpn/gnunet-service-vpn.c:2624 +#: src/vpn/gnunet-service-vpn.c:2448 src/vpn/gnunet-service-vpn.c:2661 #, fuzzy msgid "# Active destinations" msgstr "# cĂĄc káşżt nối dht" -#: src/vpn/gnunet-service-vpn.c:2726 +#: src/vpn/gnunet-service-vpn.c:2734 msgid "Failed to allocate IP address for new destination\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3133 +#: src/vpn/gnunet-service-vpn.c:3141 msgid "IPv6 support disabled as this system does not support IPv6\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3165 +#: src/vpn/gnunet-service-vpn.c:3173 msgid "IPv4 support disabled as this system does not support IPv4\n" msgstr "" @@ -5846,22 +6124,171 @@ msgstr "# cĂĄc byte đã nháş­n qua UDP" msgid "Setup tunnels via VPN." msgstr "" -#: src/include/gnunet_common.h:479 src/include/gnunet_common.h:484 -#: src/include/gnunet_common.h:490 +#: src/include/gnunet_common.h:497 src/include/gnunet_common.h:502 +#: src/include/gnunet_common.h:508 #, fuzzy, c-format msgid "Assertion failed at %s:%d.\n" msgstr "Lỗi nội bộ : kháşłng định khĂ´ng thĂ nh cĂ´ng tấi %s:%d.\n" -#: src/include/gnunet_common.h:500 +#: src/include/gnunet_common.h:518 #, fuzzy, c-format msgid "External protocol violation detected at %s:%d.\n" msgstr "Lỗi nội bộ : kháşłng định khĂ´ng thĂ nh cĂ´ng tấi %s:%d.\n" -#: src/include/gnunet_common.h:521 src/include/gnunet_common.h:528 +#: src/include/gnunet_common.h:539 src/include/gnunet_common.h:546 #, c-format msgid "`%s' failed on file `%s' at %s:%d with error: %s\n" msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s\n" +#~ msgid "Received malformed message via %s. Ignored.\n" +#~ msgstr "Nháş­n được thĂ´ng bĂĄo dấng sai qua %s. Bị bỏ qua.\n" + +#~ msgid "SMTP filter string to invalid, lacks ': '\n" +#~ msgstr "Chuỗi lọc vĂ o SMTP khĂ´ng hᝣp lệ, còn thiáşżu ÂŤ : Âť\n" + +#~ msgid "SMTP filter string to long, capped to `%s'\n" +#~ msgstr "Chuỗi lọc vĂ o SMTP quĂĄ dĂ i, tối đa ÂŤ %s Âť\n" + +#~ msgid "SMTP: `%s' failed: %s.\n" +#~ msgstr "SMTP: ÂŤ %s Âť bị lỗi: %s\n" + +#~ msgid "No email-address specified, can not start SMTP transport.\n" +#~ msgstr "" +#~ "ChĆ°a ghi rĂľ địa chỉ thĆ° điện táť­ nĂŞn khĂ´ng tấo được truyᝁn tải SMTP.\n" + +#~ msgid "# bytes received via SMTP" +#~ msgstr "# cĂĄc byte đã nháş­n qua SMTP" + +#~ msgid "# bytes sent via SMTP" +#~ msgstr "# cĂĄc byte đã gáť­i qua SMTP" + +#~ msgid "# bytes dropped by SMTP (outgoing)" +#~ msgstr "# cĂĄc byte loấi đi bởi SMTP (đi ra)" + +#, fuzzy +#~ msgid "# Peers connected" +#~ msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" + +#, fuzzy +#~ msgid "%s failed for `%s' at %s:%d: `%s'\n" +#~ msgstr "%s bị lỗi tấi %s:%d: ÂŤ %s Âť\n" + +#, fuzzy +#~ msgid "Failed to transmit shutdown ACK.\n" +#~ msgstr "Lỗi bắt đầu thu tháş­p.\n" + +#, fuzzy +#~ msgid "Unable to initialize Postgres with configuration `%s': %s" +#~ msgstr "KhĂ´ng thᝃ lĆ°u táş­p tin cẼu hĂŹnh ÂŤ %s Âť:" + +#, fuzzy +#~ msgid "Failed to transmit message to `%s' service.\n" +#~ msgstr "Lỗi sĆĄ khởi dịch v᝼ ÂŤ %s Âť.\n" + +#, fuzzy +#~ msgid "Target is %d connections per peer." +#~ msgstr "Lỗi thiáşżt láş­p káşżt nối với đồng đẳng.\n" + +#~ msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n" +#~ msgstr "" +#~ "Đang káşżt nối cĂĄc điᝃm nĂşt theo địa hĂŹnh học hĂŹnh xuyáşżn hai chiᝁu: %u " +#~ "hĂ ng, %u cột\n" + +#, fuzzy +#~ msgid "Copying file with RENAME (%s,%s)\n" +#~ msgstr "ÂŤ %s Âť thẼt bấi với mĂŁ lỗi %s: %s\n" + +#, fuzzy +#~ msgid "Copying file with command scp %s %s\n" +#~ msgstr "ÂŤ %s Âť thẼt bấi với mĂŁ lỗi %s: %s\n" + +#, fuzzy +#~ msgid "Finished copying all blacklist files!\n" +#~ msgstr "KhĂ´ng thᝃ đọc danh sĂĄch bấn bè ÂŤ %s Âť\n" + +#, fuzzy +#~ msgid "Offering HELLO of peer %s to peer %s\n" +#~ msgstr "đang káşżt nối đồng đẳng %s:%d tới đồng đẳng %s:%d\n" + +#, fuzzy +#~ msgid "Failed during blacklist file copying!\n" +#~ msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" + +#, fuzzy +#~ msgid "# bytes payload received for other peers" +#~ msgstr "# cĂĄc byte kiᝃu %d được nháş­n" + +#, fuzzy +#~ msgid "# fast reconnects failed" +#~ msgstr "# cᝧa cĂĄc đồng đẳng đã káşżt nối" + +#, fuzzy +#~ msgid "# peers disconnected due to timeout" +#~ msgstr "# cĂĄc káşżt nối bị đóng (vẼn đề truyᝁn tải)" + +#, fuzzy +#~ msgid "# peers disconnected due to global disconnect" +#~ msgstr "# CĂĄc quảng cĂĄo đồng đẳng bị hᝧy do trọng tải" + +#, fuzzy +#~ msgid "# messages not sent (no such peer or not connected)" +#~ msgstr "# cĂĄc thĂ´ng bĂĄo được chắp liᝁn" + +#, fuzzy +#~ msgid "# unexpected CONNECT_ACK messages" +#~ msgstr "gáť­i ĐẞM thĂ´ng bĂĄo" + +#, fuzzy +#~ msgid "# wlan session timeouts" +#~ msgstr "# cĂĄc khoĂĄ phiĂŞn chấy được chẼp nháş­n" + +#, fuzzy +#~ msgid "# wlan session created" +#~ msgstr "# cĂĄc khoĂĄ phiĂŞn chấy được chẼp nháş­n" + +#, fuzzy +#~ msgid "# wlan pending fragments" +#~ msgstr "# cĂĄc mảnh bị loấi bỏ" + +#, fuzzy +#~ msgid "# wlan fragments send" +#~ msgstr "# cĂĄc mảnh bị loấi bỏ" + +#, fuzzy +#~ msgid "# wlan whole messages received" +#~ msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" + +#, fuzzy +#~ msgid "# wlan hello messages received" +#~ msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" + +#, fuzzy +#~ msgid "# wlan fragments received" +#~ msgstr "# cĂĄc mảnh bị loấi bỏ" + +#, fuzzy +#~ msgid "# wlan acks received" +#~ msgstr "# cĂĄc yĂŞu cầu khĂĄch lỗ hổng được nháş­n" + +#, fuzzy +#~ msgid "# wlan messages for this client received" +#~ msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" + +#, fuzzy +#~ msgid "# wlan messages inside WLAN_HELPER_DATA received" +#~ msgstr "# cĂĄc thĂ´ng bĂĄo phĂĄt hiện dht được nháş­n" + +#~ msgid "Unknown user `%s'\n" +#~ msgstr "KhĂ´ng rĂľ người dĂšng ÂŤ %s Âť\n" + +#, fuzzy +#~ msgid "Namespace `%s' unknown.\n" +#~ msgstr "KhĂ´ng gian tĂŞn ÂŤ %s Âť cĂł đánh giĂĄ %d.\n" + +#, fuzzy +#~ msgid "Failed to connect to statistics service!\n" +#~ msgstr "Lỗi káşżt nối đến gnunetd.\n" + #, fuzzy #~ msgid "Failed to send to `%s': %s\n" #~ msgstr "Lỗi mở táş­p tin ghi sáťą kiện ÂŤ %s Âť: %s\n" @@ -5929,10 +6356,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "Unable to accept connection for service `%s': %s\n" #~ msgstr "KhĂ´ng thᝃ lĆ°u táş­p tin cẼu hĂŹnh ÂŤ %s Âť:" -#, fuzzy -#~ msgid "Service `%s' started\n" -#~ msgstr "Dịch v᝼ đã bị xoĂĄ.\n" - #, fuzzy #~ msgid "Peer `%s' plugin: `%s' address `%s'\n" #~ msgstr "Đồng đẳng ÂŤ %s Âť cĂł mᝊc tin cáş­y %8u vĂ  địa chỉ ÂŤ %s Âť\n" @@ -5965,14 +6388,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "Failed to load dhtlog plugin for `%s'\n" #~ msgstr "Lỗi đọc danh sĂĄch bấn bè tᝍ ÂŤ %s Âť\n" -#, fuzzy -#~ msgid "Failed to get full path for `%s'\n" -#~ msgstr "Lỗi cáş­p nháş­t dᝯ liệu cho mĂ´-đun ÂŤ %s Âť\n" - -#, fuzzy -#~ msgid "Failed to create file for dhtlog.\n" -#~ msgstr "Lỗi tấo thĆ° m᝼c tấm thời." - #, fuzzy #~ msgid "Found peer `%s'\n" #~ msgstr "TĂ´i lĂ  đồng đẳng ÂŤ %s Âť.\n" @@ -5985,10 +6400,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "Loading udp transport plugin\n" #~ msgstr "Đang nấp cĂĄc truyᝁn tải ÂŤ %s Âť\n" -#, fuzzy -#~ msgid "Failed to load transport plugin for udp\n" -#~ msgstr "KhĂ´ng thᝃ nấp phần bổ sung truyᝁn tải ÂŤ %s Âť\n" - #, fuzzy #~ msgid "# SET QUOTA messages received" #~ msgstr "# cĂĄc thĂ´ng bĂĄo PONG đã máş­t mĂŁ được nháş­n" @@ -6029,10 +6440,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "Connection: %X: %s failed at %s:%d: `%s'\n" #~ msgstr "%s bị lỗi tấi %s:%d: ÂŤ %s Âť\n" -#, fuzzy -#~ msgid "Loading HTTP transport plugin `%s'\n" -#~ msgstr "Đang nấp cĂĄc truyᝁn tải ÂŤ %s Âť\n" - #, fuzzy #~ msgid "Failed to load transport plugin for http\n" #~ msgstr "KhĂ´ng thᝃ nấp phần bổ sung truyᝁn tải ÂŤ %s Âť\n" @@ -6097,9 +6504,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "Ok" #~ msgstr "OK" -#~ msgid "GNUnet configuration" -#~ msgstr "CẼu hĂŹnh GNUnet" - #~ msgid "" #~ "Welcome to GNUnet!\n" #~ "\n" @@ -6343,9 +6747,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ "\n" #~ "CHĆŻA lĆ°u cĂĄc thay đổi trong cẼu hĂŹnh.\n" -#~ msgid "list all network adapters" -#~ msgstr "liệt kĂŞ mọi bộ tiáşżp hᝣp mấng" - #~ msgid "install GNUnet as Windows service" #~ msgstr "cĂ i đặt GNUnet nhĆ° lĂ  một dịch v᝼ Windows" @@ -6355,9 +6756,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "display a file's hash value" #~ msgstr "hiᝃn thị giĂĄ trị tổng kiᝃm cᝧa táş­p tin" -#~ msgid "GNUnet service installed successfully.\n" -#~ msgstr "Dịch v᝼ GNUnet đã được cĂ i đặt.\n" - #~ msgid "This version of Windows doesn't support services.\n" #~ msgstr "PhiĂŞn bản Windows nĂ y khĂ´ng hỗ trᝣ dịch v᝼.\n" @@ -6964,9 +7362,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "Command `%s' requires two arguments (`%s' and `%s').\n" #~ msgstr "Câu lệnh ÂŤ %s Âť cần đến hai đối số (ÂŤ %s Âť vĂ  ÂŤ %s Âť).\n" -#~ msgid "Unsupported command `%s'. Aborting.\n" -#~ msgstr "Lệnh khĂ´ng được hỗ trᝣ ÂŤ %s Âť. Đang hᝧy bỏ.\n" - #~ msgid "# dht route host lookups performed" #~ msgstr "# cĂĄc việc tra tĂŹm đường tới mĂĄy dht được lĂ m" @@ -7314,9 +7709,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgstr "" #~ "HoĂ n thĂ nh tải xuống táş­p tin ÂŤ %s Âť. Tốc độ lĂ  %8.3f KiB một giây.\n" -#~ msgid "no name given" -#~ msgstr "chĆ°a đưa ra tĂŞn" - #~ msgid "Not enough arguments. You must specify a GNUnet file URI\n" #~ msgstr "KhĂ´ng đủ đối số. Phải ghi rĂľ một địa chỉ URI táş­p tin GNUnet\n" @@ -7329,9 +7721,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "Downloading %d files from directory `%s'.\n" #~ msgstr "Đang tải %d táş­p tin xuống thĆ° m᝼c ÂŤ %s Âť.\n" -#~ msgid "Did not find any files in directory `%s'\n" -#~ msgstr "KhĂ´ng tĂŹm thẼy táş­p tin nĂ o trong thĆ° m᝼c ÂŤ %s Âť\n" - #~ msgid "File stored as `%s'.\n" #~ msgstr "Táş­p tin được lĆ°u dấng ÂŤ %s Âť.\n" @@ -7399,9 +7788,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "# gap requests total received" #~ msgstr "# tổng số yĂŞu cầu lỗ hổng được nháş­n" -#~ msgid "# gap content total received" -#~ msgstr "# tổng số nội dung lỗ hổng được nháş­n" - #~ msgid "# gap total trust awarded" #~ msgstr "# tổng số tin cáş­y lỗ hổng được cẼp" @@ -7484,9 +7870,6 @@ msgstr "ÂŤ %s Âť thẼt bấi ở táş­p tin ÂŤ %s Âť tấi %s:%d với lỗi: %s #~ msgid "Set up multiple gnunetd daemons across multiple hosts." #~ msgstr "Thiáşżt láş­p nhiᝁu trĂŹnh nᝁn gnunetd qua nhiᝁu mĂĄy khĂĄc nhau." -#~ msgid "set number of daemons to start" -#~ msgstr "đặt số trĂŹnh nᝁn cần khởi chấy" - #~ msgid "Waiting for peers to connect" #~ msgstr "Đang đợi cĂĄc đồng đẳng káşżt nối" diff --git a/po/zh_CN.gmo b/po/zh_CN.gmo index 005c77e..6db97d6 100644 Binary files a/po/zh_CN.gmo and b/po/zh_CN.gmo differ diff --git a/po/zh_CN.po b/po/zh_CN.po index cb4721c..b50a113 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet-0.8.1\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2012-02-28 18:30+0100\n" +"POT-Creation-Date: 2012-06-05 15:47+0200\n" "PO-Revision-Date: 2011-07-09 12:12+0800\n" "Last-Translator: Wylmer Wang \n" "Language-Team: Chinese (simplified) \n" @@ -16,254 +16,269 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/arm/arm_api.c:187 +#: src/arm/arm_api.c:165 msgid "Failed to transmit shutdown request to client.\n" msgstr "" -#: src/arm/arm_api.c:378 +#: src/arm/arm_api.c:349 #, fuzzy, c-format msgid "Configuration failes to specify option `%s' in section `%s'!\n" msgstr "配置不满足配置规范文件“%s”的约束!\n" -#: src/arm/arm_api.c:392 +#: src/arm/arm_api.c:363 #, fuzzy, c-format msgid "Configuration fails to specify option `%s' in section `%s'!\n" msgstr "配置不满足配置规范文件“%s”的约束!\n" -#: src/arm/arm_api.c:467 +#: src/arm/arm_api.c:432 #, c-format msgid "Error receiving response to `%s' request from ARM for service `%s'\n" msgstr "" -#: src/arm/arm_api.c:523 +#: src/arm/arm_api.c:485 #, c-format msgid "Requesting start of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:524 +#: src/arm/arm_api.c:486 #, c-format msgid "Requesting termination of service `%s'.\n" msgstr "" -#: src/arm/arm_api.c:546 +#: src/arm/arm_api.c:507 #, c-format msgid "Error while trying to transmit request to start `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:548 +#: src/arm/arm_api.c:508 #, c-format msgid "Error while trying to transmit request to stop `%s' to ARM\n" msgstr "" -#: src/arm/arm_api.c:581 +#: src/arm/arm_api.c:540 #, c-format msgid "Asked to start service `%s' within %llu ms\n" msgstr "" -#: src/arm/arm_api.c:654 +#: src/arm/arm_api.c:612 #, c-format msgid "Stopping service `%s' within %llu ms\n" msgstr "" -#: src/arm/gnunet-arm.c:149 +#: src/arm/gnunet-arm.c:159 #, fuzzy, c-format msgid "Service `%s' is unknown to ARM.\n" msgstr "服务已删除。\n" -#: src/arm/gnunet-arm.c:154 +#: src/arm/gnunet-arm.c:164 #, fuzzy, c-format msgid "Service `%s' has been stopped.\n" msgstr "服务已删除。\n" -#: src/arm/gnunet-arm.c:157 +#: src/arm/gnunet-arm.c:167 #, fuzzy, c-format msgid "Service `%s' was already running.\n" msgstr "服务已删除。\n" -#: src/arm/gnunet-arm.c:162 +#: src/arm/gnunet-arm.c:172 #, fuzzy, c-format msgid "Service `%s' has been started.\n" msgstr "服务已删除。\n" -#: src/arm/gnunet-arm.c:165 +#: src/arm/gnunet-arm.c:175 #, fuzzy, c-format msgid "Service `%s' was already being stopped.\n" msgstr "服务已删除。\n" -#: src/arm/gnunet-arm.c:169 +#: src/arm/gnunet-arm.c:179 #, fuzzy, c-format msgid "Service `%s' was already not running.\n" msgstr "服务已删除。\n" -#: src/arm/gnunet-arm.c:173 +#: src/arm/gnunet-arm.c:183 msgid "Request ignored as ARM is shutting down.\n" msgstr "" -#: src/arm/gnunet-arm.c:177 +#: src/arm/gnunet-arm.c:187 msgid "Error communicating with ARM service.\n" msgstr "" -#: src/arm/gnunet-arm.c:181 +#: src/arm/gnunet-arm.c:191 msgid "Timeout communicating with ARM service.\n" msgstr "" -#: src/arm/gnunet-arm.c:185 +#: src/arm/gnunet-arm.c:195 msgid "Operation failed.\n" msgstr "" -#: src/arm/gnunet-arm.c:189 +#: src/arm/gnunet-arm.c:199 msgid "Unknown response code from ARM.\n" msgstr "" -#: src/arm/gnunet-arm.c:216 +#: src/arm/gnunet-arm.c:222 +#, fuzzy +msgid "Error communicating with ARM. ARM not running?\n" +msgstr "连接 %s:%u 出错。守护程序在运行吗?\n" + +#: src/arm/gnunet-arm.c:225 +msgid "Running services:\n" +msgstr "" + +#: src/arm/gnunet-arm.c:249 #, c-format msgid "Fatal configuration error: `%s' option in section `%s' missing.\n" msgstr "" -#: src/arm/gnunet-arm.c:224 src/arm/gnunet-arm.c:324 +#: src/arm/gnunet-arm.c:257 src/arm/gnunet-arm.c:357 src/arm/gnunet-arm.c:373 msgid "Fatal error initializing ARM API.\n" msgstr "" -#: src/arm/gnunet-arm.c:247 +#: src/arm/gnunet-arm.c:280 #, fuzzy, c-format msgid "Failed to remove configuration file %s\n" msgstr "解析配置文件“%s”失败\n" -#: src/arm/gnunet-arm.c:253 +#: src/arm/gnunet-arm.c:286 #, c-format msgid "Failed to remove servicehome directory %s\n" msgstr "" -#: src/arm/gnunet-arm.c:355 +#: src/arm/gnunet-arm.c:407 #, fuzzy msgid "stop all GNUnet services" msgstr "卸载 GNUnet 服务" -#: src/arm/gnunet-arm.c:357 +#: src/arm/gnunet-arm.c:409 msgid "start a particular service" msgstr "" -#: src/arm/gnunet-arm.c:359 +#: src/arm/gnunet-arm.c:411 msgid "stop a particular service" msgstr "" -#: src/arm/gnunet-arm.c:361 +#: src/arm/gnunet-arm.c:413 #, fuzzy msgid "start all GNUnet default services" msgstr "卸载 GNUnet 服务" -#: src/arm/gnunet-arm.c:364 +#: src/arm/gnunet-arm.c:416 #, fuzzy msgid "stop and start all GNUnet default services" msgstr "卸载 GNUnet 服务" -#: src/arm/gnunet-arm.c:367 +#: src/arm/gnunet-arm.c:419 msgid "delete config file and directory on exit" msgstr "" -#: src/arm/gnunet-arm.c:369 +#: src/arm/gnunet-arm.c:421 msgid "don't print status messages" msgstr "" -#: src/arm/gnunet-arm.c:372 +#: src/arm/gnunet-arm.c:424 #, fuzzy msgid "timeout for completing current operation" msgstr "等待一次迭代完成的时间(毫秒)" -#: src/arm/gnunet-arm.c:383 +#: src/arm/gnunet-arm.c:426 +msgid "List currently running services" +msgstr "" + +#: src/arm/gnunet-arm.c:437 msgid "Control services and the Automated Restart Manager (ARM)" msgstr "" -#: src/arm/gnunet-service-arm.c:328 +#: src/arm/gnunet-service-arm.c:332 #, fuzzy, c-format msgid "Failed to start service `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/arm/gnunet-service-arm.c:331 +#: src/arm/gnunet-service-arm.c:335 #, c-format msgid "Starting service `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:357 +#: src/arm/gnunet-service-arm.c:361 msgid "Could not send status result to client\n" msgstr "" -#: src/arm/gnunet-service-arm.c:484 +#: src/arm/gnunet-service-arm.c:393 +#, fuzzy +msgid "Could not send list result to client\n" +msgstr "找不到接口“%s”的一个 IP 地址。\n" + +#: src/arm/gnunet-service-arm.c:523 #, fuzzy, c-format msgid "Unable to create socket for service `%s': %s\n" msgstr "无法创建用户账户:" -#: src/arm/gnunet-service-arm.c:506 +#: src/arm/gnunet-service-arm.c:545 #, c-format msgid "Unable to bind listening socket for service `%s' to address `%s': %s\n" msgstr "" -#: src/arm/gnunet-service-arm.c:520 +#: src/arm/gnunet-service-arm.c:559 #, c-format msgid "ARM now monitors connections to service `%s' at `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:628 +#: src/arm/gnunet-service-arm.c:667 #, c-format msgid "Preparing to stop `%s'\n" msgstr "" -#: src/arm/gnunet-service-arm.c:782 +#: src/arm/gnunet-service-arm.c:878 #, c-format msgid "Restarting service `%s'.\n" msgstr "" -#: src/arm/gnunet-service-arm.c:877 +#: src/arm/gnunet-service-arm.c:970 msgid "exit" msgstr "" -#: src/arm/gnunet-service-arm.c:882 +#: src/arm/gnunet-service-arm.c:975 msgid "signal" msgstr "" -#: src/arm/gnunet-service-arm.c:887 +#: src/arm/gnunet-service-arm.c:980 #, fuzzy msgid "unknown" msgstr "未知错误" -#: src/arm/gnunet-service-arm.c:921 +#: src/arm/gnunet-service-arm.c:986 +#, fuzzy, c-format +msgid "Service `%s' took %llu ms to terminate\n" +msgstr "服务已删除。\n" + +#: src/arm/gnunet-service-arm.c:1021 #, c-format msgid "Service `%s' terminated with status %s/%d, will restart in %llu ms\n" msgstr "" -#: src/arm/gnunet-service-arm.c:967 src/arm/mockup-service.c:41 -msgid "Failed to transmit shutdown ACK.\n" -msgstr "" - -#: src/arm/gnunet-service-arm.c:1067 +#: src/arm/gnunet-service-arm.c:1127 #, fuzzy, c-format msgid "Configuration file `%s' for service `%s' not valid: %s\n" msgstr "配置文件“%s”已写入。\n" -#: src/arm/gnunet-service-arm.c:1069 +#: src/arm/gnunet-service-arm.c:1129 msgid "option missing" msgstr "" -#: src/arm/gnunet-service-arm.c:1152 +#: src/arm/gnunet-service-arm.c:1213 #, fuzzy, c-format msgid "Starting default services `%s'\n" msgstr "卸载 GNUnet 服务" -#: src/arm/gnunet-service-arm.c:1163 +#: src/arm/gnunet-service-arm.c:1224 #, c-format msgid "Default service `%s' not configured correctly!\n" msgstr "" -#: src/arm/gnunet-service-arm.c:1177 +#: src/arm/gnunet-service-arm.c:1238 msgid "" "No default services configured, GNUnet will not really start right now.\n" msgstr "" -#: src/arm/mockup-service.c:46 -msgid "Transmitting shutdown ACK.\n" -msgstr "" - -#: src/arm/mockup-service.c:69 +#: src/arm/mockup-service.c:44 msgid "Initiating shutdown as requested by client.\n" msgstr "" @@ -321,194 +336,197 @@ msgstr "" msgid "Undefined mandatory parameter: memberCallback\n" msgstr "" -#: src/chat/gnunet-chat.c:92 +#: src/chat/gnunet-chat.c:93 msgid "Joined\n" msgstr "" -#: src/chat/gnunet-chat.c:124 +#: src/chat/gnunet-chat.c:125 src/chat/gnunet-chat.c:133 +#: src/chat/gnunet-chat.c:213 src/chat/gnunet-chat.c:253 +#: src/chat/gnunet-chat.c:329 src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:400 src/chat/gnunet-chat.c:700 msgid "anonymous" msgstr "匿名" -#: src/chat/gnunet-chat.c:130 +#: src/chat/gnunet-chat.c:144 #, fuzzy, c-format msgid "(%s) `%s' said: %s\n" msgstr "“%s”说:%s\n" -#: src/chat/gnunet-chat.c:133 src/chat/gnunet-chat.c:136 +#: src/chat/gnunet-chat.c:147 src/chat/gnunet-chat.c:150 #, fuzzy, c-format msgid "(%s) `%s' said to you: %s\n" msgstr "“%s”对您说:%s\n" -#: src/chat/gnunet-chat.c:139 +#: src/chat/gnunet-chat.c:153 #, fuzzy, c-format msgid "(%s) `%s' said for sure: %s\n" msgstr "“%s”对您说:%s\n" -#: src/chat/gnunet-chat.c:142 +#: src/chat/gnunet-chat.c:156 #, fuzzy, c-format msgid "(%s) `%s' said to you for sure: %s\n" msgstr "“%s”对您说:%s\n" -#: src/chat/gnunet-chat.c:145 +#: src/chat/gnunet-chat.c:159 #, c-format msgid "(%s) `%s' was confirmed that you received: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:148 +#: src/chat/gnunet-chat.c:162 #, c-format msgid "(%s) `%s' was confirmed that you and only you received: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:151 +#: src/chat/gnunet-chat.c:165 #, c-format msgid "(%s) `%s' was confirmed that you received from him or her: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:156 +#: src/chat/gnunet-chat.c:170 #, c-format msgid "" "(%s) `%s' was confirmed that you and only you received from him or her: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:159 +#: src/chat/gnunet-chat.c:173 #, fuzzy, c-format msgid "(%s) `%s' said off the record: %s\n" msgstr "“%s”对您说:%s\n" -#: src/chat/gnunet-chat.c:162 +#: src/chat/gnunet-chat.c:176 #, c-format msgid "(%s) <%s> said using an unknown message type: %s\n" msgstr "" -#: src/chat/gnunet-chat.c:193 +#: src/chat/gnunet-chat.c:217 #, c-format msgid "'%s' acknowledged message #%d\n" msgstr "" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' entered the room\n" msgstr "“%s”进入了房间\n" -#: src/chat/gnunet-chat.c:224 +#: src/chat/gnunet-chat.c:260 #, c-format msgid "`%s' left the room\n" msgstr "“%s”离开了房间\n" -#: src/chat/gnunet-chat.c:284 src/chat/gnunet-chat.c:316 +#: src/chat/gnunet-chat.c:321 src/chat/gnunet-chat.c:363 #, fuzzy msgid "Could not change username\n" msgstr "已将用户名改为“%s”。\n" -#: src/chat/gnunet-chat.c:288 src/chat/gnunet-chat.c:630 +#: src/chat/gnunet-chat.c:334 src/chat/gnunet-chat.c:702 #, c-format msgid "Joining room `%s' as user `%s'...\n" msgstr "" -#: src/chat/gnunet-chat.c:320 +#: src/chat/gnunet-chat.c:373 #, fuzzy, c-format msgid "Changed username to `%s'\n" msgstr "已将用户名改为“%s”。\n" -#: src/chat/gnunet-chat.c:333 +#: src/chat/gnunet-chat.c:388 #, c-format msgid "Users in room `%s': " msgstr "房间“%s”中的用户:" -#: src/chat/gnunet-chat.c:371 +#: src/chat/gnunet-chat.c:434 msgid "Syntax: /msg USERNAME MESSAGE" msgstr "语法:/msg 用户名 月息" -#: src/chat/gnunet-chat.c:379 +#: src/chat/gnunet-chat.c:443 #, c-format -msgid "Unknown user `%s'\n" -msgstr "未知的用户“%s”\n" +msgid "Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n" +msgstr "" -#: src/chat/gnunet-chat.c:395 +#: src/chat/gnunet-chat.c:460 #, c-format msgid "User `%s' is currently not in the room!\n" msgstr "用户“%s”当前不在房间里!\n" -#: src/chat/gnunet-chat.c:448 +#: src/chat/gnunet-chat.c:513 #, fuzzy, c-format msgid "Unknown command `%s'\n" msgstr "未知的命令“%s”。\n" -#: src/chat/gnunet-chat.c:459 +#: src/chat/gnunet-chat.c:524 msgid "" "Use `/join #roomname' to join a chat room. Joining a room will cause you to " "leave the current room" msgstr "" -#: src/chat/gnunet-chat.c:463 +#: src/chat/gnunet-chat.c:528 msgid "" "Use `/nick nickname' to change your nickname. This will cause you to leave " "the current room and immediately rejoin it with the new name." msgstr "" -#: src/chat/gnunet-chat.c:467 +#: src/chat/gnunet-chat.c:532 msgid "" "Use `/msg nickname message' to send a private message to the specified user" msgstr "" -#: src/chat/gnunet-chat.c:470 +#: src/chat/gnunet-chat.c:535 msgid "The `/notice' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:472 +#: src/chat/gnunet-chat.c:537 msgid "The `/query' command is an alias for `/msg'" msgstr "" -#: src/chat/gnunet-chat.c:474 +#: src/chat/gnunet-chat.c:539 msgid "Use `/sig message' to send a signed public message" msgstr "" -#: src/chat/gnunet-chat.c:477 +#: src/chat/gnunet-chat.c:542 msgid "Use `/ack message' to require signed acknowledgment of the message" msgstr "" -#: src/chat/gnunet-chat.c:480 +#: src/chat/gnunet-chat.c:545 msgid "Use `/anonymous message' to send a public anonymous message" msgstr "" -#: src/chat/gnunet-chat.c:482 +#: src/chat/gnunet-chat.c:547 msgid "The `/anon' command is an alias for `/anonymous'" msgstr "" -#: src/chat/gnunet-chat.c:484 +#: src/chat/gnunet-chat.c:549 msgid "Use `/quit' to terminate gnunet-chat" msgstr "" -#: src/chat/gnunet-chat.c:486 +#: src/chat/gnunet-chat.c:551 msgid "The `/leave' command is an alias for `/quit'" msgstr "" -#: src/chat/gnunet-chat.c:489 +#: src/chat/gnunet-chat.c:554 msgid "Use `/names' to list all of the current members in the chat room" msgstr "" -#: src/chat/gnunet-chat.c:491 +#: src/chat/gnunet-chat.c:556 msgid "Use `/help command' to get help for a specific command" msgstr "" -#: src/chat/gnunet-chat.c:606 +#: src/chat/gnunet-chat.c:672 msgid "You must specify a nickname\n" msgstr "您必须指定一个昵称\n" -#: src/chat/gnunet-chat.c:622 +#: src/chat/gnunet-chat.c:688 #, c-format msgid "Failed to join room `%s'\n" msgstr "" -#: src/chat/gnunet-chat.c:655 +#: src/chat/gnunet-chat.c:727 msgid "set the nickname to use (required)" msgstr "设置要使用的昵称(必须)" -#: src/chat/gnunet-chat.c:658 +#: src/chat/gnunet-chat.c:730 msgid "set the chat room to join" msgstr "设置要加入的聊天室" -#: src/chat/gnunet-chat.c:670 +#: src/chat/gnunet-chat.c:742 msgid "Join a chat on GNUnet." msgstr "" @@ -532,166 +550,167 @@ msgstr "保存配置失败。" msgid "Failed to queue a leave notification\n" msgstr "保存配置失败。" -#: src/core/core_api.c:798 +#: src/core/core_api.c:786 msgid "Client was disconnected from core service, trying to reconnect.\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:77 -#: src/peerinfo-tool/gnunet-peerinfo.c:60 +#: src/core/gnunet-core.c:54 src/peerinfo-tool/gnunet-peerinfo.c:286 #, c-format msgid "Peer `%s'\n" msgstr "" -#: src/core/gnunet-core-list-connections.c:175 -#: src/peerinfo-tool/gnunet-peerinfo.c:194 +#: src/core/gnunet-core.c:72 src/peerinfo-tool/gnunet-peerinfo.c:817 #, fuzzy, c-format msgid "Invalid command line argument `%s'\n" msgstr "“%s”的参数无效。\n" -#: src/core/gnunet-core-list-connections.c:196 -#: src/peerinfo-tool/gnunet-peerinfo.c:252 -msgid "don't resolve host names" -msgstr "" - -#: src/core/gnunet-core-list-connections.c:203 +#: src/core/gnunet-core.c:95 msgid "Print information about connected peers." msgstr "" -#: src/core/gnunet-service-core.c:99 +#: src/core/gnunet-service-core.c:97 #, c-format msgid "Core service of `%4s' ready.\n" msgstr "" -#: src/core/gnunet-service-core_clients.c:360 +#: src/core/gnunet-service-core_clients.c:370 msgid "# send requests dropped (disconnected)" msgstr "" -#: src/core/gnunet-service-core_clients.c:465 +#: src/core/gnunet-service-core_clients.c:475 msgid "# messages discarded (session disconnected)" msgstr "" -#: src/core/gnunet-service-core_clients.c:801 +#: src/core/gnunet-service-core_clients.c:818 #, c-format msgid "# bytes of messages of type %u received" msgstr "" -#: src/core/gnunet-service-core_kx.c:493 +#: src/core/gnunet-service-core_kx.c:565 msgid "# bytes encrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:543 +#: src/core/gnunet-service-core_kx.c:617 msgid "# bytes decrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:604 src/dv/gnunet-service-dv.c:3002 -#: src/hostlist/hostlist-server.c:436 src/peerinfo-tool/gnunet-peerinfo.c:151 +#: src/core/gnunet-service-core_kx.c:681 src/dv/gnunet-service-dv.c:3003 msgid "Error in communication with PEERINFO service\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:623 +#: src/core/gnunet-service-core_kx.c:700 msgid "# Delayed connecting due to lack of public key" msgstr "" -#: src/core/gnunet-service-core_kx.c:673 +#: src/core/gnunet-service-core_kx.c:753 msgid "# key exchanges initiated" msgstr "" -#: src/core/gnunet-service-core_kx.c:694 +#: src/core/gnunet-service-core_kx.c:775 msgid "# key exchanges stopped" msgstr "" -#: src/core/gnunet-service-core_kx.c:746 +#: src/core/gnunet-service-core_kx.c:828 msgid "# session keys received" msgstr "" -#: src/core/gnunet-service-core_kx.c:765 +#: src/core/gnunet-service-core_kx.c:845 #, c-format msgid "`%s' is for `%s', not for me. Ignoring.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:803 +#: src/core/gnunet-service-core_kx.c:890 msgid "# SET_KEY messages decrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:883 -#: src/transport/gnunet-service-transport_validation.c:803 +#: src/core/gnunet-service-core_kx.c:977 +#: src/transport/gnunet-service-transport_validation.c:810 msgid "# PING messages received" msgstr "" -#: src/core/gnunet-service-core_kx.c:917 +#: src/core/gnunet-service-core_kx.c:1010 #, c-format msgid "" "Received PING from `%s' for different identity: I am `%s', PONG identity: `" "%s'\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:938 +#: src/core/gnunet-service-core_kx.c:1029 msgid "# PONG messages created" msgstr "" -#: src/core/gnunet-service-core_kx.c:1026 +#: src/core/gnunet-service-core_kx.c:1125 msgid "# sessions terminated by timeout" msgstr "" -#: src/core/gnunet-service-core_kx.c:1037 +#: src/core/gnunet-service-core_kx.c:1135 msgid "# keepalive messages sent" msgstr "" -#: src/core/gnunet-service-core_kx.c:1095 -#: src/transport/gnunet-service-transport_validation.c:1026 +#: src/core/gnunet-service-core_kx.c:1236 +#: src/transport/gnunet-service-transport_validation.c:1031 msgid "# PONG messages received" msgstr "" -#: src/core/gnunet-service-core_kx.c:1125 +#: src/core/gnunet-service-core_kx.c:1275 msgid "# PONG messages decrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:1157 +#: src/core/gnunet-service-core_kx.c:1303 msgid "# session keys confirmed via PONG" msgstr "" -#: src/core/gnunet-service-core_kx.c:1223 +#: src/core/gnunet-service-core_kx.c:1329 +msgid "# rekey operations confirmed via PONG" +msgstr "" + +#: src/core/gnunet-service-core_kx.c:1381 +#: src/core/gnunet-service-core_kx.c:1398 msgid "# SET_KEY and PING messages created" msgstr "" -#: src/core/gnunet-service-core_kx.c:1364 +#: src/core/gnunet-service-core_kx.c:1402 +msgid "# REKEY operations performed" +msgstr "" + +#: src/core/gnunet-service-core_kx.c:1537 msgid "# failed to decrypt message (no session key)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1406 -#: src/core/gnunet-service-core_kx.c:1431 +#: src/core/gnunet-service-core_kx.c:1577 +#: src/core/gnunet-service-core_kx.c:1602 msgid "# bytes dropped (duplicates)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1418 +#: src/core/gnunet-service-core_kx.c:1589 msgid "# bytes dropped (out of sequence)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1455 +#: src/core/gnunet-service-core_kx.c:1626 #, c-format msgid "Message received far too old (%llu ms). Content ignored.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1459 +#: src/core/gnunet-service-core_kx.c:1630 msgid "# bytes dropped (ancient message)" msgstr "" -#: src/core/gnunet-service-core_kx.c:1467 +#: src/core/gnunet-service-core_kx.c:1638 msgid "# bytes of payload decrypted" msgstr "" -#: src/core/gnunet-service-core_kx.c:1528 +#: src/core/gnunet-service-core_kx.c:1700 #, fuzzy msgid "Core service is lacking HOSTKEY configuration setting. Exiting.\n" msgstr "立即保存配置?" -#: src/core/gnunet-service-core_kx.c:1536 +#: src/core/gnunet-service-core_kx.c:1708 msgid "Core service could not access hostkey. Exiting.\n" msgstr "" -#: src/core/gnunet-service-core_kx.c:1546 src/hostlist/hostlist-server.c:555 -#: src/peerinfo-tool/gnunet-peerinfo.c:202 -#: src/transport/gnunet-service-transport.c:595 +#: src/core/gnunet-service-core_kx.c:1718 src/hostlist/hostlist-server.c:551 +#: src/peerinfo-tool/gnunet-peerinfo.c:823 +#: src/transport/gnunet-service-transport.c:611 msgid "Could not access PEERINFO service. Exiting.\n" msgstr "" @@ -700,29 +719,39 @@ msgid "# sessions terminated by transport disconnect" msgstr "" #: src/core/gnunet-service-core_neighbours.c:180 -#: src/core/gnunet-service-core_neighbours.c:342 +#: src/core/gnunet-service-core_neighbours.c:334 msgid "# neighbour entries allocated" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:251 +#: src/core/gnunet-service-core_neighbours.c:247 msgid "# encrypted bytes given to transport" msgstr "" -#: src/core/gnunet-service-core_neighbours.c:430 +#: src/core/gnunet-service-core_neighbours.c:418 #, c-format msgid "Unsupported message of type %u (%u bytes) received from peer `%s'\n" msgstr "" -#: src/core/gnunet-service-core_sessions.c:208 -#: src/core/gnunet-service-core_sessions.c:273 -msgid "# entries in session map" +#: src/core/gnunet-service-core_sessions.c:206 +#: src/core/gnunet-service-core_sessions.c:269 +#: src/dht/gnunet-service-dht_neighbours.c:625 +#: src/dht/gnunet-service-dht_neighbours.c:683 +#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 +#: src/topology/gnunet-daemon-topology.c:709 +#: src/topology/gnunet-daemon-topology.c:810 +#: src/transport/gnunet-service-transport_neighbours.c:874 +#: src/transport/gnunet-service-transport_neighbours.c:1080 +#: src/transport/gnunet-service-transport_neighbours.c:1089 +#: src/transport/gnunet-service-transport_neighbours.c:2568 +#: src/transport/gnunet-service-transport_neighbours.c:2814 +msgid "# peers connected" msgstr "" -#: src/core/gnunet-service-core_sessions.c:238 +#: src/core/gnunet-service-core_sessions.c:236 msgid "# type map refreshes sent" msgstr "" -#: src/core/gnunet-service-core_sessions.c:414 +#: src/core/gnunet-service-core_sessions.c:406 msgid "# messages discarded (expired prior to transmission)" msgstr "" @@ -735,400 +764,377 @@ msgstr "" msgid "# updates to my type map" msgstr "" -#: src/datacache/datacache.c:118 src/datacache/datacache.c:255 -#: src/datastore/gnunet-service-datastore.c:854 +#: src/datacache/datacache.c:115 src/datacache/datacache.c:250 +#: src/datastore/gnunet-service-datastore.c:834 msgid "# bytes stored" msgstr "" -#: src/datacache/datacache.c:144 src/datacache/datacache.c:151 -#: src/datastore/gnunet-service-datastore.c:1531 -#: src/datastore/gnunet-service-datastore.c:1542 +#: src/datacache/datacache.c:141 src/datacache/datacache.c:148 +#: src/datastore/gnunet-service-datastore.c:1483 +#: src/datastore/gnunet-service-datastore.c:1494 #, c-format msgid "No `%s' specified for `%s' in configuration!\n" msgstr "" -#: src/datacache/datacache.c:183 +#: src/datacache/datacache.c:180 #, c-format msgid "Loading `%s' datacache plugin\n" msgstr "" -#: src/datacache/datacache.c:191 +#: src/datacache/datacache.c:188 #, c-format msgid "Failed to load datacache plugin for `%s'\n" msgstr "" -#: src/datacache/datacache.c:281 +#: src/datacache/datacache.c:276 msgid "# requests received" msgstr "" -#: src/datacache/datacache.c:291 +#: src/datacache/datacache.c:284 msgid "# requests filtered by bloom filter" msgstr "" -#: src/datacache/plugin_datacache_mysql.c:103 -#: src/datacache/plugin_datacache_mysql.c:110 -#: src/datacache/plugin_datacache_mysql.c:517 -#: src/datacache/plugin_datacache_mysql.c:526 -#: src/datacache/plugin_datacache_mysql.c:598 -#: src/datacache/plugin_datacache_mysql.c:614 -#: src/datacache/plugin_datacache_sqlite.c:71 -#: src/datacache/plugin_datacache_sqlite.c:74 -#: src/datastore/plugin_datastore_mysql.c:139 -#: src/datastore/plugin_datastore_mysql.c:146 -#: src/datastore/plugin_datastore_mysql.c:613 -#: src/datastore/plugin_datastore_mysql.c:673 -#: src/datastore/plugin_datastore_mysql.c:685 -#: src/datastore/plugin_datastore_mysql.c:1362 -#: src/datastore/plugin_datastore_mysql.c:1376 -#: src/datastore/plugin_datastore_sqlite.c:61 -#: src/namestore/plugin_namestore_sqlite.c:49 src/util/crypto_ksk.c:49 -#: src/util/crypto_rsa.c:92 src/include/gnunet_common.h:507 -#: src/include/gnunet_common.h:514 +#: src/datacache/plugin_datacache_mysql.c:97 +#: src/datacache/plugin_datacache_mysql.c:104 +#: src/datacache/plugin_datacache_sqlite.c:69 +#: src/datacache/plugin_datacache_sqlite.c:72 +#: src/datastore/plugin_datastore_mysql.c:803 +#: src/datastore/plugin_datastore_mysql.c:817 +#: src/datastore/plugin_datastore_sqlite.c:57 src/mysql/mysql.c:41 +#: src/mysql/mysql.c:48 src/mysql/mysql.c:522 src/mysql/mysql.c:531 +#: src/mysql/mysql.c:591 src/mysql/mysql.c:607 +#: src/namestore/plugin_namestore_sqlite.c:51 src/util/crypto_ksk.c:49 +#: src/util/crypto_rsa.c:67 src/include/gnunet_common.h:525 +#: src/include/gnunet_common.h:532 #, fuzzy, c-format msgid "`%s' failed at %s:%d with error: %s\n" msgstr "“%s”于 %s:%d 处失败,错误为:%s\n" -#: src/datacache/plugin_datacache_mysql.c:224 -#: src/datastore/plugin_datastore_mysql.c:316 -#, c-format -msgid "Trying to use file `%s' for MySQL configuration.\n" -msgstr "" - -#: src/datacache/plugin_datacache_mysql.c:230 -#: src/datastore/plugin_datastore_mysql.c:322 -#, fuzzy, c-format -msgid "Could not access file `%s': %s\n" -msgstr "无法解析“%s”(%s):%s\n" - -#: src/datacache/plugin_datacache_mysql.c:979 +#: src/datacache/plugin_datacache_mysql.c:450 msgid "MySQL datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_postgres.c:79 -#: src/datastore/plugin_datastore_postgres.c:93 -#, fuzzy, c-format -msgid "`%s:%s' failed at %s:%d with error: %s" -msgstr "“%s”于 %s:%d 处失败,错误为:%s\n" - -#: src/datacache/plugin_datacache_postgres.c:149 -#, fuzzy, c-format -msgid "Unable to initialize Postgres: %s" -msgstr "无法初始化 SQLite:%s。\n" - -#: src/datacache/plugin_datacache_postgres.c:499 +#: src/datacache/plugin_datacache_postgres.c:367 msgid "Postgres datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:424 +#: src/datacache/plugin_datacache_sqlite.c:410 msgid "Sqlite datacache running\n" msgstr "" -#: src/datacache/plugin_datacache_sqlite.c:457 -#: src/datastore/plugin_datastore_sqlite.c:414 -#: src/namestore/plugin_namestore_sqlite.c:381 +#: src/datacache/plugin_datacache_sqlite.c:443 +#: src/datastore/plugin_datastore_sqlite.c:408 +#: src/namestore/plugin_namestore_sqlite.c:370 msgid "Tried to close sqlite without finalizing all prepared statements.\n" msgstr "" +#: src/datacache/plugin_datacache_sqlite.c:450 +#, fuzzy, c-format +msgid "Failed to close statement %p: %d\n" +msgstr "解析配置文件“%s”失败\n" + #: src/datacache/plugin_datacache_template.c:121 msgid "Template datacache running\n" msgstr "" -#: src/datastore/datastore_api.c:289 +#: src/datastore/datastore_api.c:305 msgid "Failed to transmit request to drop database.\n" msgstr "" -#: src/datastore/datastore_api.c:372 +#: src/datastore/datastore_api.c:388 msgid "# queue entry timeouts" msgstr "" -#: src/datastore/datastore_api.c:418 +#: src/datastore/datastore_api.c:432 msgid "# queue overflows" msgstr "" -#: src/datastore/datastore_api.c:445 +#: src/datastore/datastore_api.c:459 msgid "# queue entries created" msgstr "" -#: src/datastore/datastore_api.c:465 +#: src/datastore/datastore_api.c:477 msgid "# Requests dropped from datastore queue" msgstr "" -#: src/datastore/datastore_api.c:513 +#: src/datastore/datastore_api.c:525 msgid "# datastore connections (re)created" msgstr "" -#: src/datastore/datastore_api.c:540 +#: src/datastore/datastore_api.c:548 msgid "# reconnected to DATASTORE" msgstr "" -#: src/datastore/datastore_api.c:608 +#: src/datastore/datastore_api.c:612 msgid "# transmission request failures" msgstr "" -#: src/datastore/datastore_api.c:631 +#: src/datastore/datastore_api.c:633 msgid "# bytes sent to datastore" msgstr "" -#: src/datastore/datastore_api.c:772 +#: src/datastore/datastore_api.c:764 msgid "Failed to receive status response from database." msgstr "" -#: src/datastore/datastore_api.c:786 +#: src/datastore/datastore_api.c:778 msgid "Error reading response from datastore service" msgstr "" -#: src/datastore/datastore_api.c:798 src/datastore/datastore_api.c:804 +#: src/datastore/datastore_api.c:790 src/datastore/datastore_api.c:796 msgid "Invalid error message received from datastore service" msgstr "" -#: src/datastore/datastore_api.c:810 +#: src/datastore/datastore_api.c:800 msgid "# status messages received" msgstr "" -#: src/datastore/datastore_api.c:883 +#: src/datastore/datastore_api.c:869 msgid "# PUT requests executed" msgstr "" -#: src/datastore/datastore_api.c:954 +#: src/datastore/datastore_api.c:936 msgid "# RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1019 +#: src/datastore/datastore_api.c:997 msgid "# RELEASE RESERVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1080 +#: src/datastore/datastore_api.c:1054 msgid "# UPDATE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1148 +#: src/datastore/datastore_api.c:1118 msgid "# REMOVE requests executed" msgstr "" -#: src/datastore/datastore_api.c:1193 +#: src/datastore/datastore_api.c:1163 msgid "Failed to receive response from database.\n" msgstr "" -#: src/datastore/datastore_api.c:1253 +#: src/datastore/datastore_api.c:1221 msgid "# Results received" msgstr "" -#: src/datastore/datastore_api.c:1324 +#: src/datastore/datastore_api.c:1286 msgid "# GET REPLICATION requests executed" msgstr "" -#: src/datastore/datastore_api.c:1391 +#: src/datastore/datastore_api.c:1349 msgid "# GET ZERO ANONYMITY requests executed" msgstr "" -#: src/datastore/datastore_api.c:1455 +#: src/datastore/datastore_api.c:1409 msgid "# GET requests executed" msgstr "" -#: src/datastore/gnunet-service-datastore.c:351 +#: src/datastore/gnunet-service-datastore.c:349 msgid "# bytes expired" msgstr "" -#: src/datastore/gnunet-service-datastore.c:426 +#: src/datastore/gnunet-service-datastore.c:422 msgid "# bytes purged (low-priority)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:486 +#: src/datastore/gnunet-service-datastore.c:480 msgid "Transmission to client failed!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:640 +#: src/datastore/gnunet-service-datastore.c:511 +msgid "Shutdown in progress, aborting transmission.\n" +msgstr "" + +#: src/datastore/gnunet-service-datastore.c:626 msgid "# results found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:685 +#: src/datastore/gnunet-service-datastore.c:669 #, c-format msgid "" "Insufficient space (%llu bytes are available) to satisfy `%s' request for " "%llu bytes\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:696 +#: src/datastore/gnunet-service-datastore.c:680 #, c-format msgid "" "The requested amount (%llu bytes) is larger than the cache size (%llu " "bytes)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:700 +#: src/datastore/gnunet-service-datastore.c:684 msgid "" "Insufficient space to satisfy request and requested amount is larger than " "cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:706 +#: src/datastore/gnunet-service-datastore.c:690 msgid "Insufficient space to satisfy request" msgstr "" -#: src/datastore/gnunet-service-datastore.c:711 -#: src/datastore/gnunet-service-datastore.c:765 -#: src/datastore/gnunet-service-datastore.c:986 -#: src/datastore/gnunet-service-datastore.c:1465 +#: src/datastore/gnunet-service-datastore.c:695 +#: src/datastore/gnunet-service-datastore.c:747 +#: src/datastore/gnunet-service-datastore.c:960 +#: src/datastore/gnunet-service-datastore.c:1417 msgid "# reserved" msgstr "" -#: src/datastore/gnunet-service-datastore.c:780 +#: src/datastore/gnunet-service-datastore.c:760 msgid "Could not find matching reservation" msgstr "" -#: src/datastore/gnunet-service-datastore.c:868 +#: src/datastore/gnunet-service-datastore.c:846 #, c-format msgid "Need %llu bytes more space (%llu allowed, using %llu)\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1034 +#: src/datastore/gnunet-service-datastore.c:1006 msgid "# GET requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1048 +#: src/datastore/gnunet-service-datastore.c:1018 msgid "# requests filtered by bloomfilter" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1076 +#: src/datastore/gnunet-service-datastore.c:1046 msgid "# UPDATE requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1110 +#: src/datastore/gnunet-service-datastore.c:1076 msgid "# GET REPLICATION requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1145 +#: src/datastore/gnunet-service-datastore.c:1109 msgid "# GET ZERO ANONYMITY requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1172 +#: src/datastore/gnunet-service-datastore.c:1134 msgid "Content not found" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1182 +#: src/datastore/gnunet-service-datastore.c:1142 msgid "# bytes removed (explicit request)" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1216 +#: src/datastore/gnunet-service-datastore.c:1174 msgid "# REMOVE requests received" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1260 +#: src/datastore/gnunet-service-datastore.c:1216 #, c-format msgid "Datastore payload inaccurate (%lld < %lld). Trying to fix.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1323 +#: src/datastore/gnunet-service-datastore.c:1277 #, c-format msgid "Loading `%s' datastore plugin\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1332 +#: src/datastore/gnunet-service-datastore.c:1286 #, fuzzy, c-format msgid "Failed to load datastore plugin for `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/datastore/gnunet-service-datastore.c:1536 +#: src/datastore/gnunet-service-datastore.c:1488 #, c-format msgid "# bytes used in file-sharing datastore `%s'" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1547 +#: src/datastore/gnunet-service-datastore.c:1499 msgid "# quota" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1549 +#: src/datastore/gnunet-service-datastore.c:1501 msgid "# cache size" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1562 +#: src/datastore/gnunet-service-datastore.c:1514 #, c-format msgid "Could not use specified filename `%s' for bloomfilter.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1580 -#: src/datastore/gnunet-service-datastore.c:1596 +#: src/datastore/gnunet-service-datastore.c:1532 +#: src/datastore/gnunet-service-datastore.c:1548 #, fuzzy, c-format msgid "Failed to remove bogus bloomfilter file `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/datastore/gnunet-service-datastore.c:1626 +#: src/datastore/gnunet-service-datastore.c:1578 #, fuzzy msgid "Failed to initialize bloomfilter.\n" msgstr "初始化“%s”服务失败。\n" -#: src/datastore/gnunet-service-datastore.c:1655 +#: src/datastore/gnunet-service-datastore.c:1607 msgid "Rebuilding bloomfilter. Please be patient.\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1660 +#: src/datastore/gnunet-service-datastore.c:1612 msgid "Plugin does not support get_keys function. Please fix!\n" msgstr "" -#: src/datastore/gnunet-service-datastore.c:1663 +#: src/datastore/gnunet-service-datastore.c:1615 msgid "Bloomfilter construction complete.\n" msgstr "" -#: src/datastore/plugin_datastore_mysql.c:529 -#: src/datastore/plugin_datastore_mysql.c:1336 +#: src/datastore/plugin_datastore_mysql.c:780 #, fuzzy, c-format msgid "Failed to prepare statement `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/datastore/plugin_datastore_mysql.c:622 -#: src/datastore/plugin_datastore_mysql.c:1346 +#: src/datastore/plugin_datastore_mysql.c:788 #, fuzzy, c-format msgid "`%s' for `%s' failed at %s:%d with error: %s\n" msgstr "“%s”于 %s:%d 处失败,错误为:%s\n" -#: src/datastore/plugin_datastore_mysql.c:1581 +#: src/datastore/plugin_datastore_mysql.c:1019 msgid "Mysql database running\n" msgstr "" -#: src/datastore/plugin_datastore_postgres.c:173 -#, fuzzy, c-format -msgid "Unable to initialize Postgres with configuration `%s': %s" -msgstr "无法保存配置文件“%s”:" +#: src/datastore/plugin_datastore_postgres.c:824 +#, fuzzy +msgid "Failed to drop table from database.\n" +msgstr "发送消息失败。\n" -#: src/datastore/plugin_datastore_postgres.c:1017 +#: src/datastore/plugin_datastore_postgres.c:860 msgid "Postgres database running\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:61 +#: src/datastore/plugin_datastore_sqlite.c:57 #, fuzzy, c-format msgid "`%s' failed at %s:%u with error: %s" msgstr "“%s”于 %s:%d 处失败,错误为:%s\n" -#: src/datastore/plugin_datastore_sqlite.c:239 -#: src/namestore/plugin_namestore_sqlite.c:223 +#: src/datastore/plugin_datastore_sqlite.c:233 +#: src/namestore/plugin_namestore_sqlite.c:204 #, c-format msgid "Option `%s' in section `%s' missing in configuration!\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:266 -#: src/namestore/plugin_namestore_sqlite.c:248 +#: src/datastore/plugin_datastore_sqlite.c:260 +#: src/namestore/plugin_namestore_sqlite.c:229 #, c-format msgid "Unable to initialize SQLite: %s.\n" msgstr "无法初始化 SQLite:%s。\n" -#: src/datastore/plugin_datastore_sqlite.c:669 +#: src/datastore/plugin_datastore_sqlite.c:655 #, fuzzy msgid "Invalid data in database. Trying to fix (by deletion).\n" msgstr "%s 中有无效数据。请尝试修复(删除之)。\n" -#: src/datastore/plugin_datastore_sqlite.c:1159 +#: src/datastore/plugin_datastore_sqlite.c:1139 msgid "sqlite version to old to determine size, assuming zero\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1178 +#: src/datastore/plugin_datastore_sqlite.c:1158 #, c-format msgid "" "Using sqlite page utilization to estimate payload (%llu pages of size %llu " "bytes)\n" msgstr "" -#: src/datastore/plugin_datastore_sqlite.c:1218 -#: src/namestore/plugin_namestore_sqlite.c:779 +#: src/datastore/plugin_datastore_sqlite.c:1198 +#: src/namestore/plugin_namestore_sqlite.c:829 #, fuzzy msgid "Sqlite database running\n" msgstr "sqlite 数据仓库" @@ -1137,33 +1143,32 @@ msgstr "sqlite 数据仓库" msgid "Template database running\n" msgstr "" -#: src/dht/dht_api.c:280 +#: src/dht/dht_api.c:348 #, fuzzy msgid "Failed to connect to the DHT service!\n" msgstr "初始化“%s”服务失败。\n" -#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-put.c:172 -#: src/gns/gnunet-gns-lookup.c:179 +#: src/dht/gnunet-dht-get.c:201 src/dht/gnunet-dht-monitor.c:293 +#: src/dht/gnunet-dht-put.c:192 msgid "the query key" msgstr "" -#: src/dht/gnunet-dht-get.c:204 src/gns/gnunet-gns-lookup.c:182 +#: src/dht/gnunet-dht-get.c:204 msgid "how many parallel requests (replicas) to create" msgstr "" -#: src/dht/gnunet-dht-get.c:207 src/gns/gnunet-gns-lookup.c:185 +#: src/dht/gnunet-dht-get.c:207 src/dht/gnunet-dht-monitor.c:296 msgid "the type of data to look for" msgstr "" -#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:181 -#: src/gns/gnunet-gns-lookup.c:188 +#: src/dht/gnunet-dht-get.c:210 src/dht/gnunet-dht-put.c:201 msgid "how long to execute this query before giving up?" msgstr "" -#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-put.c:184 -#: src/fs/gnunet-download.c:270 src/fs/gnunet-publish.c:725 -#: src/fs/gnunet-search.c:297 src/fs/gnunet-unindex.c:169 -#: src/gns/gnunet-gns-lookup.c:191 src/nse/gnunet-nse-profiler.c:908 +#: src/dht/gnunet-dht-get.c:213 src/dht/gnunet-dht-monitor.c:302 +#: src/dht/gnunet-dht-put.c:204 src/fs/gnunet-download.c:271 +#: src/fs/gnunet-publish.c:731 src/fs/gnunet-search.c:297 +#: src/fs/gnunet-unindex.c:169 src/nse/gnunet-nse-profiler.c:910 msgid "be verbose (print progress information)" msgstr "" @@ -1171,94 +1176,110 @@ msgstr "" msgid "Issue a GET request to the GNUnet DHT, prints results." msgstr "" -#: src/dht/gnunet-dht-put.c:100 +#: src/dht/gnunet-dht-monitor.c:299 +msgid "how long to execute? 0 = forever" +msgstr "" + +#: src/dht/gnunet-dht-monitor.c:321 +msgid "Prints all packets that go through the DHT." +msgstr "" + +#: src/dht/gnunet-dht-put.c:108 msgid "PUT request sent!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:124 +#: src/dht/gnunet-dht-put.c:111 +msgid "Timeout sending PUT request!\n" +msgstr "" + +#: src/dht/gnunet-dht-put.c:114 +msgid "PUT request not confirmed!\n" +msgstr "" + +#: src/dht/gnunet-dht-put.c:144 msgid "Must provide KEY and DATA for DHT put!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:132 +#: src/dht/gnunet-dht-put.c:152 #, fuzzy, c-format msgid "Could not connect to %s service!\n" msgstr "无法连接到 %s:%u:%s\n" -#: src/dht/gnunet-dht-put.c:137 +#: src/dht/gnunet-dht-put.c:157 #, fuzzy, c-format msgid "Connected to %s service!\n" msgstr "“%s”已连接到“%s”。\n" -#: src/dht/gnunet-dht-put.c:152 +#: src/dht/gnunet-dht-put.c:172 #, c-format msgid "Issuing put request for `%s' with data `%s'!\n" msgstr "" -#: src/dht/gnunet-dht-put.c:166 +#: src/dht/gnunet-dht-put.c:186 msgid "the data to insert under the key" msgstr "" -#: src/dht/gnunet-dht-put.c:169 +#: src/dht/gnunet-dht-put.c:189 msgid "how long to store this entry in the dht (in seconds)" msgstr "" -#: src/dht/gnunet-dht-put.c:175 +#: src/dht/gnunet-dht-put.c:195 msgid "how many replicas to create" msgstr "" -#: src/dht/gnunet-dht-put.c:178 +#: src/dht/gnunet-dht-put.c:198 msgid "the type to insert data as" msgstr "" -#: src/dht/gnunet-dht-put.c:203 +#: src/dht/gnunet-dht-put.c:223 msgid "Issue a PUT request to the GNUnet DHT insert DATA under KEY." msgstr "" -#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:556 -#: src/testing/testing.c:1979 src/testing/testing.c:2009 +#: src/dht/gnunet-service-dht.c:163 src/testing/testing.c:544 +#: src/testing/testing.c:1968 src/testing/testing.c:1998 #, fuzzy msgid "Failed to connect to transport service!\n" msgstr "初始化“%s”服务失败。\n" -#: src/dht/gnunet-service-dht_clients.c:371 +#: src/dht/gnunet-service-dht_clients.c:407 msgid "# GET requests from clients injected" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:462 +#: src/dht/gnunet-service-dht_clients.c:500 msgid "# PUT requests received from clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:529 +#: src/dht/gnunet-service-dht_clients.c:584 msgid "# GET requests received from clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:624 +#: src/dht/gnunet-service-dht_clients.c:682 msgid "# GET STOP requests received from clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:854 +#: src/dht/gnunet-service-dht_clients.c:919 msgid "# Key match, type mismatches in REPLY to CLIENT" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:869 +#: src/dht/gnunet-service-dht_clients.c:932 msgid "# Duplicate REPLIES to CLIENT request dropped" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:906 +#: src/dht/gnunet-service-dht_clients.c:967 #, c-format msgid "Unsupported block type (%u) in request!\n" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:928 +#: src/dht/gnunet-service-dht_clients.c:989 msgid "# RESULTS queued for clients" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:979 -#: src/dht/gnunet-service-dht_clients.c:1022 +#: src/dht/gnunet-service-dht_clients.c:1038 +#: src/dht/gnunet-service-dht_clients.c:1081 msgid "# REPLIES ignored for CLIENTS (no match)" msgstr "" -#: src/dht/gnunet-service-dht_clients.c:989 +#: src/dht/gnunet-service-dht_clients.c:1048 msgid "Could not pass reply to client, message too big!\n" msgstr "" @@ -1271,28 +1292,28 @@ msgstr "" msgid "# ITEMS stored in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:209 +#: src/dht/gnunet-service-dht_datacache.c:207 msgid "# Good RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:220 +#: src/dht/gnunet-service-dht_datacache.c:218 msgid "# Duplicate RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:226 +#: src/dht/gnunet-service-dht_datacache.c:224 msgid "# Invalid RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:238 +#: src/dht/gnunet-service-dht_datacache.c:236 msgid "# Unsupported RESULTS found in datacache" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:241 +#: src/dht/gnunet-service-dht_datacache.c:239 #, c-format msgid "Unsupported block type (%u) in local response!\n" msgstr "" -#: src/dht/gnunet-service-dht_datacache.c:271 +#: src/dht/gnunet-service-dht_datacache.c:269 msgid "# GET requests given to datacache" msgstr "" @@ -1304,85 +1325,77 @@ msgstr "" msgid "# Preference updates given to core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:573 +#: src/dht/gnunet-service-dht_neighbours.c:571 msgid "# FIND PEER messages initiated" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:629 -#: src/dht/gnunet-service-dht_neighbours.c:689 -#, fuzzy -msgid "# Peers connected" -msgstr "" -"\n" -"按任意键继续\n" - -#: src/dht/gnunet-service-dht_neighbours.c:723 +#: src/dht/gnunet-service-dht_neighbours.c:717 msgid "# Queued messages discarded (peer disconnected)" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:778 +#: src/dht/gnunet-service-dht_neighbours.c:772 msgid "# Bytes transmitted to other peers" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:816 +#: src/dht/gnunet-service-dht_neighbours.c:810 msgid "# Bytes of bandwdith requested from core" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1040 -#: src/dht/gnunet-service-dht_neighbours.c:1068 +#: src/dht/gnunet-service-dht_neighbours.c:1032 +#: src/dht/gnunet-service-dht_neighbours.c:1060 msgid "# Peers excluded from routing due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1049 -#: src/dht/gnunet-service-dht_neighbours.c:1085 +#: src/dht/gnunet-service-dht_neighbours.c:1041 +#: src/dht/gnunet-service-dht_neighbours.c:1075 msgid "# Peer selection failed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1221 +#: src/dht/gnunet-service-dht_neighbours.c:1207 msgid "# PUT requests routed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1252 +#: src/dht/gnunet-service-dht_neighbours.c:1236 msgid "# PUT messages queued for transmission" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1333 +#: src/dht/gnunet-service-dht_neighbours.c:1315 msgid "# GET requests routed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1364 +#: src/dht/gnunet-service-dht_neighbours.c:1342 msgid "# GET messages queued for transmission" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1467 +#: src/dht/gnunet-service-dht_neighbours.c:1443 msgid "# RESULT messages queued for transmission" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1555 +#: src/dht/gnunet-service-dht_neighbours.c:1531 msgid "# P2P PUT requests received" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1668 +#: src/dht/gnunet-service-dht_neighbours.c:1647 msgid "# FIND PEER requests ignored due to Bloomfilter" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1676 +#: src/dht/gnunet-service-dht_neighbours.c:1655 msgid "# FIND PEER requests ignored due to lack of HELLO" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1767 +#: src/dht/gnunet-service-dht_neighbours.c:1746 msgid "# P2P GET requests received" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1811 +#: src/dht/gnunet-service-dht_neighbours.c:1788 msgid "# P2P FIND PEER requests processed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1825 +#: src/dht/gnunet-service-dht_neighbours.c:1802 msgid "# P2P GET requests ONLY routed" msgstr "" -#: src/dht/gnunet-service-dht_neighbours.c:1895 +#: src/dht/gnunet-service-dht_neighbours.c:1876 msgid "# P2P RESULTS received" msgstr "" @@ -1402,29 +1415,28 @@ msgstr "" msgid "# Invalid REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:236 +#: src/dht/gnunet-service-dht_routing.c:238 msgid "# Unsupported REPLIES matched against routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:314 -#: src/dht/gnunet-service-dht_routing.c:368 +#: src/dht/gnunet-service-dht_routing.c:311 msgid "# Entries removed from routing table" msgstr "" -#: src/dht/gnunet-service-dht_routing.c:324 +#: src/dht/gnunet-service-dht_routing.c:352 msgid "# Entries added to routing table" msgstr "" -#: src/dht/plugin_block_dht.c:124 +#: src/dht/plugin_block_dht.c:136 #, c-format msgid "Block not of type %u\n" msgstr "" -#: src/dht/plugin_block_dht.c:131 +#: src/dht/plugin_block_dht.c:143 msgid "Size mismatch for block\n" msgstr "" -#: src/dht/plugin_block_dht.c:140 +#: src/dht/plugin_block_dht.c:152 #, c-format msgid "Block of type %u is malformed\n" msgstr "" @@ -1453,67 +1465,68 @@ msgstr "" msgid "Change DNS replies to point elsewhere." msgstr "" -#: src/dns/gnunet-service-dns.c:480 +#: src/dns/gnunet-service-dns.c:485 #, fuzzy, c-format msgid "Could not bind to any port: %s\n" msgstr "找不到主机“%s”的 IP:%s\n" -#: src/dns/gnunet-service-dns.c:634 +#: src/dns/gnunet-service-dns.c:639 msgid "# DNS requests answered via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:818 +#: src/dns/gnunet-service-dns.c:822 msgid "# DNS exit failed (failed to open socket)" msgstr "" -#: src/dns/gnunet-service-dns.c:1001 +#: src/dns/gnunet-service-dns.c:1005 #, c-format msgid "Received DNS response that is too small (%u bytes)" msgstr "" -#: src/dns/gnunet-service-dns.c:1046 +#: src/dns/gnunet-service-dns.c:1050 msgid "# External DNS response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1165 +#: src/dns/gnunet-service-dns.c:1168 msgid "# Client response discarded (no matching request)" msgstr "" -#: src/dns/gnunet-service-dns.c:1198 -msgid "Changing DNS reply according to client specifications\n" -msgstr "" - -#: src/dns/gnunet-service-dns.c:1279 +#: src/dns/gnunet-service-dns.c:1281 msgid "Received malformed IPv4-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1294 +#: src/dns/gnunet-service-dns.c:1297 msgid "Received malformed IPv6-UDP packet on TUN interface.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1303 +#: src/dns/gnunet-service-dns.c:1306 #, c-format msgid "Got non-IP packet with %u bytes and protocol %u from TUN\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1312 +#: src/dns/gnunet-service-dns.c:1315 msgid "# Non-DNS UDP packet received via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:1377 +#: src/dns/gnunet-service-dns.c:1380 msgid "# DNS requests received via TUN interface" msgstr "" -#: src/dns/gnunet-service-dns.c:1461 +#: src/dns/gnunet-service-dns.c:1465 #, c-format msgid "Configured DNS exit `%s' is not working / valid.\n" msgstr "" -#: src/dns/gnunet-service-dns.c:1493 src/exit/gnunet-daemon-exit.c:2673 +#: src/dns/gnunet-service-dns.c:1497 src/exit/gnunet-daemon-exit.c:2674 msgid "# Inbound MESH tunnels created" msgstr "" -#: src/dns/gnunet-service-dns.c:1567 +#: src/dns/gnunet-service-dns.c:1561 src/exit/gnunet-daemon-exit.c:3032 +#, c-format +msgid "`%s' must be installed SUID, refusing to run\n" +msgstr "" + +#: src/dns/gnunet-service-dns.c:1581 msgid "Configured to provide DNS exit, but no valid DNS server configured!\n" msgstr "" @@ -1536,15 +1549,15 @@ msgstr "" msgid "# Bytes transmitted via mesh tunnels" msgstr "" -#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2068 -#: src/exit/gnunet-daemon-exit.c:2318 src/vpn/gnunet-service-vpn.c:1388 -#: src/vpn/gnunet-service-vpn.c:1788 src/vpn/gnunet-service-vpn.c:1951 +#: src/exit/gnunet-daemon-exit.c:679 src/exit/gnunet-daemon-exit.c:2069 +#: src/exit/gnunet-daemon-exit.c:2319 src/vpn/gnunet-service-vpn.c:1394 +#: src/vpn/gnunet-service-vpn.c:1795 src/vpn/gnunet-service-vpn.c:1958 msgid "# ICMPv4 packets dropped (type not allowed)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2127 -#: src/exit/gnunet-daemon-exit.c:2377 src/vpn/gnunet-service-vpn.c:1444 -#: src/vpn/gnunet-service-vpn.c:1847 src/vpn/gnunet-service-vpn.c:1984 +#: src/exit/gnunet-daemon-exit.c:716 src/exit/gnunet-daemon-exit.c:2128 +#: src/exit/gnunet-daemon-exit.c:2378 src/vpn/gnunet-service-vpn.c:1450 +#: src/vpn/gnunet-service-vpn.c:1854 src/vpn/gnunet-service-vpn.c:1991 msgid "# ICMPv6 packets dropped (type not allowed)" msgstr "" @@ -1591,124 +1604,124 @@ msgstr "" msgid "Packet from unknown protocol %u received. Ignored.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1470 +#: src/exit/gnunet-daemon-exit.c:1471 msgid "# TCP packets sent via TUN" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1570 +#: src/exit/gnunet-daemon-exit.c:1571 msgid "# TCP service creation requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1573 src/exit/gnunet-daemon-exit.c:1652 -#: src/exit/gnunet-daemon-exit.c:1762 src/exit/gnunet-daemon-exit.c:1992 -#: src/exit/gnunet-daemon-exit.c:2234 src/exit/gnunet-daemon-exit.c:2515 -#: src/exit/gnunet-daemon-exit.c:2615 +#: src/exit/gnunet-daemon-exit.c:1574 src/exit/gnunet-daemon-exit.c:1653 +#: src/exit/gnunet-daemon-exit.c:1763 src/exit/gnunet-daemon-exit.c:1993 +#: src/exit/gnunet-daemon-exit.c:2235 src/exit/gnunet-daemon-exit.c:2516 +#: src/exit/gnunet-daemon-exit.c:2616 msgid "# Bytes received from MESH" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1606 src/exit/gnunet-daemon-exit.c:2637 +#: src/exit/gnunet-daemon-exit.c:1607 src/exit/gnunet-daemon-exit.c:2638 #, c-format msgid "No service found for %s on port %d!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1610 +#: src/exit/gnunet-daemon-exit.c:1611 msgid "# TCP requests dropped (no such service)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1655 +#: src/exit/gnunet-daemon-exit.c:1656 msgid "# TCP IP-exit creation requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1765 +#: src/exit/gnunet-daemon-exit.c:1766 msgid "# TCP data requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1779 +#: src/exit/gnunet-daemon-exit.c:1780 msgid "# TCP DATA requests dropped (no session)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1829 +#: src/exit/gnunet-daemon-exit.c:1830 msgid "# ICMP packets sent via TUN" msgstr "" -#: src/exit/gnunet-daemon-exit.c:1995 +#: src/exit/gnunet-daemon-exit.c:1996 msgid "# ICMP IP-exit requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2237 +#: src/exit/gnunet-daemon-exit.c:2238 msgid "# ICMP service requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2303 src/vpn/gnunet-service-vpn.c:1378 -#: src/vpn/gnunet-service-vpn.c:1945 +#: src/exit/gnunet-daemon-exit.c:2304 src/vpn/gnunet-service-vpn.c:1384 +#: src/vpn/gnunet-service-vpn.c:1952 msgid "# ICMPv4 packets dropped (impossible PT to v6)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2362 src/vpn/gnunet-service-vpn.c:1414 -#: src/vpn/gnunet-service-vpn.c:1426 src/vpn/gnunet-service-vpn.c:1835 +#: src/exit/gnunet-daemon-exit.c:2363 src/vpn/gnunet-service-vpn.c:1420 +#: src/vpn/gnunet-service-vpn.c:1432 src/vpn/gnunet-service-vpn.c:1842 msgid "# ICMPv6 packets dropped (impossible PT to v4)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2412 +#: src/exit/gnunet-daemon-exit.c:2413 msgid "# UDP packets sent via TUN" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2518 +#: src/exit/gnunet-daemon-exit.c:2519 msgid "# UDP IP-exit requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2618 +#: src/exit/gnunet-daemon-exit.c:2619 msgid "# UDP service requests received via mesh" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2641 +#: src/exit/gnunet-daemon-exit.c:2642 msgid "# UDP requests dropped (no such service)" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2881 +#: src/exit/gnunet-daemon-exit.c:2882 #, c-format msgid "No addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2895 src/exit/gnunet-daemon-exit.c:2907 +#: src/exit/gnunet-daemon-exit.c:2896 src/exit/gnunet-daemon-exit.c:2908 #, c-format msgid "Service `%s' configured for IPv4, but IPv4 is disabled!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:2918 +#: src/exit/gnunet-daemon-exit.c:2919 #, c-format msgid "No IP addresses found for hostname `%s' of service `%s'!\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3047 +#: src/exit/gnunet-daemon-exit.c:3048 msgid "" "This system does not support IPv4, will disable IPv4 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3055 +#: src/exit/gnunet-daemon-exit.c:3056 msgid "" "This system does not support IPv6, will disable IPv6 functions despite them " "being enabled in the configuration\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3062 +#: src/exit/gnunet-daemon-exit.c:3063 msgid "" "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use " "ENABLE_IPv4=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3068 +#: src/exit/gnunet-daemon-exit.c:3069 msgid "" "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use " "ENABLE_IPv6=YES\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3074 src/pt/gnunet-daemon-pt.c:884 +#: src/exit/gnunet-daemon-exit.c:3075 src/pt/gnunet-daemon-pt.c:884 msgid "No useful service enabled. Exiting.\n" msgstr "" -#: src/exit/gnunet-daemon-exit.c:3235 +#: src/exit/gnunet-daemon-exit.c:3236 msgid "Daemon to run to provide an IP exit node for the VPN" msgstr "" @@ -1716,116 +1729,120 @@ msgstr "" msgid "# acknowledgements sent for fragment" msgstr "" -#: src/fragmentation/defragmentation.c:454 +#: src/fragmentation/defragmentation.c:456 msgid "# fragments received" msgstr "" -#: src/fragmentation/defragmentation.c:513 +#: src/fragmentation/defragmentation.c:521 msgid "# duplicate fragments received" msgstr "" -#: src/fragmentation/defragmentation.c:526 +#: src/fragmentation/defragmentation.c:534 msgid "# messages defragmented" msgstr "" -#: src/fragmentation/fragmentation.c:188 +#: src/fragmentation/fragmentation.c:203 msgid "# fragments transmitted" msgstr "" -#: src/fragmentation/fragmentation.c:191 +#: src/fragmentation/fragmentation.c:206 msgid "# fragments retransmitted" msgstr "" -#: src/fragmentation/fragmentation.c:255 +#: src/fragmentation/fragmentation.c:232 +msgid "# fragments wrap arounds" +msgstr "" + +#: src/fragmentation/fragmentation.c:273 msgid "# messages fragmented" msgstr "" -#: src/fragmentation/fragmentation.c:258 +#: src/fragmentation/fragmentation.c:276 msgid "# total size of fragmented messages" msgstr "" -#: src/fragmentation/fragmentation.c:343 +#: src/fragmentation/fragmentation.c:363 msgid "# fragment acknowledgements received" msgstr "" -#: src/fragmentation/fragmentation.c:349 +#: src/fragmentation/fragmentation.c:369 msgid "# bits removed from fragmentation ACKs" msgstr "" -#: src/fragmentation/fragmentation.c:373 +#: src/fragmentation/fragmentation.c:393 msgid "# fragmentation transmissions completed" msgstr "" -#: src/fs/fs_api.c:284 +#: src/fs/fs_api.c:339 #, fuzzy, c-format msgid "Could not open file `%s': %s" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/fs_api.c:293 +#: src/fs/fs_api.c:348 #, fuzzy, c-format msgid "Could not read file `%s': %s" msgstr "无法解析“%s”(%s):%s\n" -#: src/fs/fs_api.c:299 +#: src/fs/fs_api.c:354 #, c-format msgid "Short read reading from file `%s'!" msgstr "" -#: src/fs/fs_api.c:877 +#: src/fs/fs_api.c:938 #, fuzzy, c-format msgid "Failed to resume publishing information `%s': %s\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/fs_api.c:1334 +#: src/fs/fs_api.c:1395 #, c-format msgid "Failed to recover namespace `%s', cannot resume publishing operation.\n" msgstr "" -#: src/fs/fs_api.c:1376 +#: src/fs/fs_api.c:1437 #, c-format msgid "Failure while resuming publishing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:1392 +#: src/fs/fs_api.c:1453 #, fuzzy, c-format msgid "Failed to resume publishing operation `%s': %s\n" msgstr "解析配置文件“%s”失败\n" -#: src/fs/fs_api.c:2004 +#: src/fs/fs_api.c:2106 #, c-format msgid "Failure while resuming unindexing operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2014 +#: src/fs/fs_api.c:2116 #, fuzzy, c-format msgid "Failed to resume unindexing operation `%s': %s\n" msgstr "解析配置文件“%s”失败\n" -#: src/fs/fs_api.c:2139 src/fs/fs_api.c:2378 +#: src/fs/fs_api.c:2241 src/fs/fs_api.c:2480 #, fuzzy, c-format msgid "Failed to resume sub-download `%s': %s\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/fs_api.c:2156 +#: src/fs/fs_api.c:2258 #, fuzzy, c-format msgid "Failed to resume sub-search `%s': %s\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/fs_api.c:2168 src/fs/fs_api.c:2187 src/fs/fs_api.c:2671 +#: src/fs/fs_api.c:2270 src/fs/fs_api.c:2289 src/fs/fs_api.c:2773 #, c-format msgid "Failure while resuming search operation `%s': %s\n" msgstr "" -#: src/fs/fs_api.c:2369 +#: src/fs/fs_api.c:2471 #, fuzzy, c-format msgid "Failed to resume sub-download `%s': could not open file `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/fs/fs_api.c:2615 +#: src/fs/fs_api.c:2717 msgid "Could not resume running search, will resume as paused search\n" msgstr "" -#: src/fs/fs_api.c:2709 +#: src/fs/fs_api.c:2811 #, c-format msgid "Failure while resuming download operation `%s': %s\n" msgstr "" @@ -1834,53 +1851,58 @@ msgstr "" msgid "MAGIC mismatch. This is not a GNUnet directory.\n" msgstr "" -#: src/fs/fs_download.c:310 +#: src/fs/fs_download.c:311 msgid "" "Recursive downloads of directories larger than 4 GB are not supported on 32-" "bit systems\n" msgstr "" -#: src/fs/fs_download.c:330 +#: src/fs/fs_download.c:331 msgid "Directory too large for system address space\n" msgstr "" -#: src/fs/fs_download.c:488 src/fs/fs_download.c:500 +#: src/fs/fs_download.c:497 src/fs/fs_download.c:509 #, fuzzy, c-format msgid "Failed to open file `%s' for writing" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/fs_download.c:870 +#: src/fs/fs_download.c:878 #, c-format msgid "Failed to create directory for recursive download of `%s'\n" msgstr "" -#: src/fs/fs_download.c:951 +#: src/fs/fs_download.c:960 #, c-format msgid "" "Internal error or bogus download URI (expected %u bytes at depth %u and " -"offset %llu/%llu, got %u bytes)\n" +"offset %llu/%llu, got %u bytes)" msgstr "" -#: src/fs/fs_download.c:977 +#: src/fs/fs_download.c:986 msgid "internal error decrypting content" msgstr "" -#: src/fs/fs_download.c:1000 +#: src/fs/fs_download.c:1009 #, fuzzy, c-format -msgid "Download failed: could not open file `%s': %s\n" +msgid "Download failed: could not open file `%s': %s" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/fs_download.c:1010 +#: src/fs/fs_download.c:1019 #, fuzzy, c-format -msgid "Failed to seek to offset %llu in file `%s': %s\n" +msgid "Failed to seek to offset %llu in file `%s': %s" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/fs_download.c:1019 +#: src/fs/fs_download.c:1028 #, fuzzy, c-format -msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s\n" +msgid "Failed to write block of %u bytes at offset %llu in file `%s': %s" msgstr "解析配置文件“%s”失败\n" -#: src/fs/fs_download.c:1835 +#: src/fs/fs_download.c:1125 +#, fuzzy +msgid "internal error decoding tree" +msgstr "未知错误。\n" + +#: src/fs/fs_download.c:1888 #, fuzzy msgid "Invalid URI" msgstr "无效条目。\n" @@ -1961,63 +1983,63 @@ msgstr "未知错误。\n" msgid "Failed to connect to datastore." msgstr "" -#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:395 +#: src/fs/fs_publish.c:129 src/fs/fs_publish.c:397 #, c-format msgid "Publishing failed: %s" msgstr "" -#: src/fs/fs_publish.c:616 src/fs/fs_publish.c:633 src/fs/fs_publish.c:672 -#: src/fs/fs_publish.c:692 src/fs/fs_publish.c:717 src/fs/fs_publish.c:857 +#: src/fs/fs_publish.c:621 src/fs/fs_publish.c:638 src/fs/fs_publish.c:677 +#: src/fs/fs_publish.c:697 src/fs/fs_publish.c:722 src/fs/fs_publish.c:862 #, c-format msgid "Can not index file `%s': %s. Will try to insert instead.\n" msgstr "" -#: src/fs/fs_publish.c:618 +#: src/fs/fs_publish.c:623 msgid "timeout on index-start request to `fs' service" msgstr "" -#: src/fs/fs_publish.c:630 +#: src/fs/fs_publish.c:635 #, fuzzy msgid "unknown error" msgstr "未知错误" -#: src/fs/fs_publish.c:673 +#: src/fs/fs_publish.c:678 msgid "failed to compute hash" msgstr "" -#: src/fs/fs_publish.c:693 +#: src/fs/fs_publish.c:698 msgid "filename too long" msgstr "" -#: src/fs/fs_publish.c:718 +#: src/fs/fs_publish.c:723 msgid "could not connect to `fs' service" msgstr "" -#: src/fs/fs_publish.c:741 +#: src/fs/fs_publish.c:746 #, fuzzy, c-format msgid "Failed to get file identifiers for `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/fs/fs_publish.c:806 +#: src/fs/fs_publish.c:811 #, c-format msgid "Recursive upload failed at `%s': %s" msgstr "" -#: src/fs/fs_publish.c:812 +#: src/fs/fs_publish.c:817 #, c-format msgid "Recursive upload failed: %s" msgstr "" -#: src/fs/fs_publish.c:858 +#: src/fs/fs_publish.c:863 msgid "needs to be an actual file" msgstr "" -#: src/fs/fs_publish.c:1067 +#: src/fs/fs_publish.c:1071 #, c-format msgid "Insufficient space for publishing: %s" msgstr "" -#: src/fs/fs_publish.c:1138 +#: src/fs/fs_publish.c:1142 #, c-format msgid "Reserving space for %u entries and %llu bytes for publication\n" msgstr "" @@ -2026,7 +2048,7 @@ msgstr "" msgid "Could not connect to datastore." msgstr "" -#: src/fs/fs_search.c:810 +#: src/fs/fs_search.c:829 #, c-format msgid "Got result with unknown block type `%d', ignoring" msgstr "" @@ -2036,43 +2058,63 @@ msgstr "" msgid "Failed to start daemon: %s\n" msgstr "运行 %s失败:%s %d\n" -#: src/fs/fs_unindex.c:57 +#: src/fs/fs_unindex.c:58 msgid "Failed to find given position in file" msgstr "" -#: src/fs/fs_unindex.c:62 +#: src/fs/fs_unindex.c:63 #, fuzzy msgid "Failed to read file" msgstr "发送消息失败。\n" -#: src/fs/fs_unindex.c:231 +#: src/fs/fs_unindex.c:233 msgid "Unexpected time for a response from `fs' service." msgstr "" -#: src/fs/fs_unindex.c:239 +#: src/fs/fs_unindex.c:241 msgid "Timeout waiting for `fs' service." msgstr "" -#: src/fs/fs_unindex.c:247 +#: src/fs/fs_unindex.c:249 #, fuzzy msgid "Invalid response from `fs' service." msgstr "“%s”的参数无效。\n" -#: src/fs/fs_unindex.c:292 +#: src/fs/fs_unindex.c:293 msgid "Failed to connect to FS service for unindexing." msgstr "" -#: src/fs/fs_unindex.c:325 +#: src/fs/fs_unindex.c:344 +#, fuzzy +msgid "Failed to get KSKs from directory scan." +msgstr "解析配置文件“%s”失败\n" + +#: src/fs/fs_unindex.c:356 +#, fuzzy, c-format +msgid "Internal error scanning `%s'.\n" +msgstr "未知错误。\n" + +#: src/fs/fs_unindex.c:411 +#, fuzzy, c-format +msgid "Failed to remove KBlock: %s\n" +msgstr "打开日志文件“%s”失败:%s\n" + +#: src/fs/fs_unindex.c:501 +#, fuzzy, c-format +msgid "Failed to parse URI `%s' from KBlock!\n" +msgstr "运行 %s失败:%s %d\n" + +#: src/fs/fs_unindex.c:553 src/fs/fs_unindex.c:618 #, fuzzy msgid "Failed to connect to `datastore' service." msgstr "初始化“%s”服务失败。\n" -#: src/fs/fs_unindex.c:338 +#: src/fs/fs_unindex.c:631 #, fuzzy msgid "Failed to open file for unindexing." msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/fs_unindex.c:372 +#: src/fs/fs_unindex.c:665 msgid "Failed to compute hash of file." msgstr "" @@ -2183,92 +2225,92 @@ msgstr "更改 GNUnet 目录的权限出错" msgid "Display contents of a GNUnet directory" msgstr "更改 GNUnet 目录的权限出错" -#: src/fs/gnunet-download.c:100 +#: src/fs/gnunet-download.c:101 #, fuzzy, c-format msgid "Starting download `%s'.\n" msgstr "未知的命令“%s”。\n" -#: src/fs/gnunet-download.c:109 +#: src/fs/gnunet-download.c:110 #, fuzzy msgid "" msgstr "未知错误" -#: src/fs/gnunet-download.c:118 +#: src/fs/gnunet-download.c:119 #, c-format msgid "" "Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to " "download\n" msgstr "" -#: src/fs/gnunet-download.c:128 +#: src/fs/gnunet-download.c:129 #, c-format msgid "Error downloading: %s.\n" msgstr "" -#: src/fs/gnunet-download.c:136 +#: src/fs/gnunet-download.c:137 #, c-format msgid "Downloading `%s' done (%s/s).\n" msgstr "" -#: src/fs/gnunet-download.c:151 src/fs/gnunet-publish.c:190 +#: src/fs/gnunet-download.c:152 src/fs/gnunet-publish.c:190 #: src/fs/gnunet-search.c:190 src/fs/gnunet-unindex.c:109 #, c-format msgid "Unexpected status: %d\n" msgstr "" -#: src/fs/gnunet-download.c:176 +#: src/fs/gnunet-download.c:177 #, fuzzy msgid "You need to specify a URI argument.\n" msgstr "您必须指定一个昵称\n" -#: src/fs/gnunet-download.c:182 src/fs/gnunet-publish.c:618 +#: src/fs/gnunet-download.c:183 src/fs/gnunet-publish.c:624 #, fuzzy, c-format msgid "Failed to parse URI: %s\n" msgstr "运行 %s失败:%s %d\n" -#: src/fs/gnunet-download.c:189 +#: src/fs/gnunet-download.c:190 msgid "Only CHK or LOC URIs supported.\n" msgstr "" -#: src/fs/gnunet-download.c:196 +#: src/fs/gnunet-download.c:197 msgid "Target filename must be specified.\n" msgstr "" -#: src/fs/gnunet-download.c:210 src/fs/gnunet-publish.c:596 +#: src/fs/gnunet-download.c:211 src/fs/gnunet-publish.c:602 #: src/fs/gnunet-search.c:241 src/fs/gnunet-unindex.c:141 #, fuzzy, c-format msgid "Could not initialize `%s' subsystem.\n" msgstr "初始化“%s”服务失败。\n" -#: src/fs/gnunet-download.c:247 src/fs/gnunet-search.c:285 +#: src/fs/gnunet-download.c:248 src/fs/gnunet-search.c:285 msgid "set the desired LEVEL of receiver-anonymity" msgstr "" -#: src/fs/gnunet-download.c:250 +#: src/fs/gnunet-download.c:251 msgid "delete incomplete downloads (when aborted with CTRL-C)" msgstr "" -#: src/fs/gnunet-download.c:253 src/fs/gnunet-search.c:288 +#: src/fs/gnunet-download.c:254 src/fs/gnunet-search.c:288 msgid "only search the local peer (no P2P network search)" msgstr "" -#: src/fs/gnunet-download.c:256 +#: src/fs/gnunet-download.c:257 msgid "write the file to FILENAME" msgstr "" -#: src/fs/gnunet-download.c:260 +#: src/fs/gnunet-download.c:261 msgid "set the maximum number of parallel downloads that is allowed" msgstr "" -#: src/fs/gnunet-download.c:264 +#: src/fs/gnunet-download.c:265 msgid "set the maximum number of parallel requests for blocks that is allowed" msgstr "" -#: src/fs/gnunet-download.c:267 +#: src/fs/gnunet-download.c:268 msgid "download a GNUnet directory recursively" msgstr "" -#: src/fs/gnunet-download.c:277 +#: src/fs/gnunet-download.c:278 msgid "" "Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/" "chk/...)" @@ -2282,69 +2324,64 @@ msgstr "" msgid "Special file-sharing operations" msgstr "" -#: src/fs/gnunet-pseudonym.c:151 src/statistics/gnunet-statistics.c:126 +#: src/fs/gnunet-pseudonym.c:160 src/statistics/gnunet-statistics.c:167 #, fuzzy, c-format msgid "Invalid argument `%s'\n" msgstr "“%s”的参数无效。\n" -#: src/fs/gnunet-pseudonym.c:165 -#, c-format -msgid "Namespace `%s' unknown.\n" -msgstr "" - -#: src/fs/gnunet-pseudonym.c:240 src/fs/gnunet-pseudonym.c:247 -#: src/fs/gnunet-pseudonym.c:249 +#: src/fs/gnunet-pseudonym.c:250 src/fs/gnunet-pseudonym.c:257 +#: src/fs/gnunet-pseudonym.c:259 #, fuzzy, c-format msgid "Option `%s' ignored\n" msgstr "%s:选项“%s”有歧义\n" -#: src/fs/gnunet-pseudonym.c:269 src/fs/gnunet-publish.c:672 +#: src/fs/gnunet-pseudonym.c:279 src/fs/gnunet-publish.c:678 msgid "set the desired LEVEL of sender-anonymity" msgstr "" -#: src/fs/gnunet-pseudonym.c:272 +#: src/fs/gnunet-pseudonym.c:282 msgid "create or advertise namespace NAME" msgstr "" -#: src/fs/gnunet-pseudonym.c:275 +#: src/fs/gnunet-pseudonym.c:285 msgid "delete namespace NAME " msgstr "" -#: src/fs/gnunet-pseudonym.c:278 +#: src/fs/gnunet-pseudonym.c:288 msgid "" "add an additional keyword for the advertisment (this option can be specified " "multiple times)" msgstr "" -#: src/fs/gnunet-pseudonym.c:282 src/fs/gnunet-publish.c:691 +#: src/fs/gnunet-pseudonym.c:292 src/fs/gnunet-publish.c:697 msgid "set the meta-data for the given TYPE to the given VALUE" msgstr "" -#: src/fs/gnunet-pseudonym.c:285 +#: src/fs/gnunet-pseudonym.c:295 msgid "print names of local namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:288 +#: src/fs/gnunet-pseudonym.c:298 msgid "use the given PRIORITY for the advertisments" msgstr "" -#: src/fs/gnunet-pseudonym.c:291 +#: src/fs/gnunet-pseudonym.c:301 msgid "do not print names of remote namespaces" msgstr "" -#: src/fs/gnunet-pseudonym.c:294 src/fs/gnunet-publish.c:710 +#: src/fs/gnunet-pseudonym.c:304 src/fs/gnunet-publish.c:716 msgid "set the desired replication LEVEL" msgstr "" -#: src/fs/gnunet-pseudonym.c:297 +#: src/fs/gnunet-pseudonym.c:307 msgid "specify ID of the root of the namespace" msgstr "" -#: src/fs/gnunet-pseudonym.c:300 +#: src/fs/gnunet-pseudonym.c:310 msgid "change rating of namespace ID by VALUE" msgstr "" -#: src/fs/gnunet-pseudonym.c:308 +#: src/fs/gnunet-pseudonym.c:318 msgid "Manage GNUnet pseudonyms." msgstr "" @@ -2372,163 +2409,163 @@ msgstr "" msgid "Cleanup after abort complete.\n" msgstr "" -#: src/fs/gnunet-publish.c:299 +#: src/fs/gnunet-publish.c:305 #, fuzzy, c-format msgid "Meta data for file `%s' (%s)\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/gnunet-publish.c:301 +#: src/fs/gnunet-publish.c:307 #, fuzzy, c-format msgid "Keywords for file `%s' (%s)\n" msgstr "无法解析“%s”(%s):%s\n" -#: src/fs/gnunet-publish.c:352 +#: src/fs/gnunet-publish.c:358 #, fuzzy, c-format msgid "Failed to create namespace `%s'\n" msgstr "发送消息失败。\n" -#: src/fs/gnunet-publish.c:427 +#: src/fs/gnunet-publish.c:433 #, fuzzy msgid "Could not publish\n" msgstr "无法解析“%s”(%s):%s\n" -#: src/fs/gnunet-publish.c:454 +#: src/fs/gnunet-publish.c:460 msgid "Could not start publishing.\n" msgstr "" -#: src/fs/gnunet-publish.c:485 +#: src/fs/gnunet-publish.c:491 #, fuzzy, c-format msgid "Scanning directory `%s'.\n" msgstr "解析配置文件“%s”失败\n" -#: src/fs/gnunet-publish.c:487 +#: src/fs/gnunet-publish.c:493 #, fuzzy, c-format msgid "Scanning file `%s'.\n" msgstr "未知的命令“%s”。\n" -#: src/fs/gnunet-publish.c:492 +#: src/fs/gnunet-publish.c:498 #, c-format msgid "There was trouble processing file `%s', skipping it.\n" msgstr "" -#: src/fs/gnunet-publish.c:497 +#: src/fs/gnunet-publish.c:503 msgid "Preprocessing complete.\n" msgstr "" -#: src/fs/gnunet-publish.c:501 +#: src/fs/gnunet-publish.c:507 #, fuzzy, c-format msgid "Extracting meta data from file `%s' complete.\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/gnunet-publish.c:505 +#: src/fs/gnunet-publish.c:511 msgid "Meta data extraction has finished.\n" msgstr "" -#: src/fs/gnunet-publish.c:512 +#: src/fs/gnunet-publish.c:518 #, fuzzy msgid "Internal error scanning directory.\n" msgstr "未知错误。\n" -#: src/fs/gnunet-publish.c:546 +#: src/fs/gnunet-publish.c:552 #, c-format msgid "Cannot extract metadata from a URI!\n" msgstr "" -#: src/fs/gnunet-publish.c:553 +#: src/fs/gnunet-publish.c:559 #, c-format msgid "You must specify one and only one filename for insertion.\n" msgstr "" -#: src/fs/gnunet-publish.c:559 +#: src/fs/gnunet-publish.c:565 #, c-format msgid "You must NOT specify an URI and a filename.\n" msgstr "" -#: src/fs/gnunet-publish.c:567 src/vpn/gnunet-vpn.c:214 +#: src/fs/gnunet-publish.c:573 src/vpn/gnunet-vpn.c:214 #, c-format msgid "Option `%s' is required when using option `%s'.\n" msgstr "" -#: src/fs/gnunet-publish.c:577 src/fs/gnunet-publish.c:584 -#: src/transport/gnunet-transport.c:530 +#: src/fs/gnunet-publish.c:583 src/fs/gnunet-publish.c:590 +#: src/transport/gnunet-transport.c:560 #, c-format msgid "Option `%s' makes no sense without option `%s'.\n" msgstr "" -#: src/fs/gnunet-publish.c:606 +#: src/fs/gnunet-publish.c:612 #, fuzzy, c-format msgid "Could not create namespace `%s'\n" msgstr "无法解析“%s”(%s):%s\n" -#: src/fs/gnunet-publish.c:639 +#: src/fs/gnunet-publish.c:645 #, fuzzy, c-format msgid "Failed to access `%s': %s\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/fs/gnunet-publish.c:651 +#: src/fs/gnunet-publish.c:657 msgid "" "Failed to start meta directory scanner. Is gnunet-helper-publish-fs " "installed?\n" msgstr "" -#: src/fs/gnunet-publish.c:676 +#: src/fs/gnunet-publish.c:682 msgid "disable adding the creation time to the metadata of the uploaded file" msgstr "" -#: src/fs/gnunet-publish.c:679 +#: src/fs/gnunet-publish.c:685 msgid "do not use libextractor to add keywords or metadata" msgstr "" -#: src/fs/gnunet-publish.c:683 +#: src/fs/gnunet-publish.c:689 msgid "" "print list of extracted keywords that would be used, but do not perform " "upload" msgstr "" -#: src/fs/gnunet-publish.c:687 +#: src/fs/gnunet-publish.c:693 msgid "" "add an additional keyword for the top-level file or directory (this option " "can be specified multiple times)" msgstr "" -#: src/fs/gnunet-publish.c:694 +#: src/fs/gnunet-publish.c:700 msgid "" "do not index, perform full insertion (stores entire file in encrypted form " "in GNUnet database)" msgstr "" -#: src/fs/gnunet-publish.c:699 +#: src/fs/gnunet-publish.c:705 msgid "" "specify ID of an updated version to be published in the future (for " "namespace insertions only)" msgstr "" -#: src/fs/gnunet-publish.c:703 +#: src/fs/gnunet-publish.c:709 msgid "specify the priority of the content" msgstr "" -#: src/fs/gnunet-publish.c:707 +#: src/fs/gnunet-publish.c:713 msgid "publish the files under the pseudonym NAME (place file into namespace)" msgstr "" -#: src/fs/gnunet-publish.c:713 +#: src/fs/gnunet-publish.c:719 msgid "" "only simulate the process but do not do any actual publishing (useful to " "compute URIs)" msgstr "" -#: src/fs/gnunet-publish.c:717 +#: src/fs/gnunet-publish.c:723 msgid "" "set the ID of this version of the publication (for namespace insertions only)" msgstr "" -#: src/fs/gnunet-publish.c:721 +#: src/fs/gnunet-publish.c:727 msgid "" "URI to be published (can be used instead of passing a file to add keywords " "to the file with the respective URI)" msgstr "" -#: src/fs/gnunet-publish.c:736 +#: src/fs/gnunet-publish.c:742 msgid "Publish a file or directory on GNUnet" msgstr "" @@ -2575,23 +2612,12 @@ msgid "# Loopback routes suppressed" msgstr "" #: src/fs/gnunet-service-fs.c:581 src/hostlist/gnunet-daemon-hostlist.c:297 -#: src/topology/gnunet-daemon-topology.c:1290 -#: src/topology/gnunet-daemon-topology.c:1297 +#: src/topology/gnunet-daemon-topology.c:1330 +#: src/topology/gnunet-daemon-topology.c:1337 #, fuzzy, c-format msgid "Failed to connect to `%s' service.\n" msgstr "初始化“%s”服务失败。\n" -#: src/fs/gnunet-service-fs_cp.c:615 src/fs/gnunet-service-fs_cp.c:1532 -#: src/topology/gnunet-daemon-topology.c:654 -#: src/topology/gnunet-daemon-topology.c:756 -#: src/transport/gnunet-service-transport_neighbours.c:960 -#: src/transport/gnunet-service-transport_neighbours.c:1289 -#: src/transport/gnunet-service-transport_neighbours.c:1841 -#: src/transport/gnunet-service-transport_neighbours.c:2499 -#: src/transport/gnunet-service-transport_neighbours.c:2566 -msgid "# peers connected" -msgstr "" - #: src/fs/gnunet-service-fs_cp.c:696 msgid "# migration stop messages received" msgstr "" @@ -2914,15 +2940,131 @@ msgstr "" msgid "Reply mismatched in terms of namespace. Discarded.\n" msgstr "" -#: src/gns/gns_api.c:221 +#: src/gns/gnunet-gns.c:191 +#, fuzzy +msgid "Failed to connect to GNS\n" +msgstr "初始化“%s”服务失败。\n" + +#: src/gns/gnunet-gns.c:232 +msgid "try to shorten a given GNS name" +msgstr "" + +#: src/gns/gnunet-gns.c:235 +msgid "Lookup a record using GNS (NOT IMPLEMENTED)" +msgstr "" + +#: src/gns/gnunet-gns.c:238 +msgid "Get the authority of a particular name" +msgstr "" + +#: src/gns/gnunet-gns.c:241 +msgid "Specify the type of the record lookup" +msgstr "" + +#: src/gns/gnunet-gns.c:244 +msgid "No unneeded output" +msgstr "" + +#: src/gns/gnunet-gns.c:255 +msgid "GNUnet GNS access tool" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:280 +#, fuzzy, c-format +msgid "Unsupported form value `%s'\n" +msgstr "未知的命令“%s”。\n" + +#: src/gns/gnunet-gns-fcfsd.c:333 +#, fuzzy, c-format +msgid "Failed to create record for domain `%s': %s\n" +msgstr "解析配置文件“%s”失败\n" + +#: src/gns/gnunet-gns-fcfsd.c:377 +#, c-format +msgid "Found existing name `%s' for the given key\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:439 +#, c-format +msgid "Found %u existing records for domain `%s'\n" +msgstr "" + +#: src/gns/gnunet-gns-fcfsd.c:498 +#, fuzzy, c-format +msgid "Failed to create page for `%s'\n" +msgstr "发送消息失败。\n" + +#: src/gns/gnunet-gns-fcfsd.c:514 +#, fuzzy, c-format +msgid "Failed to setup post processor for `%s'\n" +msgstr "解析配置文件“%s”失败\n" + +#: src/gns/gnunet-gns-fcfsd.c:725 src/gns/gnunet-gns-fcfsd.c:737 +#, fuzzy, c-format +msgid "Option `%s' not specified in configuration section `%s'\n" +msgstr "配置文件“%s”已写入。\n" + +#: src/gns/gnunet-gns-fcfsd.c:747 src/namestore/gnunet-namestore.c:299 +#, fuzzy +msgid "Failed to read or create private zone key\n" +msgstr "无法为守护程序创建用户账户。" + +#: src/gns/gnunet-gns-fcfsd.c:757 src/namestore/gnunet-namestore.c:310 +#, fuzzy +msgid "Failed to connect to namestore\n" +msgstr "初始化“%s”服务失败。\n" + +#: src/gns/gnunet-gns-fcfsd.c:773 src/gns/gnunet-gns-proxy.c:525 #, fuzzy -msgid "Failed to connect to the GNS service!\n" +msgid "Failed to start HTTP server\n" msgstr "初始化“%s”服务失败。\n" -#: src/gns/gnunet-gns-lookup.c:210 -msgid "Issue a request to the GNUnet Naming System, prints results." +#: src/gns/gnunet-gns-fcfsd.c:804 +msgid "GNUnet GNS first come first serve registration service" msgstr "" +#: src/gns/gnunet-gns-proxy.c:800 +msgid "listen on specified port" +msgstr "" + +#: src/gns/gnunet-gns-proxy.c:811 +msgid "GNUnet GNS proxy" +msgstr "" + +#: src/hello/gnunet-hello.c:122 +msgid "Call with name of HELLO file to modify.\n" +msgstr "" + +#: src/hello/gnunet-hello.c:128 +#, fuzzy, c-format +msgid "Error accessing file `%s': %s\n" +msgstr "创建用户出错" + +#: src/hello/gnunet-hello.c:136 +#, c-format +msgid "File `%s' is too big to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:143 +#, c-format +msgid "File `%s' is too small to be a HELLO\n" +msgstr "" + +#: src/hello/gnunet-hello.c:153 src/hello/gnunet-hello.c:181 +#, fuzzy, c-format +msgid "Error opening file `%s': %s\n" +msgstr "创建用户出错" + +#: src/hello/gnunet-hello.c:169 +#, c-format +msgid "Did not find well-formed HELLO in file `%s'\n" +msgstr "" + +#: src/hello/gnunet-hello.c:193 +#, fuzzy, c-format +msgid "Error writing HELLO to file `%s': %s\n" +msgstr "创建用户出错" + #: src/hostlist/gnunet-daemon-hostlist.c:264 msgid "" "None of the functions for the hostlist daemon were enabled. I have no " @@ -2951,190 +3093,190 @@ msgstr "" msgid "GNUnet hostlist server and client" msgstr "" -#: src/hostlist/hostlist-client.c:286 +#: src/hostlist/hostlist-client.c:289 msgid "# bytes downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:307 src/hostlist/hostlist-client.c:339 +#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:340 msgid "# invalid HELLOs downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:310 src/hostlist/hostlist-client.c:342 +#: src/hostlist/hostlist-client.c:313 src/hostlist/hostlist-client.c:343 #, c-format msgid "Invalid `%s' message received from hostlist at `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:330 +#: src/hostlist/hostlist-client.c:331 msgid "# valid HELLOs downloaded from hostlist servers" msgstr "" -#: src/hostlist/hostlist-client.c:374 src/hostlist/hostlist-client.c:395 +#: src/hostlist/hostlist-client.c:375 src/hostlist/hostlist-client.c:396 #, c-format msgid "No `%s' specified in `%s' configuration, will not bootstrap.\n" msgstr "" -#: src/hostlist/hostlist-client.c:472 src/hostlist/hostlist-client.c:682 -#: src/hostlist/hostlist-client.c:688 src/hostlist/hostlist-client.c:740 -#: src/hostlist/hostlist-client.c:749 src/hostlist/hostlist-client.c:877 -#: src/hostlist/hostlist-client.c:967 src/hostlist/hostlist-client.c:972 -#: src/transport/plugin_transport_http_client.c:108 -#: src/transport/plugin_transport_http_client.c:123 +#: src/hostlist/hostlist-client.c:473 src/hostlist/hostlist-client.c:683 +#: src/hostlist/hostlist-client.c:689 src/hostlist/hostlist-client.c:741 +#: src/hostlist/hostlist-client.c:750 src/hostlist/hostlist-client.c:871 +#: src/hostlist/hostlist-client.c:961 src/hostlist/hostlist-client.c:966 +#: src/transport/plugin_transport_http_client.c:110 +#: src/transport/plugin_transport_http_client.c:125 #, c-format msgid "%s failed at %s:%d: `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:592 src/hostlist/hostlist-client.c:1342 +#: src/hostlist/hostlist-client.c:593 src/hostlist/hostlist-client.c:1331 msgid "# advertised hostlist URIs" msgstr "" -#: src/hostlist/hostlist-client.c:622 +#: src/hostlist/hostlist-client.c:623 #, c-format msgid "# advertised URI `%s' downloaded" msgstr "" -#: src/hostlist/hostlist-client.c:663 +#: src/hostlist/hostlist-client.c:664 #, c-format msgid "" "Advertised hostlist with URI `%s' could not be downloaded. Advertised URI " "gets dismissed.\n" msgstr "" -#: src/hostlist/hostlist-client.c:805 +#: src/hostlist/hostlist-client.c:802 #, c-format msgid "Timeout trying to download hostlist from `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:822 +#: src/hostlist/hostlist-client.c:816 #, c-format msgid "Download limit of %u bytes exceeded, stopping download\n" msgstr "" -#: src/hostlist/hostlist-client.c:842 +#: src/hostlist/hostlist-client.c:836 #, fuzzy, c-format -msgid "%s failed for `%s' at %s:%d: `%s'\n" -msgstr "对驱动器“%2$s”的“%1$s”操作失败:%3$u\n" +msgid "Download of hostlist from `%s' failed: `%s'\n" +msgstr "打开日志文件“%s”失败:%s\n" -#: src/hostlist/hostlist-client.c:848 +#: src/hostlist/hostlist-client.c:842 #, c-format msgid "Download of hostlist `%s' completed.\n" msgstr "" -#: src/hostlist/hostlist-client.c:856 +#: src/hostlist/hostlist-client.c:850 #, c-format msgid "Adding successfully tested hostlist `%s' datastore.\n" msgstr "" -#: src/hostlist/hostlist-client.c:909 +#: src/hostlist/hostlist-client.c:903 #, c-format msgid "Bootstrapping using hostlist at `%s'.\n" msgstr "" -#: src/hostlist/hostlist-client.c:917 +#: src/hostlist/hostlist-client.c:911 msgid "# hostlist downloads initiated" msgstr "" -#: src/hostlist/hostlist-client.c:1045 src/hostlist/hostlist-client.c:1515 +#: src/hostlist/hostlist-client.c:1037 src/hostlist/hostlist-client.c:1505 msgid "# milliseconds between hostlist downloads" msgstr "" -#: src/hostlist/hostlist-client.c:1054 +#: src/hostlist/hostlist-client.c:1046 #, c-format msgid "Have %u/%u connections. Will consider downloading hostlist in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1092 +#: src/hostlist/hostlist-client.c:1084 msgid "Scheduled saving of hostlists\n" msgstr "" -#: src/hostlist/hostlist-client.c:1096 +#: src/hostlist/hostlist-client.c:1088 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1119 src/hostlist/hostlist-client.c:1135 +#: src/hostlist/hostlist-client.c:1111 src/hostlist/hostlist-client.c:1127 msgid "# active connections" msgstr "" -#: src/hostlist/hostlist-client.c:1253 +#: src/hostlist/hostlist-client.c:1242 #, c-format msgid "Initial time between hostlist downloads is %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1284 +#: src/hostlist/hostlist-client.c:1273 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot load hostlists from file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1290 +#: src/hostlist/hostlist-client.c:1279 #, c-format msgid "Loading saved hostlist entries from file `%s' \n" msgstr "" -#: src/hostlist/hostlist-client.c:1294 +#: src/hostlist/hostlist-client.c:1283 #, c-format msgid "Hostlist file `%s' is not existing\n" msgstr "" -#: src/hostlist/hostlist-client.c:1305 +#: src/hostlist/hostlist-client.c:1294 #, fuzzy, c-format msgid "Could not open file `%s' for reading to load hostlists: %s\n" msgstr "无法解析“%s”来确定已方的 IP 地址:%s\n" -#: src/hostlist/hostlist-client.c:1338 +#: src/hostlist/hostlist-client.c:1327 #, c-format msgid "%u hostlist URIs loaded from file\n" msgstr "" -#: src/hostlist/hostlist-client.c:1340 +#: src/hostlist/hostlist-client.c:1329 msgid "# hostlist URIs read from file" msgstr "" -#: src/hostlist/hostlist-client.c:1373 +#: src/hostlist/hostlist-client.c:1362 #, c-format msgid "" "No `%s' specified in `%s' configuration, cannot save hostlists to file.\n" msgstr "" -#: src/hostlist/hostlist-client.c:1387 +#: src/hostlist/hostlist-client.c:1376 #, fuzzy, c-format msgid "Could not open file `%s' for writing to save hostlists: %s\n" msgstr "无法解析“%s”来确定已方的 IP 地址:%s\n" -#: src/hostlist/hostlist-client.c:1392 +#: src/hostlist/hostlist-client.c:1381 #, c-format msgid "Writing %u hostlist URIs to `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:1416 src/hostlist/hostlist-client.c:1433 +#: src/hostlist/hostlist-client.c:1405 src/hostlist/hostlist-client.c:1422 #, c-format msgid "Error writing hostlist URIs to file `%s'\n" msgstr "" -#: src/hostlist/hostlist-client.c:1428 +#: src/hostlist/hostlist-client.c:1417 msgid "# hostlist URIs written to file" msgstr "" -#: src/hostlist/hostlist-client.c:1480 +#: src/hostlist/hostlist-client.c:1470 msgid "Learning is enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1483 +#: src/hostlist/hostlist-client.c:1473 #, c-format msgid "Hostlists will be saved to file again in %llums\n" msgstr "" -#: src/hostlist/hostlist-client.c:1492 +#: src/hostlist/hostlist-client.c:1482 msgid "Learning is not enabled on this peer\n" msgstr "" -#: src/hostlist/hostlist-client.c:1504 +#: src/hostlist/hostlist-client.c:1494 #, c-format msgid "" "Since learning is not enabled on this peer, hostlist file `%s' was removed\n" msgstr "" -#: src/hostlist/hostlist-client.c:1508 +#: src/hostlist/hostlist-client.c:1498 #, c-format msgid "Hostlist file `%s' could not be removed\n" msgstr "" @@ -3147,8 +3289,10 @@ msgstr "" msgid "expired addresses encountered" msgstr "" -#: src/hostlist/hostlist-server.c:184 -#: src/topology/gnunet-daemon-topology.c:875 +#: src/hostlist/hostlist-server.c:184 src/hostlist/hostlist-server.c:425 +#: src/peerinfo-tool/gnunet-peerinfo.c:403 +#: src/peerinfo-tool/gnunet-peerinfo.c:519 +#: src/topology/gnunet-daemon-topology.c:927 #, c-format msgid "Error in communication with PEERINFO service: %s\n" msgstr "" @@ -3157,246 +3301,553 @@ msgstr "" msgid "HELLOs without addresses encountered (ignored)" msgstr "" -#: src/hostlist/hostlist-server.c:221 +#: src/hostlist/hostlist-server.c:219 msgid "bytes not included in hostlist (size limit)" msgstr "" -#: src/hostlist/hostlist-server.c:269 +#: src/hostlist/hostlist-server.c:263 #, c-format msgid "Refusing `%s' request to hostlist server\n" msgstr "" -#: src/hostlist/hostlist-server.c:272 +#: src/hostlist/hostlist-server.c:266 msgid "hostlist requests refused (not HTTP GET)" msgstr "" -#: src/hostlist/hostlist-server.c:280 +#: src/hostlist/hostlist-server.c:273 msgid "Sending 100 CONTINUE reply\n" msgstr "" -#: src/hostlist/hostlist-server.c:287 +#: src/hostlist/hostlist-server.c:279 #, c-format msgid "Refusing `%s' request with %llu bytes of upload data\n" msgstr "" -#: src/hostlist/hostlist-server.c:291 +#: src/hostlist/hostlist-server.c:283 msgid "hostlist requests refused (upload data)" msgstr "" -#: src/hostlist/hostlist-server.c:299 +#: src/hostlist/hostlist-server.c:291 msgid "Could not handle hostlist request since I do not have a response yet\n" msgstr "" -#: src/hostlist/hostlist-server.c:302 +#: src/hostlist/hostlist-server.c:294 msgid "hostlist requests refused (not ready)" msgstr "" -#: src/hostlist/hostlist-server.c:306 +#: src/hostlist/hostlist-server.c:298 msgid "Received request for our hostlist\n" msgstr "" -#: src/hostlist/hostlist-server.c:307 +#: src/hostlist/hostlist-server.c:299 msgid "hostlist requests processed" msgstr "" -#: src/hostlist/hostlist-server.c:350 +#: src/hostlist/hostlist-server.c:341 msgid "# hostlist advertisements send" msgstr "" -#: src/hostlist/hostlist-server.c:397 +#: src/hostlist/hostlist-server.c:388 msgid "Advertisement message could not be queued by core\n" msgstr "" -#: src/hostlist/hostlist-server.c:565 +#: src/hostlist/hostlist-server.c:561 #, c-format msgid "Invalid port number %llu. Exiting.\n" msgstr "" -#: src/hostlist/hostlist-server.c:574 +#: src/hostlist/hostlist-server.c:570 #, c-format msgid "Hostlist service starts on %s:%llu\n" msgstr "" -#: src/hostlist/hostlist-server.c:588 +#: src/hostlist/hostlist-server.c:584 #, c-format msgid "Address to obtain hostlist: `%s'\n" msgstr "" -#: src/hostlist/hostlist-server.c:626 +#: src/hostlist/hostlist-server.c:624 +#, fuzzy, c-format +msgid "`%s' is not a valid IP address! Ignoring BINDTOIP.\n" +msgstr "“%s”不可用。\n" + +#: src/hostlist/hostlist-server.c:666 #, c-format msgid "Could not start hostlist HTTP server on port %u\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4595 +#: src/integration-tests/connection_watchdog.c:997 +#, c-format +msgid "Transport plugin: `%s' port %llu\n" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1030 +#, fuzzy, c-format +msgid "Found %u transport plugins: `%s'\n" +msgstr "解析配置文件“%s”失败\n" + +#: src/integration-tests/connection_watchdog.c:1089 +msgid "Send ping messages to test connectivity (default == NO)" +msgstr "" + +#: src/integration-tests/connection_watchdog.c:1095 +#: src/template/gnunet-template.c:68 +msgid "help text" +msgstr "" + +#: src/mesh/gnunet-service-mesh.c:4590 msgid "Wrong CORE service\n" msgstr "" -#: src/mesh/gnunet-service-mesh.c:4789 +#: src/mesh/gnunet-service-mesh.c:4784 #, fuzzy msgid "Mesh service is lacking key configuration settings. Exiting.\n" msgstr "立即保存配置?" -#: src/mesh/gnunet-service-mesh.c:4798 +#: src/mesh/gnunet-service-mesh.c:4793 #, fuzzy msgid "Mesh service could not access hostkey. Exiting.\n" msgstr "找不到接口“%s”的一个 IP 地址。\n" -#: src/namestore/namestore_api.c:272 src/namestore/namestore_api.c:313 -msgid "Namestore added record successfully" +#: src/mysql/mysql.c:174 +#, c-format +msgid "Trying to use file `%s' for MySQL configuration.\n" msgstr "" -#: src/namestore/namestore_api.c:281 src/namestore/namestore_api.c:322 -msgid "Namestore failed to add record" -msgstr "" +#: src/mysql/mysql.c:181 +#, fuzzy, c-format +msgid "Could not access file `%s': %s\n" +msgstr "无法解析“%s”(%s):%s\n" -#: src/nat/gnunet-nat-server.c:289 +#: src/namestore/gnunet-namestore.c:157 #, c-format -msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgid "Adding record failed: %s\n" msgstr "" -#: src/nat/gnunet-nat-server.c:328 -msgid "GNUnet NAT traversal test helper daemon" +#: src/namestore/gnunet-namestore.c:183 +#, c-format +msgid "Deleting record failed: %s\n" msgstr "" -#: src/nat/nat.c:803 +#: src/namestore/gnunet-namestore.c:239 #, c-format -msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgid "\tCorrupt or unsupported record of type %u\n" msgstr "" -#: src/nat/nat.c:852 -#, fuzzy, c-format -msgid "Failed to start %s\n" -msgstr "运行 %s失败:%s %d\n" +#: src/namestore/gnunet-namestore.c:276 +#, c-format +msgid "Option `%s' not given, but I need a zone key file!\n" +msgstr "" -#: src/nat/nat.c:1121 +#: src/namestore/gnunet-namestore.c:281 #, fuzzy, c-format -msgid "Malformed %s `%s' given in configuration!\n" -msgstr "保存配置失败。" +msgid "Using default zone file `%s'\n" +msgstr "卸载 GNUnet 服务" -#: src/nat/nat.c:1187 src/nat/nat.c:1197 +#: src/namestore/gnunet-namestore.c:291 #, c-format -msgid "" -"Configuration requires `%s', but binary is not installed properly (SUID bit " -"not set). Option disabled.\n" +msgid "No options given\n" msgstr "" -#: src/nat/nat.c:1329 -msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" +#: src/namestore/gnunet-namestore.c:321 +#, fuzzy, c-format +msgid "Unsupported type `%s'\n" +msgstr "未知的命令“%s”。\n" + +#: src/namestore/gnunet-namestore.c:328 src/namestore/gnunet-namestore.c:350 +#: src/namestore/gnunet-namestore.c:374 src/namestore/gnunet-namestore.c:384 +#: src/namestore/gnunet-namestore.c:409 +#, fuzzy, c-format +msgid "Missing option `%s' for operation `%s'\n" +msgstr "配置文件“%s”已写入。\n" + +#: src/namestore/gnunet-namestore.c:329 src/namestore/gnunet-namestore.c:351 +msgid "add/del" msgstr "" -#: src/nat/nat.c:1341 +#: src/namestore/gnunet-namestore.c:341 #, c-format -msgid "Running gnunet-helper-nat-client %s %s %u\n" +msgid "Value `%s' invalid for record type `%s'\n" msgstr "" -#: src/nat/nat_test.c:348 -msgid "Failed to connect to `gnunet-nat-server'\n" +#: src/namestore/gnunet-namestore.c:366 +#, fuzzy, c-format +msgid "Invalid time format `%s'\n" +msgstr "IP 格式无效:“%s”\n" + +#: src/namestore/gnunet-namestore.c:375 src/namestore/gnunet-namestore.c:385 +msgid "add" msgstr "" -#: src/nat/nat_test.c:418 -#, c-format -msgid "Failed to create listen socket bound to `%s' for NAT test: %s\n" +#: src/namestore/gnunet-namestore.c:410 +msgid "del" msgstr "" -#: src/nse/gnunet-nse-profiler.c:926 -#, fuzzy -msgid "Measure quality and performance of the NSE service." -msgstr "无法访问该服务" +#: src/namestore/gnunet-namestore.c:462 +msgid "add record" +msgstr "" -#: src/nse/gnunet-service-nse.c:936 -#, c-format -msgid "Proof of work invalid: %llu!\n" +#: src/namestore/gnunet-namestore.c:465 +msgid "delete record" msgstr "" -#: src/nse/gnunet-service-nse.c:1391 src/nse/gnunet-service-nse.c:1410 -#: src/nse/gnunet-service-nse.c:1431 -msgid "NSE service is lacking key configuration settings. Exiting.\n" +#: src/namestore/gnunet-namestore.c:468 +msgid "display records" msgstr "" -#: src/nse/gnunet-service-nse.c:1398 -msgid "Invalid work requirement for NSE service. Exiting.\n" +#: src/namestore/gnunet-namestore.c:471 +msgid "" +"expiration time for record to use (for adding only), \"never\" is possible" msgstr "" -#: src/nse/gnunet-service-nse.c:1419 -#, fuzzy +#: src/namestore/gnunet-namestore.c:474 +msgid "name of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:477 +msgid "type of the record to add/delete/display" +msgstr "" + +#: src/namestore/gnunet-namestore.c:480 +msgid "value of the record to add/delete" +msgstr "" + +#: src/namestore/gnunet-namestore.c:483 +msgid "create or list public record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:486 +msgid "create or list non-authority record" +msgstr "" + +#: src/namestore/gnunet-namestore.c:489 +msgid "filename with the zone key" +msgstr "" + +#: src/namestore/gnunet-namestore.c:500 +#, fuzzy +msgid "GNUnet zone manipulation tool" +msgstr "GNUnet 配置" + +#: src/namestore/gnunet-service-namestore.c:143 +#, c-format +msgid "File zone `%s' but corrupt content already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:154 +#, c-format +msgid "File zone `%s' containing this key already exists\n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:160 +#, c-format +msgid "" +"File zone `%s' but different zone key already exists, failed to write! \n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:198 +#, fuzzy, c-format +msgid "Stored zonekey for zone `%s' in file `%s'\n" +msgstr "打开日志文件“%s”失败:%s\n" + +#: src/namestore/gnunet-service-namestore.c:1909 +msgid "No directory to load zonefiles specified in configuration\n" +msgstr "" + +#: src/namestore/gnunet-service-namestore.c:1918 +#, c-format +msgid "Creating directory `%s' for zone files failed!\n" +msgstr "" + +#: src/namestore/namestore_api.c:315 src/namestore/namestore_api.c:353 +msgid "Namestore added record successfully" +msgstr "" + +#: src/namestore/namestore_api.c:323 +msgid "Namestore failed to add record" +msgstr "" + +#: src/namestore/namestore_api.c:361 +msgid "Namestore record already existed" +msgstr "" + +#: src/namestore/namestore_api.c:368 +msgid "Namestore failed to add record\n" +msgstr "" + +#: src/namestore/namestore_api.c:401 +#, fuzzy +msgid "Namestore removed record successfully" +msgstr "GNUnet 服务安装成功。\n" + +#: src/namestore/namestore_api.c:408 +msgid "No records for entry" +msgstr "" + +#: src/namestore/namestore_api.c:415 +#, fuzzy +msgid "Could not find record to remove" +msgstr "无法连接到 %s:%u:%s\n" + +#: src/namestore/namestore_api.c:422 +#, fuzzy +msgid "Failed to create new signature" +msgstr "发送消息失败。\n" + +#: src/namestore/namestore_api.c:429 +msgid "Failed to put new set of records in database" +msgstr "" + +#: src/nat/gnunet-nat-server.c:279 +#, c-format +msgid "Please pass valid port number as the first argument! (got `%s')\n" +msgstr "" + +#: src/nat/gnunet-nat-server.c:318 +msgid "GNUnet NAT traversal test helper daemon" +msgstr "" + +#: src/nat/nat.c:799 +#, c-format +msgid "gnunet-helper-nat-server generated malformed address `%s'\n" +msgstr "" + +#: src/nat/nat.c:844 +#, fuzzy, c-format +msgid "Failed to start %s\n" +msgstr "运行 %s失败:%s %d\n" + +#: src/nat/nat.c:1111 +#, fuzzy, c-format +msgid "Malformed %s `%s' given in configuration!\n" +msgstr "保存配置失败。" + +#: src/nat/nat.c:1177 src/nat/nat.c:1187 +#, c-format +msgid "" +"Configuration requires `%s', but binary is not installed properly (SUID bit " +"not set). Option disabled.\n" +msgstr "" + +#: src/nat/nat.c:1321 +msgid "Internal IP address not known, cannot use ICMP NAT traversal method\n" +msgstr "" + +#: src/nat/nat.c:1332 +#, c-format +msgid "Running gnunet-helper-nat-client %s %s %u\n" +msgstr "" + +#: src/nat/nat_test.c:341 +msgid "Failed to connect to `gnunet-nat-server'\n" +msgstr "" + +#: src/nat/nat_test.c:411 +#, c-format +msgid "Failed to create listen socket bound to `%s' for NAT test: %s\n" +msgstr "" + +#: src/nse/gnunet-nse-profiler.c:928 +#, fuzzy +msgid "Measure quality and performance of the NSE service." +msgstr "无法访问该服务" + +#: src/nse/gnunet-service-nse.c:925 +#, c-format +msgid "Proof of work invalid: %llu!\n" +msgstr "" + +#: src/nse/gnunet-service-nse.c:1381 src/nse/gnunet-service-nse.c:1400 +#: src/nse/gnunet-service-nse.c:1421 +msgid "NSE service is lacking key configuration settings. Exiting.\n" +msgstr "" + +#: src/nse/gnunet-service-nse.c:1388 +msgid "Invalid work requirement for NSE service. Exiting.\n" +msgstr "" + +#: src/nse/gnunet-service-nse.c:1409 +#, fuzzy msgid "NSE service could not access hostkey. Exiting.\n" msgstr "找不到接口“%s”的一个 IP 地址。\n" -#: src/peerinfo/gnunet-service-peerinfo.c:133 +#: src/peerinfo/gnunet-service-peerinfo.c:134 #, c-format msgid "Removing expired address of transport `%s'\n" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:195 +#: src/peerinfo/gnunet-service-peerinfo.c:203 +#, fuzzy, c-format +msgid "Failed to parse HELLO in file `%s'\n" +msgstr "解析配置文件“%s”失败\n" + +#: src/peerinfo/gnunet-service-peerinfo.c:229 msgid "# peers known" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:239 +#: src/peerinfo/gnunet-service-peerinfo.c:254 #, c-format msgid "" "File `%s' in directory `%s' does not match naming convention. Removed.\n" msgstr "" -#: src/peerinfo/gnunet-service-peerinfo.c:305 +#: src/peerinfo/gnunet-service-peerinfo.c:353 #, c-format msgid "Still no peers found in `%s'!\n" msgstr "" -#: src/peerinfo/peerinfo_api.c:279 -#, fuzzy, c-format -msgid "Failed to transmit message to `%s' service.\n" -msgstr "初始化“%s”服务失败。\n" - -#: src/peerinfo/peerinfo_api.c:435 -msgid "Failed to receive response from `PEERINFO' service." +#: src/peerinfo/gnunet-service-peerinfo.c:710 +#, c-format +msgid "Importing HELLOs from `%s'\n" msgstr "" -#: src/peerinfo/peerinfo_api.c:463 src/peerinfo/peerinfo_api.c:481 -msgid "Received invalid message from `PEERINFO' service.\n" +#: src/peerinfo/peerinfo_api.c:238 +msgid "aborted due to explicit disconnect request" msgstr "" -#: src/peerinfo/peerinfo_api.c:523 +#: src/peerinfo/peerinfo_api.c:358 #, fuzzy -msgid "Failed to transmit iteration request to `PEERINFO' service\n" +msgid "failed to transmit request (service down?)" msgstr "初始化“%s”服务失败。\n" -#: src/peerinfo/peerinfo_api.c:557 -msgid "Timeout transmitting iteration request to `PEERINFO' service.\n" +#: src/peerinfo/peerinfo_api.c:505 +msgid "Failed to receive response from `PEERINFO' service." msgstr "" -#: src/peerinfo/peerinfo_api_notify.c:258 +#: src/peerinfo/peerinfo_api.c:531 src/peerinfo/peerinfo_api.c:550 +#: src/peerinfo/peerinfo_api.c:565 src/peerinfo/peerinfo_api.c:576 +#: src/peerinfo/peerinfo_api.c:587 +#, fuzzy +msgid "Received invalid message from `PEERINFO' service." +msgstr "“%s”的参数无效。\n" + +#: src/peerinfo/peerinfo_api.c:663 +#, fuzzy +msgid "Timeout transmitting iteration request to `PEERINFO' service." +msgstr "初始化“%s”服务失败。\n" + +#: src/peerinfo/peerinfo_api_notify.c:256 #, fuzzy, c-format msgid "Could not connect to `%s' service.\n" msgstr "无法连接到 %s:%u:%s\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:216 +#: src/peerinfo-tool/gnunet-peerinfo.c:581 +#, fuzzy +msgid "Failed to parse HELLO message: missing expiration time\n" +msgstr "保存配置失败。" + +#: src/peerinfo-tool/gnunet-peerinfo.c:589 +#, fuzzy +msgid "Failed to parse HELLO message: invalid expiration time\n" +msgstr "保存配置失败。" + +#: src/peerinfo-tool/gnunet-peerinfo.c:598 +#, fuzzy +msgid "Failed to parse HELLO message: malformed\n" +msgstr "打开日志文件“%s”失败:%s\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:608 +msgid "Failed to parse HELLO message: missing transport plugin\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:625 +#, c-format +msgid "Plugin `%s' not found\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:634 +#, c-format +msgid "Plugin `%s' does not support URIs yet\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:653 +#, fuzzy, c-format +msgid "Failed to parse `%s' as an address for plugin `%s'\n" +msgstr "找不到接口“%s”的一个 IP 地址。\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:685 +#, c-format +msgid "Failure adding HELLO: %s\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:833 #, fuzzy, c-format msgid "Could not find option `%s:%s' in configuration.\n" msgstr "找不到主机“%s”的 IP:%s\n" -#: src/peerinfo-tool/gnunet-peerinfo.c:223 +#: src/peerinfo-tool/gnunet-peerinfo.c:840 #, c-format msgid "Loading hostkey from `%s' failed.\n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:235 +#: src/peerinfo-tool/gnunet-peerinfo.c:875 +#, fuzzy, c-format +msgid "Invalid URI `%s'\n" +msgstr "无效条目。\n" + +#: src/peerinfo-tool/gnunet-peerinfo.c:899 #, c-format msgid "I am peer `%s'.\n" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:255 +#: src/peerinfo-tool/gnunet-peerinfo.c:936 +msgid "don't resolve host names" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:939 msgid "output only the identity strings" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:258 +#: src/peerinfo-tool/gnunet-peerinfo.c:942 msgid "output our own identity only" msgstr "" -#: src/peerinfo-tool/gnunet-peerinfo.c:264 +#: src/peerinfo-tool/gnunet-peerinfo.c:945 +#, fuzzy +msgid "list all known peers" +msgstr "列出所有网络适配器" + +#: src/peerinfo-tool/gnunet-peerinfo.c:948 +msgid "also output HELLO uri(s)" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:951 +msgid "add given HELLO uri to the database" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo.c:957 #, fuzzy msgid "Print information about peers." msgstr "无法获取有关用户“%s”的信息:%s\n" +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:105 +#: src/transport/gnunet-service-transport_plugins.c:118 +#, c-format +msgid "Starting transport plugins `%s'\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:109 +#: src/transport/gnunet-service-transport_plugins.c:122 +#, c-format +msgid "Loading `%s' transport plugin\n" +msgstr "" + +#: src/peerinfo-tool/gnunet-peerinfo_plugins.c:129 +#: src/transport/gnunet-service-transport_plugins.c:150 +#, fuzzy, c-format +msgid "Failed to load transport plugin for `%s'\n" +msgstr "解析配置文件“%s”失败\n" + +#: src/postgres/postgres.c:59 +#, fuzzy, c-format +msgid "`%s:%s' failed at %s:%d with error: %s" +msgstr "“%s”于 %s:%d 处失败,错误为:%s\n" + +#: src/postgres/postgres.c:148 +#, fuzzy, c-format +msgid "Unable to initialize Postgres: %s" +msgstr "无法初始化 SQLite:%s。\n" + #: src/pt/gnunet-daemon-pt.c:264 msgid "Failed to pack DNS request. Dropping.\n" msgstr "" @@ -3455,48 +3906,64 @@ msgstr "初始化“%s”服务失败。\n" msgid "Daemon to run to perform IP protocol translation to GNUnet" msgstr "" -#: src/statistics/gnunet-service-statistics.c:209 +#: src/statistics/gnunet-service-statistics.c:271 #, c-format msgid "Loading %llu bytes of statistics from `%s'\n" msgstr "" -#: src/statistics/gnunet-service-statistics.c:267 +#: src/statistics/gnunet-service-statistics.c:330 #, c-format msgid "Wrote %llu bytes of statistics to `%s'\n" msgstr "" -#: src/statistics/gnunet-statistics.c:98 +#: src/statistics/gnunet-statistics.c:122 #, fuzzy msgid "Failed to obtain statistics.\n" msgstr "初始化“%s”服务失败。\n" -#: src/statistics/gnunet-statistics.c:164 +#: src/statistics/gnunet-statistics.c:199 +#, c-format +msgid "No subsystem or name given\n" +msgstr "" + +#: src/statistics/gnunet-statistics.c:207 +#, fuzzy, c-format +msgid "Failed to initialize watch routine\n" +msgstr "初始化“%s”服务失败。\n" + +#: src/statistics/gnunet-statistics.c:227 msgid "limit output to statistics for the given NAME" msgstr "" -#: src/statistics/gnunet-statistics.c:167 +#: src/statistics/gnunet-statistics.c:230 msgid "make the value being set persistent" msgstr "" -#: src/statistics/gnunet-statistics.c:170 +#: src/statistics/gnunet-statistics.c:233 msgid "limit output to the given SUBSYSTEM" msgstr "" -#: src/statistics/gnunet-statistics.c:173 +#: src/statistics/gnunet-statistics.c:236 msgid "just print the statistics value" msgstr "" -#: src/statistics/gnunet-statistics.c:180 +#: src/statistics/gnunet-statistics.c:239 +msgid "watch value continously" +msgstr "" + +#: src/statistics/gnunet-statistics.c:246 msgid "Print statistics about GNUnet operations." msgstr "" -#: src/statistics/statistics_api.c:390 +#: src/statistics/statistics_api.c:456 #, fuzzy -msgid "Failed to connect to statistics service!\n" +msgid "Could not save some persistent statistics\n" msgstr "初始化“%s”服务失败。\n" -#: src/template/gnunet-template.c:68 -msgid "help text" +#: src/statistics/statistics_api.c:999 +msgid "" +"Failed to receive acknowledgement from statistics service, some statistics " +"might have been lost!\n" msgstr "" #: src/testing/gnunet-testing.c:157 @@ -3546,597 +4013,434 @@ msgstr "立即保存配置?" msgid "Could not access hostkey.\n" msgstr "找不到接口“%s”的一个 IP 地址。\n" -#: src/testing/testing.c:204 +#: src/testing/testing.c:200 msgid "`scp' does not seem to terminate (timeout copying config).\n" msgstr "" -#: src/testing/testing.c:218 src/testing/testing.c:808 +#: src/testing/testing.c:214 src/testing/testing.c:798 msgid "`scp' did not complete cleanly.\n" msgstr "" -#: src/testing/testing.c:239 +#: src/testing/testing.c:237 #, fuzzy msgid "Failed to create pipe for `gnunet-peerinfo' process.\n" msgstr "初始化“%s”服务失败。\n" -#: src/testing/testing.c:240 +#: src/testing/testing.c:238 #, fuzzy msgid "Failed to create pipe for `ssh' process.\n" msgstr "初始化“%s”服务失败。\n" -#: src/testing/testing.c:292 +#: src/testing/testing.c:286 #, fuzzy, c-format msgid "Could not start `%s' process to create hostkey.\n" msgstr "初始化“%s”服务失败。\n" -#: src/testing/testing.c:299 +#: src/testing/testing.c:293 #, fuzzy msgid "Failed to start `gnunet-peerinfo' process.\n" msgstr "初始化“%s”服务失败。\n" -#: src/testing/testing.c:300 src/testing/testing.c:488 +#: src/testing/testing.c:294 src/testing/testing.c:471 #, fuzzy msgid "Failed to start `ssh' process.\n" msgstr "初始化“%s”服务失败。\n" -#: src/testing/testing.c:360 +#: src/testing/testing.c:354 #, c-format msgid "Error reading from gnunet-peerinfo: %s\n" msgstr "" -#: src/testing/testing.c:364 +#: src/testing/testing.c:358 msgid "Malformed output from gnunet-peerinfo!\n" msgstr "" -#: src/testing/testing.c:374 +#: src/testing/testing.c:368 #, fuzzy msgid "Failed to get hostkey!\n" msgstr "发送消息失败。\n" -#: src/testing/testing.c:406 +#: src/testing/testing.c:400 msgid "`Failed while waiting for topology setup!\n" msgstr "" -#: src/testing/testing.c:480 +#: src/testing/testing.c:463 #, fuzzy, c-format msgid "Could not start `%s' process to start GNUnet.\n" msgstr "初始化“%s”服务失败。\n" -#: src/testing/testing.c:487 +#: src/testing/testing.c:470 #, fuzzy msgid "Failed to start `gnunet-arm' process.\n" msgstr "初始化“%s”服务失败。\n" -#: src/testing/testing.c:509 src/testing/testing.c:612 +#: src/testing/testing.c:493 src/testing/testing.c:600 msgid "`gnunet-arm' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:510 src/testing/testing.c:613 -#: src/testing/testing.c:633 +#: src/testing/testing.c:494 src/testing/testing.c:601 +#: src/testing/testing.c:621 msgid "`ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:582 +#: src/testing/testing.c:570 msgid "Unable to get HELLO for peer!\n" msgstr "" -#: src/testing/testing.c:632 +#: src/testing/testing.c:620 msgid "`gnunet-arm' terminated with non-zero exit status (or timed out)!\n" msgstr "" -#: src/testing/testing.c:653 src/testing/testing.c:685 +#: src/testing/testing.c:643 src/testing/testing.c:675 msgid "either `gnunet-arm' or `ssh' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:668 src/testing/testing.c:723 +#: src/testing/testing.c:658 src/testing/testing.c:713 msgid "shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n" msgstr "" -#: src/testing/testing.c:796 +#: src/testing/testing.c:786 msgid "`scp' does not seem to terminate.\n" msgstr "" -#: src/testing/testing.c:966 +#: src/testing/testing.c:948 #, fuzzy, c-format msgid "Starting service %s for peer `%4s'\n" msgstr "卸载 GNUnet 服务" -#: src/testing/testing.c:1237 src/testing/testing_group.c:6278 +#: src/testing/testing.c:1207 src/testing/testing_group.c:6154 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration directory.\n" msgstr "找不到主机“%s”的 IP:%s\n" -#: src/testing/testing.c:1322 src/testing/testing.c:1397 +#: src/testing/testing.c:1292 src/testing/testing.c:1359 #, fuzzy, c-format msgid "Terminating peer `%4s'\n" msgstr "未知的用户“%s”\n" -#: src/testing/testing.c:1480 +#: src/testing/testing.c:1448 #, fuzzy, c-format msgid "Setting d->dead on peer `%4s'\n" msgstr "卸载 GNUnet 服务" -#: src/testing/testing.c:1610 +#: src/testing/testing.c:1601 msgid "Peer not yet running, can not change configuration at this point." msgstr "" -#: src/testing/testing.c:1618 +#: src/testing/testing.c:1609 #, fuzzy msgid "Failed to write new configuration to disk." msgstr "保存配置失败。" -#: src/testing/testing.c:1647 +#: src/testing/testing.c:1636 #, fuzzy, c-format msgid "Could not start `%s' process to copy configuration file.\n" msgstr "找不到主机“%s”的 IP:%s\n" -#: src/testing/testing.c:1650 +#: src/testing/testing.c:1639 #, fuzzy msgid "Failed to copy new configuration to remote machine." msgstr "保存配置失败。" -#: src/testing/testing.c:1805 +#: src/testing/testing.c:1794 #, fuzzy msgid "Peers failed to connect" msgstr "" "\n" "按任意键继续\n" -#: src/testing/testing.c:1933 +#: src/testing/testing.c:1922 #, fuzzy msgid "Failed to connect to core service of first peer!\n" msgstr "加载 sqstore 服务失败。检查您的配置!\n" -#: src/testing/testing.c:2156 +#: src/testing/testing.c:2145 msgid "Peers are not fully running yet, can not connect!\n" msgstr "" -#: src/testing/testing_group.c:1910 src/testing/testing_group.c:1922 -#: src/testing/testing_group.c:2023 src/testing/testing_group.c:2082 -#: src/testing/testing_group.c:2171 src/testing/testing_group.c:2191 -#: src/testing/testing_group.c:2328 src/testing/testing_peergroup.c:940 +#: src/testing/testing_group.c:1895 src/testing/testing_group.c:1907 +#: src/testing/testing_group.c:2008 src/testing/testing_group.c:2065 +#: src/testing/testing_group.c:2152 src/testing/testing_group.c:2172 +#: src/testing/testing_group.c:2302 src/testing/testing_peergroup.c:950 #, fuzzy, c-format msgid "Invalid value `%s' for option `%s' in section `%s': expected float\n" msgstr "配置不满足配置规范文件“%s”的约束!\n" -#: src/testing/testing_group.c:1932 -#, c-format -msgid "Target is %d connections per peer." -msgstr "" - -#: src/testing/testing_group.c:2179 +#: src/testing/testing_group.c:2160 #, c-format msgid "" "Invalid value `%s' for option `%s' in section `%s': got %f, needed value " "greater than 0\n" msgstr "" -#: src/testing/testing_group.c:2209 src/testing/testing_group.c:2402 -#, c-format -msgid "Connecting nodes in 2d torus topology: %u rows %u columns\n" -msgstr "" - -#: src/testing/testing_group.c:2246 -#, c-format -msgid "natural log of %d is %d, will run %d iterations\n" -msgstr "" - -#: src/testing/testing_group.c:2249 -#, c-format -msgid "Total connections added thus far: %u!\n" -msgstr "" - -#: src/testing/testing_group.c:2290 -#, c-format -msgid "Total connections added for small world: %d!\n" -msgstr "" - -#: src/testing/testing_group.c:2342 -#, c-format -msgid "rand is %f probability is %f\n" -msgstr "" - -#: src/testing/testing_group.c:2919 src/testing/testing_group.c:3118 +#: src/testing/testing_group.c:2877 src/testing/testing_group.c:3063 #, c-format msgid "" "No `%s' specified in peer configuration in section `%s', cannot copy friends " "file!\n" msgstr "" -#: src/testing/testing_group.c:3020 -msgid "Finished copying all friend files!\n" -msgstr "" - -#: src/testing/testing_group.c:3133 -#, fuzzy, c-format -msgid "Copying file with command cp %s %s\n" -msgstr "“%s”以错误码 %s 失败:%s\n" - -#: src/testing/testing_group.c:3156 -#, fuzzy, c-format -msgid "Copying file with command scp %s %s\n" -msgstr "“%s”以错误码 %s 失败:%s\n" - -#: src/testing/testing_group.c:3173 -#, c-format -msgid "Checking copy status of file %d\n" +#: src/testing/testing_group.c:3957 +msgid "Creating no allowed topology (all peers can connect at core level)\n" msgstr "" -#: src/testing/testing_group.c:3191 -#, c-format -msgid "File %d copied\n" +#: src/testing/testing_group.c:5226 +msgid "Unknown topology specification, can't connect peers!\n" msgstr "" -#: src/testing/testing_group.c:3206 +#: src/testing/testing_group.c:5944 src/transport/transport-testing.c:636 #, fuzzy -msgid "Finished copying all blacklist files!\n" -msgstr "无法解析“%s”(%s):%s\n" - -#: src/testing/testing_group.c:3586 src/testing/testing_group.c:3723 -#: src/testing/testing_group.c:4884 src/testing/testing_group.c:5025 -msgid "Delaying connect, we have too many outstanding connections!\n" -msgstr "" +msgid "Could not read hostkeys file!\n" +msgstr "找不到接口“%s”的一个 IP 地址。\n" -#: src/testing/testing_group.c:3596 src/testing/testing_group.c:4894 -#: src/testing/testing_group.c:5035 -#, c-format -msgid "Creating connection, outstanding_connections is %d\n" -msgstr "" +#: src/testing/testing_group.c:6011 +#, fuzzy, c-format +msgid "Could not create configuration for peer number %u on `%s'!\n" +msgstr "解析配置文件“%s”失败\n" -#: src/testing/testing_group.c:3608 -#, c-format -msgid "Offering HELLO of peer %s to peer %s\n" +#: src/testing/testing_new.c:169 +msgid "tmppath cannot be NULL\n" msgstr "" -#: src/testing/testing_group.c:3734 +#: src/testing/testing_new.c:356 #, c-format -msgid "Creating connection, outstanding_connections is %d (max %d)\n" -msgstr "" - -#: src/testing/testing_group.c:3988 -msgid "Creating clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:3993 -msgid "Creating small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:3998 -msgid "Creating small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4002 -msgid "Creating ring topology\n" +msgid "Hostkeys file not found: %s\n" msgstr "" -#: src/testing/testing_group.c:4006 -msgid "Creating 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4010 -msgid "Creating Erdos-Renyi topology\n" -msgstr "" - -#: src/testing/testing_group.c:4014 -msgid "Creating InterNAT topology\n" -msgstr "" - -#: src/testing/testing_group.c:4018 -msgid "Creating Scale Free topology\n" -msgstr "" - -#: src/testing/testing_group.c:4023 -msgid "Creating straight line topology\n" -msgstr "" - -#: src/testing/testing_group.c:4027 -msgid "Creating topology from file!\n" -msgstr "" - -#: src/testing/testing_group.c:4043 -msgid "Creating no allowed topology (all peers can connect at core level)\n" -msgstr "" - -#: src/testing/testing_group.c:4058 -msgid "Failed during friend file copying!\n" -msgstr "" - -#: src/testing/testing_group.c:4064 -msgid "Friend files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:4081 -msgid "Blacklisting all but clique topology\n" -msgstr "" - -#: src/testing/testing_group.c:4087 -msgid "Blacklisting all but small world (ring) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4093 -msgid "Blacklisting all but small world (2d-torus) topology\n" -msgstr "" - -#: src/testing/testing_group.c:4099 -msgid "Blacklisting all but ring topology\n" -msgstr "" - -#: src/testing/testing_group.c:4105 -msgid "Blacklisting all but 2d torus topology\n" -msgstr "" - -#: src/testing/testing_group.c:4111 -msgid "Blacklisting all but Erdos-Renyi topology\n" -msgstr "" +#: src/testing/testing_new.c:365 +#, fuzzy, c-format +msgid "Could not open hostkeys file: %s\n" +msgstr "找不到接口“%s”的一个 IP 地址。\n" -#: src/testing/testing_group.c:4117 -msgid "Blacklisting all but InterNAT topology\n" +#: src/testing/testing_new.c:380 +#, c-format +msgid "Incorrect hostkey file format: %s\n" msgstr "" -#: src/testing/testing_group.c:4152 -msgid "Blacklisting all but Scale Free topology\n" +#: src/testing/testing_new.c:437 +#, c-format +msgid "Key number %u does not exist\n" msgstr "" -#: src/testing/testing_group.c:4158 -msgid "Blacklisting all but straight line topology\n" -msgstr "" +#: src/testing/testing_new.c:446 +#, fuzzy, c-format +msgid "Error while decoding key %u\n" +msgstr "解析 dscl 输出时出错。\n" -#: src/testing/testing_group.c:4173 +#: src/testing/testing_new.c:680 #, fuzzy -msgid "Failed during blacklist file copying!\n" +msgid "Failed to create configuration for peer (not enough free ports?)\n" msgstr "解析配置文件“%s”失败\n" -#: src/testing/testing_group.c:4179 -msgid "Blacklist files created/copied successfully!\n" -msgstr "" - -#: src/testing/testing_group.c:5263 -msgid "Creating clique CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5270 -msgid "Creating small world (ring) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5277 -msgid "Creating small world (2d-torus) CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5283 -msgid "Creating ring CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5290 -msgid "Creating 2d torus CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5297 -msgid "Creating Erdos-Renyi CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5304 -msgid "Creating InterNAT CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5311 -msgid "Creating Scale Free CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5318 -msgid "Creating straight line CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5324 -msgid "Creating no CONNECT topology\n" -msgstr "" - -#: src/testing/testing_group.c:5330 -msgid "Unknown topology specification, can't connect peers!\n" -msgstr "" - -#: src/testing/testing_group.c:5340 +#: src/testing/testing_new.c:691 #, c-format -msgid "Connecting random subset (%'.2f percent) of possible peers\n" +msgid "" +"You attempted to create a testbed with more than %u hosts. Please " +"precompute more hostkeys first.\n" msgstr "" -#: src/testing/testing_group.c:5348 -#, c-format -msgid "Connecting a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:704 +#, fuzzy, c-format +msgid "Failed to initialize hostkey for peer %u\n" +msgstr "初始化“%s”服务失败。\n" -#: src/testing/testing_group.c:5357 -#, c-format -msgid "Using DFS to connect a minimum of %u peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:734 +#, fuzzy, c-format +msgid "Failed to write hostkey file for peer %u: %s\n" +msgstr "发送消息失败。\n" -#: src/testing/testing_group.c:5367 -#, c-format -msgid "Finding additional %u closest peers each (if possible)\n" -msgstr "" +#: src/testing/testing_new.c:751 +#, fuzzy, c-format +msgid "Failed to write configuration file `%s' for peer %u: %s\n" +msgstr "解析配置文件“%s”失败\n" -#: src/testing/testing_group.c:6062 src/transport/transport-testing.c:650 -#, fuzzy -msgid "Could not read hostkeys file!\n" -msgstr "找不到接口“%s”的一个 IP 地址。\n" +#: src/testing/testing_new.c:791 +#, fuzzy, c-format +msgid "Failed to start `%s': %s\n" +msgstr "运行 %s失败:%s %d\n" -#: src/testing/testing_group.c:6131 +#: src/testing/testing_new.c:959 #, fuzzy, c-format -msgid "Could not create configuration for peer number %u on `%s'!\n" +msgid "Failed to load configuration from %s\n" msgstr "解析配置文件“%s”失败\n" -#: src/topology/gnunet-daemon-topology.c:244 +#: src/topology/gnunet-daemon-topology.c:259 msgid "# peers blacklisted" msgstr "" -#: src/topology/gnunet-daemon-topology.c:380 +#: src/topology/gnunet-daemon-topology.c:392 msgid "# connect requests issued to transport" msgstr "" -#: src/topology/gnunet-daemon-topology.c:675 -#: src/topology/gnunet-daemon-topology.c:761 +#: src/topology/gnunet-daemon-topology.c:730 +#: src/topology/gnunet-daemon-topology.c:815 msgid "# friends connected" msgstr "" -#: src/topology/gnunet-daemon-topology.c:950 +#: src/topology/gnunet-daemon-topology.c:996 msgid "Failed to connect to core service, can not manage topology!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:982 +#: src/topology/gnunet-daemon-topology.c:1026 #, c-format msgid "Option `%s' in section `%s' not specified!\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:994 +#: src/topology/gnunet-daemon-topology.c:1039 #, c-format msgid "Could not read friends list `%s'\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1000 +#: src/topology/gnunet-daemon-topology.c:1045 #, c-format msgid "Friends file `%s' is empty.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1009 +#: src/topology/gnunet-daemon-topology.c:1054 #, c-format msgid "Failed to read friends list from `%s': out of memory\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1017 +#: src/topology/gnunet-daemon-topology.c:1062 #, c-format msgid "Failed to read friends list from `%s'\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1037 +#: src/topology/gnunet-daemon-topology.c:1082 #, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1050 +#: src/topology/gnunet-daemon-topology.c:1095 #, c-format msgid "" "Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1060 +#: src/topology/gnunet-daemon-topology.c:1105 #, fuzzy, c-format msgid "Found friend `%s' in configuration\n" msgstr "" "\n" "结束配置。\n" -#: src/topology/gnunet-daemon-topology.c:1066 +#: src/topology/gnunet-daemon-topology.c:1111 #, c-format msgid "Found myself `%s' in friend list (useless, ignored)\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1076 +#: src/topology/gnunet-daemon-topology.c:1121 #, fuzzy msgid "# friends in configuration" msgstr "" "\n" "结束配置。\n" -#: src/topology/gnunet-daemon-topology.c:1082 +#: src/topology/gnunet-daemon-topology.c:1127 msgid "" "Fewer friends specified than required by minimum friend count. Will only " "connect to friends.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1089 +#: src/topology/gnunet-daemon-topology.c:1134 msgid "" "More friendly connections required than target total number of connections.\n" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1126 +#: src/topology/gnunet-daemon-topology.c:1169 msgid "# HELLO messages received" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1183 +#: src/topology/gnunet-daemon-topology.c:1224 msgid "# HELLO messages gossipped" msgstr "" -#: src/topology/gnunet-daemon-topology.c:1323 +#: src/topology/gnunet-daemon-topology.c:1363 msgid "GNUnet topology control (maintaining P2P mesh and F2F constraints)" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:247 +#: src/transport/gnunet-service-transport_blacklist.c:246 #, fuzzy, c-format msgid "Could not read blacklist file `%s'\n" msgstr "无法解析“%s”(%s):%s\n" -#: src/transport/gnunet-service-transport_blacklist.c:254 +#: src/transport/gnunet-service-transport_blacklist.c:252 #, c-format msgid "Blacklist file `%s' is empty.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:266 +#: src/transport/gnunet-service-transport_blacklist.c:263 #, fuzzy, c-format msgid "Failed to read blacklist from `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/transport/gnunet-service-transport_blacklist.c:287 -#: src/transport/gnunet-service-transport_blacklist.c:311 +#: src/transport/gnunet-service-transport_blacklist.c:284 +#: src/transport/gnunet-service-transport_blacklist.c:308 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, giving up!\n" msgstr "配置文件“%s”第 %d 行有语法错误。\n" -#: src/transport/gnunet-service-transport_blacklist.c:298 -#: src/transport/gnunet-service-transport_blacklist.c:336 +#: src/transport/gnunet-service-transport_blacklist.c:295 +#: src/transport/gnunet-service-transport_blacklist.c:331 #, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes.\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:350 +#: src/transport/gnunet-service-transport_blacklist.c:345 #, fuzzy, c-format msgid "Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n" msgstr "配置文件“%s”第 %d 行有语法错误。\n" -#: src/transport/gnunet-service-transport_blacklist.c:364 +#: src/transport/gnunet-service-transport_blacklist.c:359 #, c-format msgid "Found myself `%s' in blacklist (useless, ignored)\n" msgstr "" -#: src/transport/gnunet-service-transport_blacklist.c:523 -#: src/transport/gnunet-service-transport_blacklist.c:764 +#: src/transport/gnunet-service-transport_blacklist.c:514 +#: src/transport/gnunet-service-transport_blacklist.c:747 msgid "# disconnects due to blacklist" msgstr "" -#: src/transport/gnunet-service-transport.c:158 +#: src/transport/gnunet-service-transport.c:163 msgid "# bytes payload discarded due to not connected peer " msgstr "" -#: src/transport/gnunet-service-transport.c:572 +#: src/transport/gnunet-service-transport.c:237 +msgid "# bytes total received" +msgstr "" + +#: src/transport/gnunet-service-transport.c:284 +msgid "# bytes payload received" +msgstr "" + +#: src/transport/gnunet-service-transport.c:582 msgid "Transport service is lacking key configuration settings. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport.c:581 +#: src/transport/gnunet-service-transport.c:591 msgid "Transport service could not access hostkey. Exiting.\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:353 +#: src/transport/gnunet-service-transport_clients.c:352 #, c-format msgid "Dropping message of type %u and size %u, have %u/%u messages pending\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:358 +#: src/transport/gnunet-service-transport_clients.c:357 msgid "# messages dropped due to slow client" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:510 +#: src/transport/gnunet-service-transport_clients.c:503 #, c-format msgid "Rejecting control connection from peer `%s', which is not me!\n" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:628 -msgid "# bytes payload received for other peers" -msgstr "" - -#: src/transport/gnunet-service-transport_clients.c:645 +#: src/transport/gnunet-service-transport_clients.c:631 msgid "# bytes payload dropped (other peer was not connected)" msgstr "" -#: src/transport/gnunet-service-transport_clients.c:696 +#: src/transport/gnunet-service-transport_clients.c:682 msgid "# REQUEST CONNECT messages received" msgstr "" @@ -4144,582 +4448,526 @@ msgstr "" msgid "# refreshed my HELLO" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:482 -msgid "# failed connection attempts due to timeout" +#: src/transport/gnunet-service-transport_neighbours.c:1032 +msgid "# DISCONNECT messages sent" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:883 -msgid "# peers disconnected due to external request" +#: src/transport/gnunet-service-transport_neighbours.c:1148 +#: src/transport/gnunet-service-transport_neighbours.c:1482 +msgid "# bytes in message queue for other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:966 -#, fuzzy -msgid "# fast reconnects failed" +#: src/transport/gnunet-service-transport_neighbours.c:1153 +msgid "# messages transmitted to other peers" msgstr "" -"\n" -"按任意键继续\n" -#: src/transport/gnunet-service-transport_neighbours.c:1022 -msgid "# peers disconnected due to timeout" +#: src/transport/gnunet-service-transport_neighbours.c:1158 +msgid "# transmission failures for messages to other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1047 +#: src/transport/gnunet-service-transport_neighbours.c:1215 +msgid "# messages timed out while in transport queue" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:1254 msgid "# keepalives sent" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1088 -msgid "# peers disconnected due to global disconnect" +#: src/transport/gnunet-service-transport_neighbours.c:1278 +msgid "# KEEPALIVE messages discarded (peer unknown)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1888 -#: src/transport/gnunet-service-transport_neighbours.c:1909 -msgid "# messages not sent (no such peer or not connected)" +#: src/transport/gnunet-service-transport_neighbours.c:1286 +msgid "# KEEPALIVE messages discarded (no session)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1925 -msgid "# bytes in message queue for other peers" +#: src/transport/gnunet-service-transport_neighbours.c:1323 +msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:1977 +#: src/transport/gnunet-service-transport_neighbours.c:1332 +msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:1388 msgid "# messages discarded due to lack of neighbour record" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2013 +#: src/transport/gnunet-service-transport_neighbours.c:1422 msgid "# bandwidth quota violations by other peers" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2031 +#: src/transport/gnunet-service-transport_neighbours.c:1438 msgid "# ms throttling suggested" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2060 -msgid "# KEEPALIVE messages discarded (not connected)" +#: src/transport/gnunet-service-transport_neighbours.c:2544 +msgid "# unexpected CONNECT_ACK messages (no peer)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2113 -msgid "# KEEPALIVE_RESPONSE messages discarded (not connected)" +#: src/transport/gnunet-service-transport_neighbours.c:2559 +#: src/transport/gnunet-service-transport_neighbours.c:2585 +msgid "# unexpected CONNECT_ACK messages (not ready)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2121 -msgid "# KEEPALIVE_RESPONSE messages discarded (not expected)" +#: src/transport/gnunet-service-transport_neighbours.c:2598 +msgid "# unexpected CONNECT_ACK messages (waiting on ATS)" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:2627 +msgid "# unexpected CONNECT_ACK messages (disconnecting)" +msgstr "" + +#: src/transport/gnunet-service-transport_neighbours.c:2807 +msgid "# unexpected SESSION ACK messages" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2187 +#: src/transport/gnunet-service-transport_neighbours.c:2856 msgid "# SET QUOTA messages ignored (no such peer)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2205 +#: src/transport/gnunet-service-transport_neighbours.c:2870 msgid "# disconnects due to quota of 0" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2323 +#: src/transport/gnunet-service-transport_neighbours.c:2901 msgid "# disconnect messages ignored (old format)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2336 +#: src/transport/gnunet-service-transport_neighbours.c:2912 msgid "# disconnect messages ignored (timestamp)" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2411 -msgid "# unexpected CONNECT_ACK messages (no peer)" -msgstr "" - -#: src/transport/gnunet-service-transport_neighbours.c:2453 -msgid "# unexpected CONNECT_ACK messages" +#: src/transport/gnunet-service-transport_neighbours.c:2943 +msgid "# other peer asked to disconnect from us" msgstr "" -#: src/transport/gnunet-service-transport_neighbours.c:2544 -msgid "# unexpected ACK messages" +#: src/transport/gnunet-service-transport_neighbours.c:3020 +msgid "# disconnected from peer upon explicit request" msgstr "" #: src/transport/gnunet-service-transport_plugins.c:111 msgid "Transport service is lacking NEIGHBOUR_LIMIT option.\n" msgstr "" -#: src/transport/gnunet-service-transport_plugins.c:118 -#, c-format -msgid "Starting transport plugins `%s'\n" -msgstr "" - -#: src/transport/gnunet-service-transport_plugins.c:122 -#, c-format -msgid "Loading `%s' transport plugin\n" -msgstr "" - -#: src/transport/gnunet-service-transport_plugins.c:150 -#, fuzzy, c-format -msgid "Failed to load transport plugin for `%s'\n" -msgstr "解析配置文件“%s”失败\n" - -#: src/transport/gnunet-service-transport_validation.c:410 +#: src/transport/gnunet-service-transport_validation.c:414 msgid "# address records discarded" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:459 +#: src/transport/gnunet-service-transport_validation.c:463 #, c-format msgid "" "Not transmitting `%s' with `%s', message too big (%u bytes!). This should " "not happen.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:508 +#: src/transport/gnunet-service-transport_validation.c:512 msgid "# PING without HELLO messages sent" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:566 +#: src/transport/gnunet-service-transport_validation.c:570 msgid "# address revalidations started" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:798 +#: src/transport/gnunet-service-transport_validation.c:805 msgid "# PING message for different peer received" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:833 +#: src/transport/gnunet-service-transport_validation.c:840 #, c-format msgid "" "Not confirming PING with address `%s' since I cannot confirm having this " "address.\n" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:919 +#: src/transport/gnunet-service-transport_validation.c:924 msgid "# PONGs unicast via reliable transport" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:928 +#: src/transport/gnunet-service-transport_validation.c:933 msgid "# PONGs multicast to all available addresses" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1050 +#: src/transport/gnunet-service-transport_validation.c:1055 msgid "# PONGs dropped, no matching pending validation" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1075 +#: src/transport/gnunet-service-transport_validation.c:1080 msgid "# PONGs dropped, signature expired" msgstr "" -#: src/transport/gnunet-service-transport_validation.c:1134 +#: src/transport/gnunet-service-transport_validation.c:1136 #, c-format msgid "Adding `%s' without addresses for peer `%s'\n" msgstr "" -#: src/transport/gnunet-transport.c:256 +#: src/transport/gnunet-transport.c:260 msgid "No transport plugins configured, peer will never communicate\n" msgstr "" -#: src/transport/gnunet-transport.c:269 +#: src/transport/gnunet-transport.c:273 #, c-format msgid "No port configured for plugin `%s', cannot test it\n" msgstr "" -#: src/transport/gnunet-transport.c:319 +#: src/transport/gnunet-transport.c:323 #, c-format msgid "Received %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:326 +#: src/transport/gnunet-transport.c:330 #, c-format msgid "Transmitted %llu bytes/s (%llu bytes in %llu ms)\n" msgstr "" -#: src/transport/gnunet-transport.c:359 +#: src/transport/gnunet-transport.c:363 #, c-format msgid "Transmitting %u bytes to %s\n" msgstr "" -#: src/transport/gnunet-transport.c:379 +#: src/transport/gnunet-transport.c:383 #, fuzzy, c-format msgid "Connected to %s\n" msgstr "“%s”已连接到“%s”。\n" -#: src/transport/gnunet-transport.c:410 +#: src/transport/gnunet-transport.c:414 #, fuzzy, c-format msgid "Disconnected from %s\n" msgstr "“%s”已连接到“%s”。\n" -#: src/transport/gnunet-transport.c:439 +#: src/transport/gnunet-transport.c:443 #, c-format msgid "Received %u bytes from %s\n" msgstr "" -#: src/transport/gnunet-transport.c:453 +#: src/transport/gnunet-transport.c:466 #, fuzzy, c-format msgid "Peer `%s': %s %s\n" msgstr "运行 %s失败:%s %d\n" -#: src/transport/gnunet-transport.c:483 +#: src/transport/gnunet-transport.c:473 +#, c-format +msgid "Peer `%s': %s \n" +msgstr "" + +#: src/transport/gnunet-transport.c:501 #, fuzzy, c-format msgid "Peer `%s' disconnected\n" msgstr "" "\n" "按任意键继续\n" -#: src/transport/gnunet-transport.c:539 +#: src/transport/gnunet-transport.c:569 #, fuzzy, c-format msgid "Failed to parse peer identity `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/transport/gnunet-transport.c:587 +#: src/transport/gnunet-transport.c:618 msgid "measure how fast we are receiving data (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:590 +#: src/transport/gnunet-transport.c:621 #, fuzzy msgid "try to connect to the given peer" msgstr "初始化“%s”服务失败。\n" -#: src/transport/gnunet-transport.c:593 +#: src/transport/gnunet-transport.c:624 msgid "provide information about all current connections (once)" msgstr "" -#: src/transport/gnunet-transport.c:596 +#: src/transport/gnunet-transport.c:627 msgid "provide information about all current connections (continuously)" msgstr "" -#: src/transport/gnunet-transport.c:599 +#: src/transport/gnunet-transport.c:630 msgid "do not resolve hostnames" msgstr "" -#: src/transport/gnunet-transport.c:603 +#: src/transport/gnunet-transport.c:634 msgid "send data for benchmarking to the other peer (until CTRL-C)" msgstr "" -#: src/transport/gnunet-transport.c:606 +#: src/transport/gnunet-transport.c:637 msgid "test transport configuration (involves external server)" msgstr "" -#: src/transport/gnunet-transport.c:614 +#: src/transport/gnunet-transport.c:645 #, fuzzy msgid "Direct access to transport service." msgstr "初始化“%s”服务失败。\n" -#: src/transport/plugin_transport_http.c:981 +#: src/transport/plugin_transport_http.c:1100 msgid "Disabling IPv6 since it is not supported on this system!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1029 +#: src/transport/plugin_transport_http.c:1149 #, fuzzy msgid "Require valid port number for service in configuration!\n" msgstr "保存配置失败。" -#: src/transport/plugin_transport_http.c:1054 src/util/service.c:986 +#: src/transport/plugin_transport_http.c:1174 src/util/service.c:1036 #, fuzzy, c-format msgid "Failed to resolve `%s': %s\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/transport/plugin_transport_http.c:1071 src/util/service.c:1003 +#: src/transport/plugin_transport_http.c:1191 src/util/service.c:1053 #, fuzzy, c-format msgid "Failed to find %saddress for `%s'.\n" msgstr "找不到接口“%s”的一个 IP 地址。\n" -#: src/transport/plugin_transport_http.c:1176 +#: src/transport/plugin_transport_http.c:1296 #, c-format msgid "Found %u addresses to report to NAT service\n" msgstr "" -#: src/transport/plugin_transport_http.c:1189 +#: src/transport/plugin_transport_http.c:1309 #, c-format msgid "FREEING %s\n" msgstr "" -#: src/transport/plugin_transport_http.c:1264 +#: src/transport/plugin_transport_http.c:1386 msgid "Neither IPv4 nor IPv6 are enabled! Fix in configuration\n" msgstr "" -#: src/transport/plugin_transport_http.c:1277 +#: src/transport/plugin_transport_http.c:1399 #, fuzzy msgid "Port is required! Fix in configuration\n" msgstr "" "\n" "结束配置。\n" -#: src/transport/plugin_transport_http.c:1288 +#: src/transport/plugin_transport_http.c:1410 msgid "Port 0, client only mode\n" msgstr "" -#: src/transport/plugin_transport_http.c:1308 +#: src/transport/plugin_transport_http.c:1430 #, c-format msgid "" "Specific IPv4 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http.c:1338 +#: src/transport/plugin_transport_http.c:1460 #, c-format msgid "" "Specific IPv6 address `%s' for plugin %s in configuration file is invalid! " "Binding to all addresses!\n" msgstr "" -#: src/transport/plugin_transport_http_client.c:621 +#: src/transport/plugin_transport_http_client.c:624 #, c-format msgid "Could not initialize curl multi handle, failed to start %s plugin!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:189 +#: src/transport/plugin_transport_http_server.c:178 msgid "" "Could not create a new TLS certificate, program `gnunet-transport-" "certificate-creation' could not be started!\n" msgstr "" -#: src/transport/plugin_transport_http_server.c:213 +#: src/transport/plugin_transport_http_server.c:202 msgid "No usable TLS certificate found and creating one failed!\n" msgstr "" -#: src/transport/plugin_transport_smtp.c:370 -#, c-format -msgid "Received malformed message via %s. Ignored.\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:457 -msgid "SMTP filter string to invalid, lacks ': '\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:466 -#, c-format -msgid "SMTP filter string to long, capped to `%s'\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:561 -#: src/transport/plugin_transport_smtp.c:571 -#: src/transport/plugin_transport_smtp.c:584 -#: src/transport/plugin_transport_smtp.c:603 -#: src/transport/plugin_transport_smtp.c:626 -#: src/transport/plugin_transport_smtp.c:634 -#: src/transport/plugin_transport_smtp.c:647 -#: src/transport/plugin_transport_smtp.c:658 -#, c-format -msgid "SMTP: `%s' failed: %s.\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:801 -msgid "No email-address specified, can not start SMTP transport.\n" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:813 -msgid "# bytes received via SMTP" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:814 -msgid "# bytes sent via SMTP" -msgstr "" - -#: src/transport/plugin_transport_smtp.c:816 -msgid "# bytes dropped by SMTP (outgoing)" -msgstr "" - -#: src/transport/plugin_transport_tcp.c:512 +#: src/transport/plugin_transport_tcp.c:591 #, c-format msgid "Unexpected address length: %u bytes\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:616 -#: src/transport/plugin_transport_tcp.c:705 -#: src/transport/plugin_transport_tcp.c:757 -#: src/transport/plugin_transport_tcp.c:830 -#: src/transport/plugin_transport_tcp.c:909 +#: src/transport/plugin_transport_tcp.c:767 +#: src/transport/plugin_transport_tcp.c:856 +#: src/transport/plugin_transport_tcp.c:906 +#: src/transport/plugin_transport_tcp.c:992 +#: src/transport/plugin_transport_tcp.c:1086 +#: src/transport/plugin_transport_tcp.c:1103 msgid "# bytes currently in TCP buffers" msgstr "" -#: src/transport/plugin_transport_tcp.c:622 -#: src/transport/plugin_transport_tcp.c:856 -#: src/transport/plugin_transport_tcp.c:1561 +#: src/transport/plugin_transport_tcp.c:774 +#: src/transport/plugin_transport_tcp.c:963 +#: src/transport/plugin_transport_tcp.c:1761 +#: src/transport/plugin_transport_tcp.c:2390 msgid "# TCP sessions active" msgstr "" -#: src/transport/plugin_transport_tcp.c:709 +#: src/transport/plugin_transport_tcp.c:860 msgid "# bytes discarded by TCP (timeout)" msgstr "" -#: src/transport/plugin_transport_tcp.c:760 +#: src/transport/plugin_transport_tcp.c:909 msgid "# bytes transmitted via TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:834 +#: src/transport/plugin_transport_tcp.c:996 msgid "# bytes discarded by TCP (disconnect)" msgstr "" -#: src/transport/plugin_transport_tcp.c:1081 +#: src/transport/plugin_transport_tcp.c:1290 #, c-format msgid "Address of unexpected length: %u\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1116 -msgid "Found valid IPv4 NAT address (creating session)!\n" -msgstr "" - -#: src/transport/plugin_transport_tcp.c:1186 +#: src/transport/plugin_transport_tcp.c:1401 msgid "# transport-service disconnect requests for TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:1603 +#: src/transport/plugin_transport_tcp.c:1802 msgid "# TCP WELCOME messages received" msgstr "" -#: src/transport/plugin_transport_tcp.c:1756 +#: src/transport/plugin_transport_tcp.c:1973 msgid "# bytes received via TCP" msgstr "" -#: src/transport/plugin_transport_tcp.c:1823 +#: src/transport/plugin_transport_tcp.c:2043 msgid "# network-level TCP disconnect events" msgstr "" -#: src/transport/plugin_transport_tcp.c:1962 src/util/service.c:889 +#: src/transport/plugin_transport_tcp.c:2279 src/util/service.c:940 #, c-format msgid "Require valid port number for service `%s' in configuration!\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:1976 +#: src/transport/plugin_transport_tcp.c:2293 #, fuzzy msgid "Failed to start service.\n" msgstr "初始化“%s”服务失败。\n" -#: src/transport/plugin_transport_tcp.c:2039 +#: src/transport/plugin_transport_tcp.c:2355 #, c-format msgid "Failed to find option %s in section %s!\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2062 +#: src/transport/plugin_transport_tcp.c:2378 #, c-format msgid "TCP transport listening on port %llu\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2066 +#: src/transport/plugin_transport_tcp.c:2382 msgid "TCP transport not listening on any port (client only)\n" msgstr "" -#: src/transport/plugin_transport_tcp.c:2070 +#: src/transport/plugin_transport_tcp.c:2386 #, c-format msgid "TCP transport advertises itself as being on port %llu\n" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:130 +#: src/transport/plugin_transport_udp_broadcasting.c:128 msgid "# IPv6 multicast HELLO beacons received via udp" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:172 +#: src/transport/plugin_transport_udp_broadcasting.c:169 msgid "# IPv4 broadcast HELLO beacons received via udp" msgstr "" -#: src/transport/plugin_transport_udp_broadcasting.c:393 +#: src/transport/plugin_transport_udp_broadcasting.c:367 #, c-format msgid "Failed to set IPv4 broadcast option for broadcast socket on port %d\n" msgstr "" -#: src/transport/plugin_transport_udp.c:1985 +#: src/transport/plugin_transport_udp.c:1894 +#, c-format +msgid "" +"UDP could not message to `%s': `%s'. Please check your network configuration " +"and disable IPv6 if your connection does not have a global IPv6 address\n" +msgstr "" + +#: src/transport/plugin_transport_udp.c:2138 #, fuzzy msgid "Failed to open UDP sockets\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/transport/plugin_transport_udp.c:2068 +#: src/transport/plugin_transport_udp.c:2306 #, c-format msgid "Given `%s' option is out of range: %llu > %u\n" msgstr "" -#: src/transport/plugin_transport_udp.c:2112 +#: src/transport/plugin_transport_udp.c:2349 #, fuzzy, c-format msgid "Invalid IPv6 address: `%s'\n" msgstr "无效的进程优先级“%s”\n" -#: src/transport/plugin_transport_unix.c:1051 +#: src/transport/plugin_transport_unix.c:1356 #, fuzzy msgid "Failed to open UNIX sockets\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/transport/plugin_transport_wlan.c:875 -msgid "# wlan session timeouts" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:899 -msgid "# wlan session created" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:980 -#: src/transport/plugin_transport_wlan.c:1138 -#: src/transport/plugin_transport_wlan.c:1159 -#: src/transport/plugin_transport_wlan.c:1190 -#: src/transport/plugin_transport_wlan.c:2334 -#: src/transport/plugin_transport_wlan.c:3142 -msgid "# wlan pending sessions" -msgstr "" - -#: src/transport/plugin_transport_wlan.c:1233 -#: src/transport/plugin_transport_wlan.c:1888 -msgid "# wlan pending fragments" +#: src/transport/plugin_transport_wlan.c:561 +msgid "# WLAN ACKs sent" msgstr "" -#: src/transport/plugin_transport_wlan.c:1388 -#, c-format -msgid "" -"Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n" +#: src/transport/plugin_transport_wlan.c:580 +msgid "# WLAN messages defragmented" msgstr "" -#: src/transport/plugin_transport_wlan.c:1732 -msgid "# wlan hello beacons send" +#: src/transport/plugin_transport_wlan.c:626 +#: src/transport/plugin_transport_wlan.c:676 +#: src/transport/plugin_transport_wlan.c:1696 +msgid "# WLAN sessions allocated" msgstr "" -#: src/transport/plugin_transport_wlan.c:1765 -#: src/transport/plugin_transport_wlan.c:1968 -#: src/transport/plugin_transport_wlan.c:2059 -#, c-format -msgid "Error writing to wlan helper. errno == %d, ERROR: %s\n" +#: src/transport/plugin_transport_wlan.c:749 +msgid "# WLAN message fragments sent" msgstr "" -#: src/transport/plugin_transport_wlan.c:1954 -msgid "# wlan acks send" +#: src/transport/plugin_transport_wlan.c:767 +msgid "# WLAN messages pending (with fragmentation)" msgstr "" -#: src/transport/plugin_transport_wlan.c:2025 -msgid "# wlan fragments send" +#: src/transport/plugin_transport_wlan.c:867 +#: src/transport/plugin_transport_wlan.c:948 +#: src/transport/plugin_transport_wlan.c:1698 +msgid "# WLAN MAC endpoints allocated" msgstr "" -#: src/transport/plugin_transport_wlan.c:2161 -#, c-format -msgid "Wlan Address len %d is wrong\n" +#: src/transport/plugin_transport_wlan.c:1119 +msgid "# HELLO messages received via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2295 -#: src/transport/plugin_transport_wlan.c:2919 -#: src/transport/plugin_transport_wlan.c:3145 -msgid "# wlan mac endpoints" +#: src/transport/plugin_transport_wlan.c:1140 +msgid "# fragments received via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2517 -msgid "# wlan whole messages received" +#: src/transport/plugin_transport_wlan.c:1150 +msgid "# ACKs received via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2708 -msgid "# wlan hello messages received" +#: src/transport/plugin_transport_wlan.c:1207 +msgid "# WLAN DATA messages discarded due to CRC32 error" msgstr "" -#: src/transport/plugin_transport_wlan.c:2742 -msgid "# wlan fragments received" +#: src/transport/plugin_transport_wlan.c:1306 +msgid "# DATA messages received via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2790 -msgid "# wlan acks received" +#: src/transport/plugin_transport_wlan.c:1341 +msgid "# WLAN DATA messages processed" msgstr "" -#: src/transport/plugin_transport_wlan.c:2879 -msgid "# wlan mac endpoints timeouts" +#: src/transport/plugin_transport_wlan.c:1402 +msgid "# HELLO beacons sent via WLAN" msgstr "" -#: src/transport/plugin_transport_wlan.c:2903 -msgid "# wlan mac endpoints created" +#: src/transport/plugin_transport_wlan.c:1511 +msgid "WLAN address with invalid size encountered\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:2956 -msgid "# wlan WLAN_HELPER_DATA received" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1668 +#, fuzzy, c-format +msgid "Invalid configuration option `%s' in section `%s'\n" +msgstr "配置文件“%s”已写入。\n" -#: src/transport/plugin_transport_wlan.c:3010 -msgid "# wlan messages for this client received" +#: src/transport/plugin_transport_wlan.c:1677 +#, c-format +msgid "Helper binary `%s' not SUID, cannot run WLAN transport\n" msgstr "" -#: src/transport/plugin_transport_wlan.c:3021 -msgid "# wlan messages inside WLAN_HELPER_DATA received" -msgstr "" +#: src/transport/plugin_transport_wlan.c:1687 +#, fuzzy, c-format +msgid "Missing configuration option `%s' in section `%s'\n" +msgstr "配置文件“%s”已写入。\n" -#: src/transport/transport_api.c:588 +#: src/transport/transport_api.c:570 #, c-format msgid "Received unexpected message of type %u in %s:%u\n" msgstr "" @@ -4753,134 +5001,127 @@ msgstr "" msgid "Metadata `%s' failed to deserialize" msgstr "" -#: src/util/client.c:304 +#: src/util/client.c:359 #, c-format msgid "" "Could not determine valid hostname and port for service `%s' from " "configuration.\n" msgstr "" -#: src/util/client.c:312 +#: src/util/client.c:367 #, c-format msgid "Need a non-empty hostname for service `%s'.\n" msgstr "" -#: src/util/client.c:657 +#: src/util/client.c:685 msgid "Failure to transmit TEST request.\n" msgstr "" -#: src/util/client.c:717 src/util/service.c:919 +#: src/util/client.c:740 src/util/service.c:970 #, c-format msgid "UNIXPATH `%s' too long, maximum length is %llu\n" msgstr "" -#: src/util/client.c:859 +#: src/util/client.c:882 #, c-format msgid "Could not connect to service `%s', must not be running.\n" msgstr "" -#: src/util/client.c:875 +#: src/util/client.c:896 #, c-format msgid "Failure to transmit request to service `%s'\n" msgstr "" -#: src/util/client.c:1143 +#: src/util/client.c:1149 msgid "Could not submit request, not expecting to receive a response.\n" msgstr "" -#: src/util/common_logging.c:239 src/util/common_logging.c:889 +#: src/util/common_logging.c:239 src/util/common_logging.c:890 msgid "DEBUG" msgstr "调试" -#: src/util/common_logging.c:241 src/util/common_logging.c:887 +#: src/util/common_logging.c:241 src/util/common_logging.c:888 msgid "INFO" msgstr "俥息" -#: src/util/common_logging.c:243 src/util/common_logging.c:885 +#: src/util/common_logging.c:243 src/util/common_logging.c:886 msgid "WARNING" msgstr "警告" -#: src/util/common_logging.c:245 src/util/common_logging.c:883 +#: src/util/common_logging.c:245 src/util/common_logging.c:884 msgid "ERROR" msgstr "错误" -#: src/util/common_logging.c:247 src/util/common_logging.c:891 +#: src/util/common_logging.c:247 src/util/common_logging.c:892 msgid "NONE" msgstr "" -#: src/util/common_logging.c:609 +#: src/util/common_logging.c:610 #, fuzzy, c-format msgid "Failed to create or access directory for log file `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/util/common_logging.c:724 +#: src/util/common_logging.c:725 #, fuzzy, c-format msgid "Message `%.*s' repeated %u times in the last %s\n" msgstr "消息“%.*s”重复了 %u 次,在最近 %llu 秒内\n" -#: src/util/common_logging.c:892 +#: src/util/common_logging.c:893 msgid "INVALID" msgstr "" -#: src/util/common_logging.c:991 +#: src/util/common_logging.c:992 msgid "unknown address" msgstr "" -#: src/util/common_logging.c:1029 +#: src/util/common_logging.c:1030 msgid "invalid address" msgstr "" -#: src/util/configuration.c:245 +#: src/util/configuration.c:244 #, fuzzy, c-format msgid "Syntax error in configuration file `%s' at line %u.\n" msgstr "配置文件“%s”第 %d 行有语法错误。\n" -#: src/util/configuration.c:817 +#: src/util/configuration.c:816 #, c-format msgid "" "Configuration value '%s' for '%s' in section '%s' is not in set of legal " "choices\n" msgstr "" -#: src/util/connection.c:460 +#: src/util/connection.c:420 #, fuzzy, c-format msgid "Access denied to `%s'\n" msgstr "“%s”已连接到“%s”。\n" -#: src/util/connection.c:475 +#: src/util/connection.c:435 #, c-format msgid "Accepting connection from `%s': %p\n" msgstr "" -#: src/util/connection.c:629 +#: src/util/connection.c:550 #, c-format msgid "" "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n" msgstr "" -#: src/util/connection.c:821 src/util/connection.c:992 +#: src/util/connection.c:739 src/util/connection.c:909 #, fuzzy, c-format msgid "Trying to connect to `%s' (%p)\n" msgstr "无法连接到 %s:%u:%s\n" -#: src/util/connection.c:830 +#: src/util/connection.c:748 #, fuzzy, c-format msgid "Failed to connect to `%s' (%p)\n" msgstr "无法连接到 %s:%u:%s\n" -#: src/util/connection.c:983 +#: src/util/connection.c:900 #, c-format msgid "Attempt to connect to `%s' failed\n" msgstr "" -#: src/util/connection.c:1465 -#, c-format -msgid "" -"Could not satisfy pending transmission request, socket closed or connect " -"failed (%p).\n" -msgstr "" - -#: src/util/container_bloomfilter.c:507 +#: src/util/container_bloomfilter.c:510 #, c-format msgid "" "Size of file on disk is incorrect for this Bloom filter (want %llu, have " @@ -4897,134 +5138,134 @@ msgstr "" msgid "libgcrypt has not the expected version (version %s is required).\n" msgstr "libgcrypt 的版本不符合预期(要求版本 %s)。\n" -#: src/util/crypto_rsa.c:618 src/util/crypto_rsa.c:665 +#: src/util/crypto_rsa.c:661 src/util/crypto_rsa.c:708 #, fuzzy, c-format msgid "Could not aquire lock on file `%s': %s...\n" msgstr "无法解析“%s”(%s):%s\n" -#: src/util/crypto_rsa.c:623 +#: src/util/crypto_rsa.c:666 #, fuzzy msgid "Creating a new private key. This may take a while.\n" msgstr "正在启动数据仓库转换(可能需要一段时间)。\n" -#: src/util/crypto_rsa.c:641 +#: src/util/crypto_rsa.c:684 #, c-format msgid "I am host `%s'. Stored new private key in `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:669 src/util/crypto_rsa.c:705 +#: src/util/crypto_rsa.c:712 src/util/crypto_rsa.c:748 msgid "This may be ok if someone is currently generating a hostkey.\n" msgstr "" -#: src/util/crypto_rsa.c:700 +#: src/util/crypto_rsa.c:743 #, c-format msgid "" "When trying to read hostkey file `%s' I found %u bytes but I need at least " "%u.\n" msgstr "" -#: src/util/crypto_rsa.c:720 +#: src/util/crypto_rsa.c:763 #, c-format msgid "File `%s' does not contain a valid private key. Deleting it.\n" msgstr "" -#: src/util/crypto_rsa.c:738 +#: src/util/crypto_rsa.c:781 #, c-format msgid "I am host `%s'. Read private key from `%s'.\n" msgstr "" -#: src/util/crypto_rsa.c:959 +#: src/util/crypto_rsa.c:1032 #, c-format msgid "RSA signature verification failed at %s:%d: %s\n" msgstr "" -#: src/util/disk.c:479 +#: src/util/disk.c:498 #, fuzzy, c-format msgid "`%s' failed for drive `%S': %u\n" msgstr "对驱动器“%2$s”的“%1$s”操作失败:%3$u\n" -#: src/util/disk.c:1087 +#: src/util/disk.c:1062 #, c-format msgid "Expected `%s' to be a directory!\n" msgstr "“%s”应为目录!\n" -#: src/util/disk.c:1441 src/util/service.c:1580 +#: src/util/disk.c:1416 src/util/service.c:1650 #, c-format msgid "Cannot obtain information about user `%s': %s\n" msgstr "无法获取有关用户“%s”的信息:%s\n" -#: src/util/disk.c:1759 +#: src/util/disk.c:1734 #, c-format msgid "No `%s' specified for service `%s' in configuration.\n" msgstr "" -#: src/util/getopt.c:672 +#: src/util/getopt.c:669 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "%s:选项“%s”有歧义\n" -#: src/util/getopt.c:696 +#: src/util/getopt.c:693 #, c-format msgid "%s: option `--%s' does not allow an argument\n" msgstr "%s:选项“--%s”不允许有参数\n" -#: src/util/getopt.c:701 +#: src/util/getopt.c:698 #, c-format msgid "%s: option `%c%s' does not allow an argument\n" msgstr "%s:选项“%c%s”不允许有参数\n" -#: src/util/getopt.c:718 src/util/getopt.c:886 +#: src/util/getopt.c:715 src/util/getopt.c:883 #, c-format msgid "%s: option `%s' requires an argument\n" msgstr "%s:选项“%s”要求有一个参数\n" -#: src/util/getopt.c:747 +#: src/util/getopt.c:744 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "%s:无法识别的选项“--%s”\n" -#: src/util/getopt.c:751 +#: src/util/getopt.c:748 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "%s:无法识别的选项“%c%s”\n" -#: src/util/getopt.c:776 +#: src/util/getopt.c:773 #, c-format msgid "%s: illegal option -- %c\n" msgstr "%s:非法选项 -- %c\n" -#: src/util/getopt.c:778 +#: src/util/getopt.c:775 #, c-format msgid "%s: invalid option -- %c\n" msgstr "%s:无效选项 -- %c\n" -#: src/util/getopt.c:806 src/util/getopt.c:934 +#: src/util/getopt.c:803 src/util/getopt.c:931 #, c-format msgid "%s: option requires an argument -- %c\n" msgstr "%s:选项要求有一个参数 -- %c\n" -#: src/util/getopt.c:854 +#: src/util/getopt.c:851 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "%s:选项“-W %s”有歧义\n" -#: src/util/getopt.c:872 +#: src/util/getopt.c:869 #, c-format msgid "%s: option `-W %s' does not allow an argument\n" msgstr "%s:选项“-W %s” 不允许有参数\n" -#: src/util/getopt.c:1038 +#: src/util/getopt.c:1035 #, fuzzy, c-format msgid "Use %s to get a list of options.\n" msgstr "请使用 --help 获取选项列表。\n" -#: src/util/getopt_helpers.c:84 +#: src/util/getopt_helpers.c:86 #, c-format msgid "" "Arguments mandatory for long options are also mandatory for short options.\n" msgstr "长选项的必选参数对短选项也是必选的。\n" -#: src/util/getopt_helpers.c:255 src/util/getopt_helpers.c:283 +#: src/util/getopt_helpers.c:258 src/util/getopt_helpers.c:286 #, c-format msgid "You must pass a number to the `%s' option.\n" msgstr "您必须向“%s”选项传递一个数字。\n" @@ -5037,6 +5278,27 @@ msgstr "" msgid "Use build-in GNUnet stub resolver" msgstr "" +#: src/util/gnunet-rsa.c:64 +#, c-format +msgid "No hostkey file specified on command line\n" +msgstr "" + +#: src/util/gnunet-rsa.c:112 +msgid "print the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:115 +msgid "print the hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:118 +msgid "print the short hash of the public key in ASCII format" +msgstr "" + +#: src/util/gnunet-rsa.c:124 +msgid "Manipulate GNUnet private RSA key files" +msgstr "" + #: src/util/gnunet-service-resolver.c:288 #, c-format msgid "Could not resolve `%s' (%s): %s\n" @@ -5048,42 +5310,37 @@ msgstr "无法解析“%s”(%s):%s\n" msgid "Could not find IP of host `%s': %s\n" msgstr "找不到主机“%s”的 IP:%s\n" -#: src/util/gnunet-service-resolver.c:494 -#, c-format -msgid "Resolver asked to look up `%s'.\n" -msgstr "" - -#: src/util/gnunet-service-resolver.c:529 -#, c-format -msgid "Resolver asked to look up IP address `%s'.\n" -msgstr "" - -#: src/util/helper.c:239 +#: src/util/helper.c:244 #, fuzzy, c-format msgid "Error reading from `%s': %s\n" msgstr "创建用户出错" -#: src/util/helper.c:254 +#: src/util/helper.c:259 #, c-format msgid "Got 0 bytes from helper `%s' (EOF)\n" msgstr "" -#: src/util/helper.c:264 +#: src/util/helper.c:269 #, c-format msgid "Got %u bytes from helper `%s'\n" msgstr "" -#: src/util/helper.c:273 +#: src/util/helper.c:278 #, fuzzy, c-format msgid "Failed to parse inbound message from helper `%s'\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/util/helper.c:432 +#: src/util/helper.c:310 +#, fuzzy, c-format +msgid "Starting HELPER process `%s'\n" +msgstr "卸载 GNUnet 服务" + +#: src/util/helper.c:440 #, fuzzy, c-format msgid "Error writing to `%s': %s\n" msgstr "创建用户出错" -#: src/util/network.c:1196 +#: src/util/network.c:1200 #, c-format msgid "" "Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n" @@ -5111,12 +5368,12 @@ msgstr "“%s”说:%s\n" msgid "stat (%s) failed: %s\n" msgstr "“%s”说:%s\n" -#: src/util/os_priority.c:304 +#: src/util/os_priority.c:305 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for reading: %s\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/util/os_priority.c:305 +#: src/util/os_priority.c:306 #, fuzzy, c-format msgid "Failed to open named pipe `%s' for writing: %s\n" msgstr "打开日志文件“%s”失败:%s\n" @@ -5141,12 +5398,12 @@ msgstr "" msgid "Could not determine plugin installation path.\n" msgstr "无法确定用户界面定义文件。" -#: src/util/pseudonym.c:273 +#: src/util/pseudonym.c:276 #, fuzzy, c-format msgid "Failed to parse metadata about pseudonym from file `%s': %s\n" msgstr "打开日志文件“%s”失败:%s\n" -#: src/util/pseudonym.c:338 +#: src/util/pseudonym.c:407 src/util/pseudonym.c:433 msgid "no-name" msgstr "无名称" @@ -5161,187 +5418,167 @@ msgid "" "Must specify `%s' or numeric IP address for `%s' of `%s' in configuration!\n" msgstr "" -#: src/util/resolver_api.c:351 +#: src/util/resolver_api.c:347 #, fuzzy, c-format msgid "Timeout trying to resolve IP address `%s'.\n" msgstr "GNUnet 现在使用 IP 地址 %s。\n" -#: src/util/resolver_api.c:355 +#: src/util/resolver_api.c:351 #, c-format msgid "Timeout trying to resolve hostname `%s'.\n" msgstr "" -#: src/util/resolver_api.c:426 -#, c-format -msgid "Resolver returns `%s' for IP `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:807 -#, c-format -msgid "Resolver returns `%s'.\n" -msgstr "" - -#: src/util/resolver_api.c:901 -#, c-format -msgid "Resolving our FQDN `%s'\n" -msgstr "" - -#: src/util/resolver_api.c:906 +#: src/util/resolver_api.c:890 #, fuzzy, c-format msgid "Could not resolve our FQDN : %s\n" msgstr "无法解析“%s”(%s):%s\n" -#: src/util/resolver_api.c:938 -#, c-format -msgid "Resolving our hostname `%s'\n" -msgstr "" - -#: src/util/scheduler.c:866 +#: src/util/scheduler.c:786 msgid "Looks like we're busy waiting...\n" msgstr "" -#: src/util/scheduler.c:996 +#: src/util/scheduler.c:916 #, c-format msgid "Attempt to cancel dead task %llu!\n" msgstr "" -#: src/util/server.c:397 +#: src/util/server.c:483 #, fuzzy, c-format msgid "`%s' failed for port %d (%s).\n" msgstr "对驱动器“%2$s”的“%1$s”操作失败:%3$u\n" -#: src/util/server.c:406 +#: src/util/server.c:492 #, c-format msgid "`%s' failed for port %d (%s): address already in use\n" msgstr "" -#: src/util/server.c:411 +#: src/util/server.c:497 #, fuzzy, c-format msgid "`%s' failed for `%s': address already in use\n" msgstr "对驱动器“%2$s”的“%1$s”操作失败:%3$u\n" -#: src/util/server.c:640 +#: src/util/server.c:827 #, c-format msgid "" "Processing code for message of type %u did not call " "GNUNET_SERVER_receive_done after %llums\n" msgstr "" -#: src/util/service.c:117 src/util/service.c:143 src/util/service.c:186 -#: src/util/service.c:207 src/util/service.c:214 +#: src/util/service.c:135 src/util/service.c:161 src/util/service.c:204 +#: src/util/service.c:225 src/util/service.c:232 #, c-format msgid "Invalid format for IP: `%s'\n" msgstr "IP 格式无效:“%s”\n" -#: src/util/service.c:170 +#: src/util/service.c:188 #, c-format msgid "Invalid network notation ('/%d' is not legal in IPv4 CIDR)." msgstr "网络表示法无效(“/%d” 在 IPv4 CIDR 中是非法的)。" -#: src/util/service.c:263 +#: src/util/service.c:281 #, c-format msgid "Invalid network notation (does not end with ';': `%s')\n" msgstr "无效的网络表示法(没有以“;”结尾:“%s”)\n" -#: src/util/service.c:296 +#: src/util/service.c:313 #, c-format msgid "Wrong format `%s' for netmask\n" msgstr "网络掩码的格式“%s”错误\n" -#: src/util/service.c:326 +#: src/util/service.c:343 #, c-format msgid "Wrong format `%s' for network\n" msgstr "网络的格式“%s”错误\n" -#: src/util/service.c:668 +#: src/util/service.c:698 #, c-format msgid "Access denied to UID %d / GID %d\n" msgstr "" -#: src/util/service.c:673 +#: src/util/service.c:703 #, c-format msgid "Unknown address family %d\n" msgstr "" -#: src/util/service.c:680 +#: src/util/service.c:710 #, c-format msgid "Access from `%s' denied to service `%s'\n" msgstr "" -#: src/util/service.c:724 +#: src/util/service.c:765 #, c-format msgid "Could not parse IPv4 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:752 +#: src/util/service.c:802 #, c-format msgid "Could not parse IPv6 network specification `%s' for `%s:%s'\n" msgstr "" -#: src/util/service.c:869 +#: src/util/service.c:920 #, c-format msgid "" "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n" msgstr "" -#: src/util/service.c:939 +#: src/util/service.c:990 #, c-format msgid "" "Disabling UNIX domain socket support for service `%s', failed to create UNIX " "domain socket: %s\n" msgstr "" -#: src/util/service.c:956 +#: src/util/service.c:1007 #, c-format msgid "Have neither PORT nor UNIXPATH for service `%s', but one is required\n" msgstr "" -#: src/util/service.c:1191 +#: src/util/service.c:1241 msgid "Could not access a pre-bound socket, will try to bind myself\n" msgstr "" -#: src/util/service.c:1242 src/util/service.c:1260 +#: src/util/service.c:1292 src/util/service.c:1310 #, c-format msgid "Specified value for `%s' of service `%s' is invalid\n" msgstr "" -#: src/util/service.c:1287 +#: src/util/service.c:1337 #, c-format msgid "Could not access pre-bound socket %u, will try to bind myself\n" msgstr "" -#: src/util/service.c:1442 +#: src/util/service.c:1506 #, fuzzy, c-format msgid "Failed to start `%s' at `%s'\n" msgstr "运行 %s失败:%s %d\n" -#: src/util/service.c:1475 +#: src/util/service.c:1539 #, c-format msgid "Service `%s' runs at %s\n" msgstr "" -#: src/util/service.c:1521 +#: src/util/service.c:1588 msgid "Service process failed to initialize\n" msgstr "" -#: src/util/service.c:1525 +#: src/util/service.c:1592 msgid "Service process could not initialize server function\n" msgstr "" -#: src/util/service.c:1529 +#: src/util/service.c:1596 msgid "Service process failed to report status\n" msgstr "" -#: src/util/service.c:1581 +#: src/util/service.c:1651 msgid "No such user" msgstr "无此用户" -#: src/util/service.c:1594 +#: src/util/service.c:1664 #, c-format msgid "Cannot change user/group to `%s': %s\n" msgstr "无法更改用户/组为“%s”:%s\n" -#: src/util/service.c:1657 +#: src/util/service.c:1729 msgid "do daemonize (detach from terminal)" msgstr "" @@ -5350,54 +5587,75 @@ msgstr "" msgid "signal (%d, %p) returned %d.\n" msgstr "" -#: src/util/strings.c:143 +#: src/util/strings.c:144 msgid "b" msgstr "b" -#: src/util/strings.c:354 +#: src/util/strings.c:334 #, c-format msgid "Character sets requested were `%s'->`%s'\n" msgstr "" -#: src/util/strings.c:462 +#: src/util/strings.c:481 msgid "Failed to expand `$HOME': environment variable `HOME' not set" msgstr "扩展“$HOME”失败:没有设置环境变量“HOME”" -#: src/util/strings.c:554 +#: src/util/strings.c:573 msgid "ms" msgstr "毫秒" -#: src/util/strings.c:559 +#: src/util/strings.c:578 msgid "eternity" msgstr "" -#: src/util/strings.c:563 +#: src/util/strings.c:582 msgid "s" msgstr "秒" -#: src/util/strings.c:567 +#: src/util/strings.c:586 msgid "m" msgstr "分" -#: src/util/strings.c:571 +#: src/util/strings.c:590 msgid "h" msgstr "时" -#: src/util/strings.c:575 +#: src/util/strings.c:594 msgid " days" msgstr " 夊" -#: src/util/strings.c:599 +#: src/util/strings.c:618 msgid "end of time" msgstr "" -#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1065 +#: src/util/strings.c:1012 +msgid "IPv6 address did not start with `['\n" +msgstr "" + +#: src/util/strings.c:1020 +msgid "IPv6 address did contain ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1026 +msgid "IPv6 address did contain ']' before ':' to separate port number\n" +msgstr "" + +#: src/util/strings.c:1033 +msgid "IPv6 address did contain a valid port number after the last ':'\n" +msgstr "" + +#: src/util/strings.c:1042 +#, fuzzy, c-format +msgid "Invalid IPv6 address `%s': %s\n" +msgstr "无效的进程优先级“%s”\n" + +#: src/vpn/gnunet-service-vpn.c:511 src/vpn/gnunet-service-vpn.c:1071 msgid "# Active tunnels" msgstr "" #: src/vpn/gnunet-service-vpn.c:608 src/vpn/gnunet-service-vpn.c:645 #, fuzzy -msgid "# Peers connected to mesh tunnels" +msgid "# peers connected to mesh tunnels" msgstr "" "\n" "按任意键继续\n" @@ -5419,70 +5677,70 @@ msgstr "" msgid "Failed to setup mesh tunnel!\n" msgstr "发送消息失败。\n" -#: src/vpn/gnunet-service-vpn.c:967 +#: src/vpn/gnunet-service-vpn.c:973 #, c-format msgid "Protocol %u not supported, dropping\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1285 +#: src/vpn/gnunet-service-vpn.c:1291 msgid "# ICMPv4 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1306 +#: src/vpn/gnunet-service-vpn.c:1312 msgid "# ICMPv6 packets dropped (not allowed)" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1511 +#: src/vpn/gnunet-service-vpn.c:1517 msgid "# Packets received from TUN interface" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1549 src/vpn/gnunet-service-vpn.c:1590 +#: src/vpn/gnunet-service-vpn.c:1555 src/vpn/gnunet-service-vpn.c:1596 #, c-format msgid "Packet received for unmapped destination `%s' (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1600 +#: src/vpn/gnunet-service-vpn.c:1606 msgid "Received IPv4 packet with options (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1614 +#: src/vpn/gnunet-service-vpn.c:1620 #, c-format msgid "Received packet of unknown protocol %d from TUN (dropping it)\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:1697 +#: src/vpn/gnunet-service-vpn.c:1704 msgid "# ICMP packets received from mesh" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2038 +#: src/vpn/gnunet-service-vpn.c:2045 msgid "# UDP packets received from mesh" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2196 +#: src/vpn/gnunet-service-vpn.c:2203 msgid "# TCP packets received from mesh" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2347 +#: src/vpn/gnunet-service-vpn.c:2354 msgid "Failed to find unallocated IPv4 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2402 +#: src/vpn/gnunet-service-vpn.c:2409 msgid "Failed to find unallocated IPv6 address in VPN's range\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2441 src/vpn/gnunet-service-vpn.c:2624 +#: src/vpn/gnunet-service-vpn.c:2448 src/vpn/gnunet-service-vpn.c:2661 msgid "# Active destinations" msgstr "" -#: src/vpn/gnunet-service-vpn.c:2726 +#: src/vpn/gnunet-service-vpn.c:2734 msgid "Failed to allocate IP address for new destination\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3133 +#: src/vpn/gnunet-service-vpn.c:3141 msgid "IPv6 support disabled as this system does not support IPv6\n" msgstr "" -#: src/vpn/gnunet-service-vpn.c:3165 +#: src/vpn/gnunet-service-vpn.c:3173 msgid "IPv4 support disabled as this system does not support IPv4\n" msgstr "" @@ -5556,22 +5814,65 @@ msgstr "" msgid "Setup tunnels via VPN." msgstr "" -#: src/include/gnunet_common.h:479 src/include/gnunet_common.h:484 -#: src/include/gnunet_common.h:490 +#: src/include/gnunet_common.h:497 src/include/gnunet_common.h:502 +#: src/include/gnunet_common.h:508 #, c-format msgid "Assertion failed at %s:%d.\n" msgstr "" -#: src/include/gnunet_common.h:500 +#: src/include/gnunet_common.h:518 #, c-format msgid "External protocol violation detected at %s:%d.\n" msgstr "" -#: src/include/gnunet_common.h:521 src/include/gnunet_common.h:528 +#: src/include/gnunet_common.h:539 src/include/gnunet_common.h:546 #, c-format msgid "`%s' failed on file `%s' at %s:%d with error: %s\n" msgstr "" +#, fuzzy +#~ msgid "# Peers connected" +#~ msgstr "" +#~ "\n" +#~ "按任意键继续\n" + +#, fuzzy +#~ msgid "%s failed for `%s' at %s:%d: `%s'\n" +#~ msgstr "对驱动器“%2$s”的“%1$s”操作失败:%3$u\n" + +#, fuzzy +#~ msgid "Unable to initialize Postgres with configuration `%s': %s" +#~ msgstr "无法保存配置文件“%s”:" + +#, fuzzy +#~ msgid "Copying file with RENAME (%s,%s)\n" +#~ msgstr "“%s”以错误码 %s 失败:%s\n" + +#, fuzzy +#~ msgid "Copying file with command scp %s %s\n" +#~ msgstr "“%s”以错误码 %s 失败:%s\n" + +#, fuzzy +#~ msgid "Finished copying all blacklist files!\n" +#~ msgstr "无法解析“%s”(%s):%s\n" + +#, fuzzy +#~ msgid "Failed during blacklist file copying!\n" +#~ msgstr "解析配置文件“%s”失败\n" + +#, fuzzy +#~ msgid "# fast reconnects failed" +#~ msgstr "" +#~ "\n" +#~ "按任意键继续\n" + +#~ msgid "Unknown user `%s'\n" +#~ msgstr "未知的用户“%s”\n" + +#, fuzzy +#~ msgid "Failed to connect to statistics service!\n" +#~ msgstr "初始化“%s”服务失败。\n" + #, fuzzy #~ msgid "Failed to send to `%s': %s\n" #~ msgstr "打开日志文件“%s”失败:%s\n" @@ -5624,14 +5925,6 @@ msgstr "" #~ msgid "Failed to load dhtlog plugin for `%s'\n" #~ msgstr "解析配置文件“%s”失败\n" -#, fuzzy -#~ msgid "Failed to get full path for `%s'\n" -#~ msgstr "解析配置文件“%s”失败\n" - -#, fuzzy -#~ msgid "Failed to create file for dhtlog.\n" -#~ msgstr "无法为守护程序创建用户账户。" - #, fuzzy #~ msgid "Phase 3: sending messages\n" #~ msgstr "发送消息失败。\n" @@ -5640,10 +5933,6 @@ msgstr "" #~ msgid "Fail! Could not connect peers\n" #~ msgstr "无法连接到 %s:%u:%s\n" -#, fuzzy -#~ msgid "Failed to connect to core service\n" -#~ msgstr "初始化“%s”服务失败。\n" - #~ msgid "Error" #~ msgstr "错误" @@ -5668,9 +5957,6 @@ msgstr "" #~ msgid "Ok" #~ msgstr "确定" -#~ msgid "GNUnet configuration" -#~ msgstr "GNUnet 配置" - #~ msgid "" #~ "Welcome to GNUnet!\n" #~ "\n" @@ -5902,9 +6188,6 @@ msgstr "" #~ "\n" #~ "您的配置更改没有保存。\n" -#~ msgid "list all network adapters" -#~ msgstr "列出所有网络适配器" - #~ msgid "install GNUnet as Windows service" #~ msgstr "䝼 Windows 服务方式安装 GNUnet" @@ -5914,9 +6197,6 @@ msgstr "" #~ msgid "display a file's hash value" #~ msgstr "显示一个文件的散列值" -#~ msgid "GNUnet service installed successfully.\n" -#~ msgstr "GNUnet 服务安装成功。\n" - #~ msgid "This version of Windows doesn't support services.\n" #~ msgstr "此版本的 Windows 不支持服务。\n" @@ -6127,9 +6407,6 @@ msgstr "" #~ msgid "Syntax error in configuration entry HOST in section NETWORK: `%s'\n" #~ msgstr "在 NETWORK 节的配置条目 HOST 中有语法错误:“%s”\n" -#~ msgid "Error connecting to %s:%u. Is the daemon running?\n" -#~ msgstr "连接 %s:%u 出错。守护程序在运行吗?\n" - #~ msgid "Reading result from gnunetd failed, reply invalid!\n" #~ msgstr "从 gnunetd 读取结果失败,应答无效!\n" @@ -6288,19 +6565,12 @@ msgstr "" #~ msgid "Command `%s' requires two arguments (`%s' and `%s').\n" #~ msgstr "%s:选项“%s”要求有一个参数\n" -#, fuzzy -#~ msgid "Unsupported command `%s'. Aborting.\n" -#~ msgstr "未知的命令“%s”。\n" - #~ msgid "" #~ "OS tells us about very large message (%u bytes) pending on UDP socket, " #~ "truncating at 64k\n" #~ msgstr "" #~ "操作系统通知,在 UPnP 套接字上有大量消息待处理(%u 字节),将截短为64k\n" -#~ msgid "Error while parsing dscl output.\n" -#~ msgstr "解析 dscl 输出时出错。\n" - #~ msgid "" #~ "Couldn't find a group (`%s') for the new user and none was specified.\n" #~ msgstr "找不到新用户的组(“%s”)且没有指定用户组。\n" diff --git a/src/Makefile.am b/src/Makefile.am index c3474d5..37bcbf6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,12 +3,20 @@ #endif if HAVE_EXPERIMENTAL - EXP_DIR = chat dv gns stream + EXP_DIR = chat dv stream regex endif if LINUX # All of these currently only work on GNU/Linux - LINUX_DIR = dns exit vpn pt + LINUX_DIR = dns gns exit vpn pt +endif + +if HAVE_MYSQL + MYSQL_DIR = mysql +endif + +if HAVE_POSTGRES + POSTGRES_DIR = postgres endif @@ -21,6 +29,8 @@ SUBDIRS = \ statistics \ arm \ peerinfo \ + $(MYSQL_DIR) \ + $(POSTGRES_DIR) \ datacache \ datastore \ namestore \ @@ -32,12 +42,14 @@ SUBDIRS = \ peerinfo-tool \ core \ testing \ + testbed \ nse \ dht \ hostlist \ topology \ fs \ mesh \ + lockmanager \ $(LINUX_DIR) \ integration-tests \ $(EXP_DIR) diff --git a/src/Makefile.in b/src/Makefile.in index a819026..f4f21c1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -82,9 +82,10 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = include util hello tun block statistics arm peerinfo \ - datacache datastore namestore template ats nat fragmentation \ - transport peerinfo-tool core testing nse dht hostlist topology \ - fs mesh dns exit vpn pt integration-tests chat dv gns stream + mysql postgres datacache datastore namestore template ats nat \ + fragmentation transport peerinfo-tool core testing testbed nse \ + dht hostlist topology fs mesh lockmanager dns gns exit vpn pt \ + integration-tests chat dv stream regex DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -166,6 +167,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -199,6 +201,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -315,10 +318,12 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -@HAVE_EXPERIMENTAL_TRUE@EXP_DIR = chat dv gns stream +@HAVE_EXPERIMENTAL_TRUE@EXP_DIR = chat dv stream regex # All of these currently only work on GNU/Linux -@LINUX_TRUE@LINUX_DIR = dns exit vpn pt +@LINUX_TRUE@LINUX_DIR = dns gns exit vpn pt +@HAVE_MYSQL_TRUE@MYSQL_DIR = mysql +@HAVE_POSTGRES_TRUE@POSTGRES_DIR = postgres SUBDIRS = \ include $(INTLEMU_SUBDIRS) \ util \ @@ -328,6 +333,8 @@ SUBDIRS = \ statistics \ arm \ peerinfo \ + $(MYSQL_DIR) \ + $(POSTGRES_DIR) \ datacache \ datastore \ namestore \ @@ -339,12 +346,14 @@ SUBDIRS = \ peerinfo-tool \ core \ testing \ + testbed \ nse \ dht \ hostlist \ topology \ fs \ mesh \ + lockmanager \ $(LINUX_DIR) \ integration-tests \ $(EXP_DIR) diff --git a/src/arm/Makefile.in b/src/arm/Makefile.in index 584cc06..122ab3c 100644 --- a/src/arm/Makefile.in +++ b/src/arm/Makefile.in @@ -223,6 +223,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -256,6 +257,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/arm/arm.conf.in b/src/arm/arm.conf.in index c1f408f..e72e420 100644 --- a/src/arm/arm.conf.in +++ b/src/arm/arm.conf.in @@ -7,7 +7,7 @@ CONFIG = $DEFAULTCONFIG BINARY = gnunet-service-arm ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; -DEFAULTSERVICES = topology hostlist +DEFAULTSERVICES = topology hostlist dht nse mesh fs UNIXPATH = /tmp/gnunet-service-arm.sock UNIX_MATCH_UID = YES UNIX_MATCH_GID = YES diff --git a/src/arm/arm.h b/src/arm/arm.h index 4b9da6f..2188410 100644 --- a/src/arm/arm.h +++ b/src/arm/arm.h @@ -51,6 +51,27 @@ struct GNUNET_ARM_ResultMessage */ uint32_t status; }; + +/** + * Reply from ARM to client for the + * GNUNET_MESSAGE_TYPE_ARM_LIST request followed by count + * '\0' terminated strings. header->size contains the + * total size (including all strings). + */ +struct GNUNET_ARM_ListResultMessage +{ + /** + * Reply to client is of type GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT + */ + struct GNUNET_MessageHeader header; + + /** + * Number of '\0' terminated strings that follow + * this message. + */ + uint16_t count; +}; + GNUNET_NETWORK_STRUCT_END #endif diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c index 0f4ae6a..1b78d33 100644 --- a/src/arm/arm_api.c +++ b/src/arm/arm_api.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -52,7 +52,6 @@ struct GNUNET_ARM_Handle }; - /** * Context for handling the shutdown of a service. */ @@ -84,9 +83,9 @@ struct ShutdownContext void *cont_cls; /** - * Result of the operation + * Handle for transmission request. */ - enum GNUNET_ARM_ProcessStatus confirmed; + struct GNUNET_CLIENT_TransmitHandle *th; }; @@ -106,45 +105,23 @@ static void service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) { struct ShutdownContext *shutdown_ctx = cls; - const struct GNUNET_ARM_ResultMessage *rmsg; - if (msg == NULL) + if (NULL != msg) { - if (shutdown_ctx->cont != NULL) - { - if (shutdown_ctx->confirmed == GNUNET_ARM_PROCESS_SHUTDOWN) - { - /* shutdown is now complete, as we waited for the network disconnect... */ - shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN); - } - else - { - /* communication error */ - shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); - } - } + /* We just expected a disconnect! Report the error and be done with it... */ + GNUNET_break (0); + shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); + GNUNET_CLIENT_disconnect (shutdown_ctx->sock); GNUNET_free (shutdown_ctx); return; } - if (ntohs (msg->size) == - sizeof (struct GNUNET_ARM_ResultMessage)) - { - rmsg = (const struct GNUNET_ARM_ResultMessage*) msg; - shutdown_ctx->confirmed = (enum GNUNET_ARM_ProcessStatus) ntohl (rmsg->status); - if (shutdown_ctx->confirmed != GNUNET_ARM_PROCESS_SHUTDOWN) - { - /* ARM is not shutting down, well, report the error and be done with it... */ - shutdown_ctx->cont (shutdown_ctx->cont_cls, shutdown_ctx->confirmed); - GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); - GNUNET_free (shutdown_ctx); - return; - } - } - GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler, - shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL); + if (NULL != shutdown_ctx->cont) + /* shutdown is now complete, as we waited for the network disconnect... */ + shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN); + GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); + GNUNET_CLIENT_disconnect (shutdown_ctx->sock); + GNUNET_free (shutdown_ctx); } @@ -161,7 +138,7 @@ service_shutdown_cancel (void *cls, struct ShutdownContext *shutdown_ctx = cls; shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_TIMEOUT); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); + GNUNET_CLIENT_disconnect (shutdown_ctx->sock); GNUNET_free (shutdown_ctx); } @@ -178,19 +155,19 @@ service_shutdown_cancel (void *cls, static size_t write_shutdown (void *cls, size_t size, void *buf) { - struct GNUNET_MessageHeader *msg; struct ShutdownContext *shutdown_ctx = cls; + struct GNUNET_MessageHeader *msg; + shutdown_ctx->th = NULL; if (size < sizeof (struct GNUNET_MessageHeader)) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - _("Failed to transmit shutdown request to client.\n")); - shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); - GNUNET_free (shutdown_ctx); - return 0; /* client disconnected */ - } - + { + LOG (GNUNET_ERROR_TYPE_WARNING, + _("Failed to transmit shutdown request to client.\n")); + shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); + GNUNET_CLIENT_disconnect (shutdown_ctx->sock); + GNUNET_free (shutdown_ctx); + return 0; /* client disconnected */ + } GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler, shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL); shutdown_ctx->cancel_task = @@ -229,12 +206,10 @@ arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock, shutdown_ctx->cont_cls = cont_cls; shutdown_ctx->sock = sock; shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); - shutdown_ctx->confirmed = GNUNET_ARM_PROCESS_COMMUNICATION_ERROR; - /* FIXME: store return value? */ - GNUNET_CLIENT_notify_transmit_ready (sock, - sizeof (struct GNUNET_MessageHeader), - timeout, GNUNET_YES, &write_shutdown, - shutdown_ctx); + shutdown_ctx->th = GNUNET_CLIENT_notify_transmit_ready (sock, + sizeof (struct GNUNET_MessageHeader), + timeout, GNUNET_NO, &write_shutdown, + shutdown_ctx); } @@ -269,7 +244,7 @@ void GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h) { if (h->client != NULL) - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); GNUNET_CONFIGURATION_destroy (h->cfg); GNUNET_free (h); } @@ -345,22 +320,18 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) char *lopostfix; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) - { -#if DEBUG_ARM - LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is already running.\n", - "gnunet-service-arm"); -#endif - /* arm is running! */ - if (pos->callback != NULL) - pos->callback (pos->cls, GNUNET_ARM_PROCESS_ALREADY_RUNNING); - GNUNET_free (pos); - return; - } -#if DEBUG_ARM + { + LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is already running.\n", + "gnunet-service-arm"); + /* arm is running! */ + if (pos->callback != NULL) + pos->callback (pos->cls, GNUNET_ARM_PROCESS_ALREADY_RUNNING); + GNUNET_free (pos); + return; + } LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is not running, will start it.\n", "gnunet-service-arm"); -#endif if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "PREFIX", &loprefix)) @@ -372,33 +343,33 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "BINARY", &binary)) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - _ - ("Configuration failes to specify option `%s' in section `%s'!\n"), - "BINARY", "arm"); - if (pos->callback != NULL) - pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN); - GNUNET_free (pos); - GNUNET_free (loprefix); - GNUNET_free (lopostfix); - return; - } + { + LOG (GNUNET_ERROR_TYPE_WARNING, + _ + ("Configuration failes to specify option `%s' in section `%s'!\n"), + "BINARY", "arm"); + if (pos->callback != NULL) + pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN); + GNUNET_free (pos); + GNUNET_free (loprefix); + GNUNET_free (lopostfix); + return; + } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (pos->h->cfg, "arm", "CONFIG", &config)) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - _("Configuration fails to specify option `%s' in section `%s'!\n"), - "CONFIG", "arm"); - if (pos->callback != NULL) - pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN); - GNUNET_free (binary); - GNUNET_free (pos); - GNUNET_free (loprefix); - GNUNET_free (lopostfix); - return; - } + { + LOG (GNUNET_ERROR_TYPE_WARNING, + _("Configuration fails to specify option `%s' in section `%s'!\n"), + "CONFIG", "arm"); + if (pos->callback != NULL) + pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN); + GNUNET_free (binary); + GNUNET_free (pos); + GNUNET_free (loprefix); + GNUNET_free (lopostfix); + return; + } if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING", "WEAKRANDOM")) && (GNUNET_YES == @@ -407,26 +378,20 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) && (GNUNET_NO == GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING", "HOSTFILE"))) - { - /* Means we are ONLY running locally */ - /* we're clearly running a test, don't daemonize */ - proc = do_start_process (GNUNET_NO, - NULL, loprefix, binary, "-c", config, -#if DEBUG_ARM - "-L", "DEBUG", -#endif - /* no daemonization! */ - lopostfix, NULL); - } + { + /* Means we are ONLY running locally */ + /* we're clearly running a test, don't daemonize */ + proc = do_start_process (GNUNET_NO, + NULL, loprefix, binary, "-c", config, + /* no daemonization! */ + lopostfix, NULL); + } else - { - proc = do_start_process (GNUNET_NO, - NULL, loprefix, binary, "-c", config, -#if DEBUG_ARM - "-L", "DEBUG", -#endif - "-d", lopostfix, NULL); - } + { + proc = do_start_process (GNUNET_NO, + NULL, loprefix, binary, "-c", config, + "-d", lopostfix, NULL); + } GNUNET_free (binary); GNUNET_free (config); GNUNET_free (loprefix); @@ -461,26 +426,24 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) if ((msg == NULL) || (ntohs (msg->size) != sizeof (struct GNUNET_ARM_ResultMessage))) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - _ - ("Error receiving response to `%s' request from ARM for service `%s'\n"), - (sc->type == GNUNET_MESSAGE_TYPE_ARM_START) ? "START" : "STOP", - (const char *) &sc[1]); - GNUNET_CLIENT_disconnect (sc->h->client, GNUNET_NO); - sc->h->client = GNUNET_CLIENT_connect ("arm", sc->h->cfg); - GNUNET_assert (NULL != sc->h->client); - if (sc->callback != NULL) - sc->callback (sc->cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); - GNUNET_free (sc); - return; - } + { + LOG (GNUNET_ERROR_TYPE_WARNING, + _ + ("Error receiving response to `%s' request from ARM for service `%s'\n"), + (sc->type == GNUNET_MESSAGE_TYPE_ARM_START) ? "START" : "STOP", + (const char *) &sc[1]); + GNUNET_CLIENT_disconnect (sc->h->client); + sc->h->client = GNUNET_CLIENT_connect ("arm", sc->h->cfg); + GNUNET_assert (NULL != sc->h->client); + if (sc->callback != NULL) + sc->callback (sc->cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); + GNUNET_free (sc); + return; + } res = (const struct GNUNET_ARM_ResultMessage *) msg; -#if DEBUG_ARM LOG (GNUNET_ERROR_TYPE_DEBUG, "Received response from ARM for service `%s': %u\n", (const char *) &sc[1], ntohs (msg->type)); -#endif status = (enum GNUNET_ARM_ProcessStatus) ntohl (res->status); if (sc->callback != NULL) sc->callback (sc->cls, status); @@ -510,19 +473,17 @@ change_service (struct GNUNET_ARM_Handle *h, const char *service_name, slen = strlen (service_name) + 1; if (slen + sizeof (struct GNUNET_MessageHeader) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) - { - GNUNET_break (0); - if (cb != NULL) - cb (cb_cls, GNUNET_NO); - return; - } -#if DEBUG_ARM + { + GNUNET_break (0); + if (cb != NULL) + cb (cb_cls, GNUNET_NO); + return; + } LOG (GNUNET_ERROR_TYPE_DEBUG, (type == GNUNET_MESSAGE_TYPE_ARM_START) ? _("Requesting start of service `%s'.\n") : _("Requesting termination of service `%s'.\n"), service_name); -#endif sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen); sctx->h = h; sctx->callback = cb; @@ -539,20 +500,19 @@ change_service (struct GNUNET_ARM_Handle *h, const char *service_name, GNUNET_TIME_absolute_get_remaining (sctx->timeout), GNUNET_YES, &handle_response, sctx)) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - (type == - GNUNET_MESSAGE_TYPE_ARM_START) ? - _("Error while trying to transmit request to start `%s' to ARM\n") - : - _("Error while trying to transmit request to stop `%s' to ARM\n"), - (const char *) &service_name); - if (cb != NULL) - cb (cb_cls, GNUNET_SYSERR); - GNUNET_free (sctx); - GNUNET_free (msg); - return; - } + { + LOG (GNUNET_ERROR_TYPE_WARNING, + (type == + GNUNET_MESSAGE_TYPE_ARM_START) + ? _("Error while trying to transmit request to start `%s' to ARM\n") + : _("Error while trying to transmit request to stop `%s' to ARM\n"), + (const char *) &service_name); + if (cb != NULL) + cb (cb_cls, GNUNET_SYSERR); + GNUNET_free (sctx); + GNUNET_free (msg); + return; + } GNUNET_free (msg); } @@ -576,38 +536,36 @@ GNUNET_ARM_start_service (struct GNUNET_ARM_Handle *h, struct GNUNET_CLIENT_Connection *client; size_t slen; -#if DEBUG_ARM LOG (GNUNET_ERROR_TYPE_DEBUG, _("Asked to start service `%s' within %llu ms\n"), service_name, (unsigned long long) timeout.rel_value); -#endif if (0 == strcasecmp ("arm", service_name)) - { - slen = strlen ("arm") + 1; - sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen); - sctx->h = h; - sctx->callback = cb; - sctx->cls = cb_cls; - sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); - memcpy (&sctx[1], service_name, slen); - GNUNET_CLIENT_service_test ("arm", h->cfg, timeout, &arm_service_report, - sctx); - return; - } + { + slen = strlen ("arm") + 1; + sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen); + sctx->h = h; + sctx->callback = cb; + sctx->cls = cb_cls; + sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); + memcpy (&sctx[1], service_name, slen); + GNUNET_CLIENT_service_test ("arm", h->cfg, timeout, &arm_service_report, + sctx); + return; + } if (h->client == NULL) + { + client = GNUNET_CLIENT_connect ("arm", h->cfg); + if (client == NULL) { - client = GNUNET_CLIENT_connect ("arm", h->cfg); - if (client == NULL) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "arm_api, GNUNET_CLIENT_connect returned NULL\n"); - cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); - return; - } LOG (GNUNET_ERROR_TYPE_DEBUG, - "arm_api, GNUNET_CLIENT_connect returned non-NULL\n"); - h->client = client; + "arm_api, GNUNET_CLIENT_connect returned NULL\n"); + cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); + return; } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "arm_api, GNUNET_CLIENT_connect returned non-NULL\n"); + h->client = client; + } LOG (GNUNET_ERROR_TYPE_DEBUG, "arm_api, h->client non-NULL\n"); change_service (h, service_name, timeout, cb, cb_cls, GNUNET_MESSAGE_TYPE_ARM_START); @@ -654,28 +612,190 @@ GNUNET_ARM_stop_service (struct GNUNET_ARM_Handle *h, LOG (GNUNET_ERROR_TYPE_INFO, _("Stopping service `%s' within %llu ms\n"), service_name, (unsigned long long) timeout.rel_value); if (h->client == NULL) + { + client = GNUNET_CLIENT_connect ("arm", h->cfg); + if (client == NULL) { - client = GNUNET_CLIENT_connect ("arm", h->cfg); - if (client == NULL) - { - cb (cb_cls, GNUNET_SYSERR); - return; - } - h->client = client; - } - if (0 == strcasecmp ("arm", service_name)) - { - arm_shutdown_ctx = GNUNET_malloc (sizeof (struct ARM_ShutdownContext)); - arm_shutdown_ctx->cb = cb; - arm_shutdown_ctx->cb_cls = cb_cls; - arm_service_shutdown (h->client, timeout, &arm_shutdown_callback, - arm_shutdown_ctx); - h->client = NULL; + cb (cb_cls, GNUNET_SYSERR); return; } + h->client = client; + } + if (0 == strcasecmp ("arm", service_name)) + { + arm_shutdown_ctx = GNUNET_malloc (sizeof (struct ARM_ShutdownContext)); + arm_shutdown_ctx->cb = cb; + arm_shutdown_ctx->cb_cls = cb_cls; + arm_service_shutdown (h->client, timeout, &arm_shutdown_callback, + arm_shutdown_ctx); + h->client = NULL; + return; + } change_service (h, service_name, timeout, cb, cb_cls, GNUNET_MESSAGE_TYPE_ARM_STOP); } +/** + * Internal state for a list request with ARM. + */ +struct ListRequestContext +{ + + /** + * Pointer to our handle with ARM. + */ + struct GNUNET_ARM_Handle *h; + + /** + * Function to call with a status code for the requested operation. + */ + GNUNET_ARM_List_Callback callback; + + /** + * Closure for "callback". + */ + void *cls; + + /** + * Timeout for the operation. + */ + struct GNUNET_TIME_Absolute timeout; +}; + + +/** + * Process a response from ARM for the list request. + * + * @param cls the list request context + * @param msg the response + */ +static void +handle_list_response (void *cls, const struct GNUNET_MessageHeader *msg) +{ + struct ListRequestContext *sc = cls; + const struct GNUNET_ARM_ListResultMessage *res; + const char *pos; + uint16_t size_check; + uint16_t rcount; + uint16_t msize; + + if (NULL == msg) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Error receiving response to LIST request from ARM\n"); + GNUNET_CLIENT_disconnect (sc->h->client); + sc->h->client = GNUNET_CLIENT_connect ("arm", sc->h->cfg); + GNUNET_assert (NULL != sc->h->client); + if (sc->callback != NULL) + sc->callback (sc->cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR, 0, NULL); + GNUNET_free (sc); + return; + } + + if (NULL == sc->callback) + { + GNUNET_break (0); + GNUNET_free (sc); + return; + } + msize = ntohs (msg->size); + if ( (msize < sizeof ( struct GNUNET_ARM_ListResultMessage)) || + (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT) ) + { + GNUNET_break (0); + sc->callback (sc->cls, GNUNET_NO, 0, NULL); + GNUNET_free (sc); + return; + } + size_check = 0; + res = (const struct GNUNET_ARM_ListResultMessage *) msg; + rcount = ntohs (res->count); + { + const char *list[rcount]; + unsigned int i; + + pos = (const char *)&res[1]; + for (i=0; icallback (sc->cls, GNUNET_NO, 0, NULL); + GNUNET_free (sc); + return; + } + list[i] = pos; + size_check += (end - pos) + 1; + pos = end + 1; + } + sc->callback (sc->cls, GNUNET_YES, rcount, list); + } + GNUNET_free (sc); +} + + +/** + * List all running services. + * + * @param h handle to ARM + * @param timeout how long to wait before failing for good + * @param cb callback to invoke when service is ready + * @param cb_cls closure for callback + */ +void +GNUNET_ARM_list_running_services (struct GNUNET_ARM_Handle *h, + struct GNUNET_TIME_Relative timeout, + GNUNET_ARM_List_Callback cb, void *cb_cls) +{ + struct ListRequestContext *sctx; + struct GNUNET_MessageHeader msg; + struct GNUNET_CLIENT_Connection *client; + + if (h->client == NULL) + { + client = GNUNET_CLIENT_connect ("arm", h->cfg); + if (client == NULL) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "arm_api, GNUNET_CLIENT_connect returned NULL\n"); + cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR, 0, NULL); + return; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "arm_api, GNUNET_CLIENT_connect returned non-NULL\n"); + h->client = client; + } + + sctx = GNUNET_malloc (sizeof (struct RequestContext)); + sctx->h = h; + sctx->callback = cb; + sctx->cls = cb_cls; + sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); + msg.size = htons (sizeof (struct GNUNET_MessageHeader)); + msg.type = htons (GNUNET_MESSAGE_TYPE_ARM_LIST); + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Requesting LIST from ARM service with timeout: %llu ms\n", + (unsigned long long)timeout.rel_value); + + if (GNUNET_OK != + GNUNET_CLIENT_transmit_and_get_response (sctx->h->client, + &msg, + GNUNET_TIME_absolute_get_remaining + (sctx->timeout), + GNUNET_YES, + &handle_list_response, + sctx)) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Error while trying to transmit request to list services to ARM\n"); + if (cb != NULL) + cb (cb_cls, GNUNET_SYSERR, 0, NULL); + GNUNET_free (sctx); + return; + } +} + /* end of arm_api.c */ diff --git a/src/arm/do_start_process.c b/src/arm/do_start_process.c index 865ea8e..4554f57 100644 --- a/src/arm/do_start_process.c +++ b/src/arm/do_start_process.c @@ -7,6 +7,7 @@ * limitation that it does NOT allow passing command line arguments * with spaces to the new process. * + * @param pipe_control should a pipe be used to send signals to the child? * @param lsocks array of listen sockets to dup starting at fd3 (systemd-style), or NULL * @param first_arg first argument for argv (may be an empty string) * @param ... more arguments, NULL terminated diff --git a/src/arm/gnunet-arm.c b/src/arm/gnunet-arm.c index 65700ee..58aa709 100644 --- a/src/arm/gnunet-arm.c +++ b/src/arm/gnunet-arm.c @@ -48,6 +48,11 @@ */ #define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) +/** + * Timeout for listing all running services. + */ +#define LIST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) + /** * Set if we are to shutdown all services (including ARM). */ @@ -73,6 +78,11 @@ static int delete; */ static int quiet; +/** + * Set if we should print a list of currently running services. + */ +static int list; + /** * Set to the name of a service to start. */ @@ -193,6 +203,29 @@ confirm_cb (void *cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); } +/** + * Callback invoked with the list of running services. + * Reports to the user and then runs the next phase in the FSM. + * + * @param cls currently not used + * @param result result of the operation + * @param count number of running services + * @param list copy of the list of running services + */ +static void +list_cb (void *cls, int result, unsigned int count, const char *const*list) +{ + unsigned int i; + + if ( (result != GNUNET_YES) || (NULL == list) ) + { + FPRINTF (stderr, "%s", _("Error communicating with ARM. ARM not running?\n")); + return; + } + FPRINTF (stdout, "%s", _("Running services:\n")); + for (i=0; iname, "DEBUG"); /* actually start process */ -#if DEBUG_ARM GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting service `%s' using binary `%s' and configuration `%s'\n", sl->name, sl->binary, sl->config); -#endif GNUNET_assert (NULL == sl->proc); if (GNUNET_YES == use_debug) sl->proc = @@ -357,10 +361,8 @@ write_result (void *cls, size_t size, void *buf) _("Could not send status result to client\n")); return 0; /* error, not much we can do */ } -#if DEBUG_ARM GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending status response %u to client\n", (unsigned int) *res); -#endif GNUNET_assert (size >= sizeof (struct GNUNET_ARM_ResultMessage)); msg = buf; msg->header.size = htons (sizeof (struct GNUNET_ARM_ResultMessage)); @@ -370,6 +372,43 @@ write_result (void *cls, size_t size, void *buf) return sizeof (struct GNUNET_ARM_ResultMessage); } +/** + * Transmit the list of running services. + * + * @param cls pointer to struct GNUNET_ARM_ListResultMessage with the message + * @param size number of bytes available in buf + * @param buf where to copy the message, NULL on error + * @return number of bytes copied to buf + */ +static size_t +write_list_result (void *cls, size_t size, void *buf) +{ + struct GNUNET_ARM_ListResultMessage *msg = cls; + struct GNUNET_ARM_ListResultMessage *rslt; + size_t rslt_size; + + if (buf == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Could not send list result to client\n")); + return 0; /* error, not much we can do */ + } + + GNUNET_assert (size >= msg->header.size); + rslt = buf; + rslt->header.size = htons (msg->header.size); + rslt->header.type = htons (msg->header.type); + rslt->count = htons (msg->count); + + size_t list_size = msg->header.size + - sizeof (struct GNUNET_ARM_ListResultMessage); + memcpy (&rslt[1], &msg[1], list_size); + + rslt_size = msg->header.size; + GNUNET_free (msg); + return rslt_size; +} + /** * Signal our client that we will start or stop the @@ -455,7 +494,7 @@ static void create_listen_socket (struct sockaddr *sa, socklen_t addr_len, struct ServiceList *sl) { - const static int on = 1; + static int on = 1; struct GNUNET_NETWORK_Handle *sock; struct ServiceListeningInfo *sli; @@ -566,7 +605,7 @@ handle_start (void *cls, struct GNUNET_SERVER_Client *client, const char *servicename; struct ServiceList *sl; uint16_t size; - + size = ntohs (message->size); size -= sizeof (struct GNUNET_MessageHeader); servicename = (const char *) &message[1]; @@ -652,17 +691,73 @@ handle_stop (void *cls, struct GNUNET_SERVER_Client *client, signal_result (client, servicename, GNUNET_ARM_PROCESS_ALREADY_DOWN); return; } -#if DEBUG_ARM GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending kill signal to service `%s', waiting for process to die.\n", servicename); -#endif + sl->killed_at = GNUNET_TIME_absolute_get (); if (0 != GNUNET_OS_process_kill (sl->proc, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); sl->killing_client = client; GNUNET_SERVER_client_keep (client); } +/** + * Handle LIST-message. + * + * @param cls closure (always NULL) + * @param client identification of the client + * @param message the actual message + */ +static void +handle_list (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + struct GNUNET_ARM_ListResultMessage *msg; + size_t string_list_size; + size_t total_size; + struct ServiceList *sl; + uint16_t count; + + if (NULL == client) + return; + + count = 0; + string_list_size = 0; + /* first count the running processes get their name's size */ + for (sl = running_head; sl != NULL; sl = sl->next) + { + if (sl->proc != NULL) + { + string_list_size += strlen (sl->name); + string_list_size += strlen (sl->binary); + string_list_size += 4; + count++; + } + } + total_size = sizeof (struct GNUNET_ARM_ListResultMessage) + + string_list_size; + msg = GNUNET_malloc (total_size); + msg->header.size = total_size; + msg->header.type = GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT; + msg->count = count; + + char *pos = (char *)&msg[1]; + for (sl = running_head; sl != NULL; sl = sl->next) + { + if (sl->proc != NULL) + { + size_t s = strlen (sl->name) + strlen (sl->binary) + 4; + GNUNET_snprintf(pos, s, "%s (%s)", sl->name, sl->binary); + pos += s; + } + } + + GNUNET_SERVER_notify_transmit_ready (client, + msg->header.size, + GNUNET_TIME_UNIT_FOREVER_REL, + &write_list_result, msg); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} /** * We are done with everything. Stop remaining @@ -698,46 +793,47 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct ServiceListeningInfo *sli; if (GNUNET_SCHEDULER_NO_TASK != child_restart_task) - { - GNUNET_SCHEDULER_cancel (child_restart_task); - child_restart_task = GNUNET_SCHEDULER_NO_TASK; - } + { + GNUNET_SCHEDULER_cancel (child_restart_task); + child_restart_task = GNUNET_SCHEDULER_NO_TASK; + } in_shutdown = GNUNET_YES; /* first, stop listening */ for (pos = running_head; NULL != pos; pos = pos->next) - { - while (NULL != (sli = pos->listen_head)) - { - GNUNET_CONTAINER_DLL_remove (pos->listen_head, - pos->listen_tail, sli); - if (sli->accept_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (sli->accept_task); - sli->accept_task = GNUNET_SCHEDULER_NO_TASK; - } - GNUNET_break (GNUNET_OK == - GNUNET_NETWORK_socket_close (sli->listen_socket)); - GNUNET_free (sli->service_addr); - GNUNET_free (sli); - } - } + { + while (NULL != (sli = pos->listen_head)) + { + GNUNET_CONTAINER_DLL_remove (pos->listen_head, + pos->listen_tail, sli); + if (sli->accept_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (sli->accept_task); + sli->accept_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_break (GNUNET_OK == + GNUNET_NETWORK_socket_close (sli->listen_socket)); + GNUNET_free (sli->service_addr); + GNUNET_free (sli); + } + } /* then, shutdown all existing service processes */ nxt = running_head; while (NULL != (pos = nxt)) + { + nxt = pos->next; + if (pos->proc != NULL) { - nxt = pos->next; - if (pos->proc != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", - pos->name); - if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); - } - else - { - free_service (pos); - } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", + pos->name); + pos->killed_at = GNUNET_TIME_absolute_get (); + if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + } + else + { + free_service (pos); } + } /* finally, should all service processes be already gone, terminate for real */ if (running_head == NULL) do_shutdown (); @@ -767,56 +863,53 @@ delayed_restart_task (void *cls, /* check for services that need to be restarted due to * configuration changes or because the last restart failed */ for (sl = running_head; NULL != sl; sl = sl->next) + { + if (NULL != sl->proc) + continue; + /* service is currently not running */ + if (GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value == + 0) { - if (sl->proc == NULL) - { - /* service is currently not running */ - if (GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value == - 0) - { - /* restart is now allowed */ - if (sl->is_default) - { - /* process should run by default, start immediately */ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Restarting service `%s'.\n"), sl->name); - start_process (sl); - } - else - { - /* process is run on-demand, ensure it is re-started if there is demand */ - for (sli = sl->listen_head; NULL != sli; sli = sli->next) - if (GNUNET_SCHEDULER_NO_TASK == sli->accept_task) - { - /* accept was actually paused, so start it again */ - sli->accept_task = - GNUNET_SCHEDULER_add_read_net - (GNUNET_TIME_UNIT_FOREVER_REL, sli->listen_socket, - &accept_connection, sli); - } - } - } - else - { - /* update calculation for earliest time to reactivate a service */ - lowestRestartDelay = - GNUNET_TIME_relative_min (lowestRestartDelay, - GNUNET_TIME_absolute_get_remaining - (sl->restart_at)); - } - } + /* restart is now allowed */ + if (sl->is_default) + { + /* process should run by default, start immediately */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Restarting service `%s'.\n"), sl->name); + start_process (sl); + } + else + { + /* process is run on-demand, ensure it is re-started if there is demand */ + for (sli = sl->listen_head; NULL != sli; sli = sli->next) + if (GNUNET_SCHEDULER_NO_TASK == sli->accept_task) + { + /* accept was actually paused, so start it again */ + sli->accept_task = + GNUNET_SCHEDULER_add_read_net + (GNUNET_TIME_UNIT_FOREVER_REL, sli->listen_socket, + &accept_connection, sli); + } + } } - if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) + else { -#if DEBUG_ARM - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will restart process in %llums\n", - (unsigned long long) lowestRestartDelay.rel_value); -#endif - child_restart_task = - GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, - GNUNET_SCHEDULER_PRIORITY_IDLE, - &delayed_restart_task, NULL); + /* update calculation for earliest time to reactivate a service */ + lowestRestartDelay = + GNUNET_TIME_relative_min (lowestRestartDelay, + GNUNET_TIME_absolute_get_remaining + (sl->restart_at)); } + } + if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will restart process in %llums\n", + (unsigned long long) lowestRestartDelay.rel_value); + child_restart_task = + GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, + GNUNET_SCHEDULER_PRIORITY_IDLE, + &delayed_restart_task, NULL); + } } @@ -861,11 +954,11 @@ maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) next = pos->next; if (pos->proc == NULL) - { - if (GNUNET_YES == in_shutdown) - free_service (pos); - continue; - } + { + if (GNUNET_YES == in_shutdown) + free_service (pos); + continue; + } if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc, &statusType, &statusCode))) @@ -873,21 +966,28 @@ maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) || (statusType == GNUNET_OS_PROCESS_RUNNING))) continue; if (statusType == GNUNET_OS_PROCESS_EXITED) - { - statstr = _( /* process termination method */ "exit"); - statcode = statusCode; - } + { + statstr = _( /* process termination method */ "exit"); + statcode = statusCode; + } else if (statusType == GNUNET_OS_PROCESS_SIGNALED) - { - statstr = _( /* process termination method */ "signal"); - statcode = statusCode; - } + { + statstr = _( /* process termination method */ "signal"); + statcode = statusCode; + } else - { - statstr = _( /* process termination method */ "unknown"); - statcode = 0; - } - GNUNET_OS_process_close (pos->proc); + { + statstr = _( /* process termination method */ "unknown"); + statcode = 0; + } + if (0 != pos->killed_at.abs_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Service `%s' took %llu ms to terminate\n"), + pos->name, + GNUNET_TIME_absolute_get_duration (pos->killed_at).rel_value); + } + GNUNET_OS_process_destroy (pos->proc); pos->proc = NULL; if (NULL != pos->killing_client) { @@ -947,41 +1047,6 @@ maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } -/** - * Transmit our shutdown acknowledgement to the client. - * - * @param cls the 'struct GNUNET_SERVER_Client' - * @param size number of bytes available in buf - * @param buf where to write the message - * @return number of bytes written - */ -static size_t -transmit_shutdown_ack (void *cls, size_t size, void *buf) -{ - struct GNUNET_SERVER_Client *client = cls; - struct GNUNET_ARM_ResultMessage *msg; - - if (size < sizeof (struct GNUNET_ARM_ResultMessage)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Failed to transmit shutdown ACK.\n")); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return 0; /* client disconnected */ - } - /* Make the connection flushing for the purpose of ACK transmitting, - * needed on W32 to ensure that the message is even received, harmless - * on other platforms... */ - GNUNET_break (GNUNET_OK == GNUNET_SERVER_client_disable_corking (client)); - msg = (struct GNUNET_ARM_ResultMessage *) buf; - msg->header.type = htons (GNUNET_MESSAGE_TYPE_ARM_RESULT); - msg->header.size = htons (sizeof (struct GNUNET_ARM_ResultMessage)); - msg->status = htonl ((uint32_t) GNUNET_ARM_PROCESS_SHUTDOWN); - GNUNET_SERVER_receive_done (client, GNUNET_OK); - GNUNET_SERVER_client_drop (client); - return sizeof (struct GNUNET_ARM_ResultMessage); -} - - /** * Handler for SHUTDOWN message. * @@ -994,11 +1059,6 @@ handle_shutdown (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { GNUNET_SCHEDULER_shutdown (); - GNUNET_SERVER_client_keep (client); - GNUNET_SERVER_notify_transmit_ready (client, - sizeof (struct GNUNET_ARM_ResultMessage), - GNUNET_TIME_UNIT_FOREVER_REL, - &transmit_shutdown_ack, client); GNUNET_SERVER_client_persist_ (client); } @@ -1114,6 +1174,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *serv, {&handle_stop, NULL, GNUNET_MESSAGE_TYPE_ARM_STOP, 0}, {&handle_shutdown, NULL, GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN, sizeof (struct GNUNET_MessageHeader)}, + {&handle_list, NULL, GNUNET_MESSAGE_TYPE_ARM_LIST, + sizeof (struct GNUNET_MessageHeader)}, {NULL, NULL, 0, 0} }; char *defaultservices; @@ -1123,7 +1185,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *serv, cfg = c; server = serv; GNUNET_assert (serv != NULL); - GNUNET_SERVER_ignore_shutdown (serv, GNUNET_YES); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); child_death_task = @@ -1201,7 +1262,8 @@ main (int argc, char *const *argv) GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); ret = (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, "arm", GNUNET_YES, &run, NULL)) ? 0 : 1; + GNUNET_SERVICE_run (argc, argv, "arm", + GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, &run, NULL)) ? 0 : 1; GNUNET_SIGNAL_handler_uninstall (shc_chld); shc_chld = NULL; GNUNET_DISK_pipe_close (sigpipe); diff --git a/src/arm/mockup-service.c b/src/arm/mockup-service.c index 1e97488..d989699 100644 --- a/src/arm/mockup-service.c +++ b/src/arm/mockup-service.c @@ -29,30 +29,6 @@ #include "gnunet_time_lib.h" -static size_t -transmit_shutdown_ack (void *cls, size_t size, void *buf) -{ - struct GNUNET_SERVER_Client *client = cls; - struct GNUNET_MessageHeader *msg; - - if (size < sizeof (struct GNUNET_MessageHeader)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Failed to transmit shutdown ACK.\n")); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return 0; /* client disconnected */ - } - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transmitting shutdown ACK.\n")); - - msg = (struct GNUNET_MessageHeader *) buf; - msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN); - msg->size = htons (sizeof (struct GNUNET_MessageHeader)); - GNUNET_SERVER_receive_done (client, GNUNET_OK); - GNUNET_SERVER_client_drop (client); - return sizeof (struct GNUNET_MessageHeader); -} - /** * Handler for SHUTDOWN message. * @@ -64,14 +40,8 @@ static void handle_shutdown (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - GNUNET_SERVER_client_keep (client); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Initiating shutdown as requested by client.\n")); - - GNUNET_SERVER_notify_transmit_ready (client, - sizeof (struct GNUNET_MessageHeader), - GNUNET_TIME_UNIT_FOREVER_REL, - &transmit_shutdown_ack, client); GNUNET_SERVER_client_persist_ (client); GNUNET_SCHEDULER_shutdown (); } @@ -87,7 +57,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, {NULL, NULL, 0, 0} }; /* process client requests */ - GNUNET_SERVER_ignore_shutdown (server, GNUNET_YES); GNUNET_SERVER_add_handlers (server, handlers); } diff --git a/src/arm/test_exponential_backoff.c b/src/arm/test_exponential_backoff.c index edd5cbf..77bd9e2 100644 --- a/src/arm/test_exponential_backoff.c +++ b/src/arm/test_exponential_backoff.c @@ -113,59 +113,47 @@ service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) { struct ShutdownContext *shutdown_ctx = cls; - if ((msg == NULL) && (shutdown_ctx->confirmed != GNUNET_YES)) - { - /* Means the other side closed the connection and never confirmed a shutdown */ - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Service handle shutdown before ACK!\n"); - if (shutdown_ctx->cont != NULL) - shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR); - GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); - GNUNET_free (shutdown_ctx); - } - else if ((msg == NULL) && (shutdown_ctx->confirmed == GNUNET_YES)) - { + if (msg == NULL) + { #if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n"); #endif - if (shutdown_ctx->cont != NULL) - shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_NO); - - GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); - GNUNET_free (shutdown_ctx); - } - else - { - GNUNET_assert (ntohs (msg->size) == - sizeof (struct GNUNET_MessageHeader)); - switch (ntohs (msg->type)) - { - case GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN: + if (shutdown_ctx->cont != NULL) + shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_NO); + + GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); + GNUNET_CLIENT_disconnect (shutdown_ctx->sock); + GNUNET_free (shutdown_ctx); + return; + } + GNUNET_assert (ntohs (msg->size) == + sizeof (struct GNUNET_MessageHeader)); + switch (ntohs (msg->type)) + { + case GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN: #if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received confirmation for service shutdown.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received confirmation for service shutdown.\n"); #endif - shutdown_ctx->confirmed = GNUNET_YES; - GNUNET_CLIENT_receive (shutdown_ctx->sock, - &service_shutdown_handler, shutdown_ctx, - GNUNET_TIME_UNIT_FOREVER_REL); - break; - default: /* Fall through */ - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Service shutdown refused!\n"); - if (shutdown_ctx->cont != NULL) - shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_YES); - - GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); - GNUNET_free (shutdown_ctx); - break; - } - } + shutdown_ctx->confirmed = GNUNET_YES; + GNUNET_CLIENT_receive (shutdown_ctx->sock, + &service_shutdown_handler, shutdown_ctx, + GNUNET_TIME_UNIT_FOREVER_REL); + break; + default: /* Fall through */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Service shutdown refused!\n"); + if (shutdown_ctx->cont != NULL) + shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_YES); + + GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); + GNUNET_CLIENT_disconnect (shutdown_ctx->sock); + GNUNET_free (shutdown_ctx); + break; + } } + /** * Shutting down took too long, cancel receive and return error. * @@ -180,7 +168,7 @@ service_shutdown_cancel (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "service_shutdown_cancel called!\n"); shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); + GNUNET_CLIENT_disconnect (shutdown_ctx->sock); GNUNET_free (shutdown_ctx); } @@ -205,7 +193,7 @@ write_shutdown (void *cls, size_t size, void *buf) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Failed to transmit shutdown request to client.\n")); shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR); - GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); + GNUNET_CLIENT_disconnect (shutdown_ctx->sock); GNUNET_free (shutdown_ctx); return 0; /* client disconnected */ } @@ -358,7 +346,7 @@ kill_task (void *cbData, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (doNothingConnection != NULL); if (trialCount == 12) { - GNUNET_CLIENT_disconnect (doNothingConnection, GNUNET_NO); + GNUNET_CLIENT_disconnect (doNothingConnection); GNUNET_ARM_stop_service (arm, "do-nothing", TIMEOUT, &arm_notify_stop, NULL); ok = 0; diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index f4056fa..2e85848 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am @@ -32,7 +32,7 @@ libgnunetats_la_LIBADD = \ libgnunetats_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 1:0:1 + -version-info 2:0:2 bin_PROGRAMS = \ @@ -54,6 +54,7 @@ gnunet_service_ats_LDADD = \ check_PROGRAMS = \ test_ats_api_scheduling \ + test_ats_api_reset_backoff \ $(GN_MLP_TEST) \ $(GN_MLP_TEST_AVG) \ $(GN_MLP_PERF) @@ -87,7 +88,7 @@ perf_ats_mlp_SOURCES = \ perf_ats_mlp_LDADD = \ $(GN_LIBGLPK) \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la + $(top_builddir)/src/statistics/libgnunetstatistics.la endif test_ats_api_scheduling_SOURCES = \ @@ -96,6 +97,12 @@ test_ats_api_scheduling_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/ats/libgnunetats.la +test_ats_api_reset_backoff_SOURCES = \ + test_ats_api_reset_backoff.c +test_ats_api_reset_backoff_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/ats/libgnunetats.la + #test_ats_api_scheduling_get_type_SOURCES = \ # test_ats_api_scheduling_get_type.c #test_ats_api_scheduling_get_type_LDADD = \ @@ -117,5 +124,5 @@ test_ats_api_scheduling_LDADD = \ EXTRA_DIST = \ ats.h \ - test_ats_api.conf + test_ats_api.conf diff --git a/src/ats/Makefile.in b/src/ats/Makefile.in index 26610e1..7f74064 100644 --- a/src/ats/Makefile.in +++ b/src/ats/Makefile.in @@ -38,7 +38,8 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = gnunet-service-ats$(EXEEXT) -check_PROGRAMS = test_ats_api_scheduling$(EXEEXT) $(am__EXEEXT_1) \ +check_PROGRAMS = test_ats_api_scheduling$(EXEEXT) \ + test_ats_api_reset_backoff$(EXEEXT) $(am__EXEEXT_1) \ $(am__EXEEXT_2) $(am__EXEEXT_3) subdir = src/ats DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ @@ -134,6 +135,13 @@ perf_ats_mlp_OBJECTS = $(am_perf_ats_mlp_OBJECTS) @HAVE_LIBGLPK_TRUE@perf_ats_mlp_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \ @HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la +am_test_ats_api_reset_backoff_OBJECTS = \ + test_ats_api_reset_backoff.$(OBJEXT) +test_ats_api_reset_backoff_OBJECTS = \ + $(am_test_ats_api_reset_backoff_OBJECTS) +test_ats_api_reset_backoff_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/ats/libgnunetats.la am_test_ats_api_scheduling_OBJECTS = \ test_ats_api_scheduling.$(OBJEXT) test_ats_api_scheduling_OBJECTS = \ @@ -187,11 +195,13 @@ AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgnunetats_la_SOURCES) $(gnunet_service_ats_SOURCES) \ - $(perf_ats_mlp_SOURCES) $(test_ats_api_scheduling_SOURCES) \ - $(test_ats_mlp_SOURCES) $(test_ats_mlp_averaging_SOURCES) + $(perf_ats_mlp_SOURCES) $(test_ats_api_reset_backoff_SOURCES) \ + $(test_ats_api_scheduling_SOURCES) $(test_ats_mlp_SOURCES) \ + $(test_ats_mlp_averaging_SOURCES) DIST_SOURCES = $(libgnunetats_la_SOURCES) \ $(am__gnunet_service_ats_SOURCES_DIST) \ $(am__perf_ats_mlp_SOURCES_DIST) \ + $(test_ats_api_reset_backoff_SOURCES) \ $(test_ats_api_scheduling_SOURCES) \ $(am__test_ats_mlp_SOURCES_DIST) \ $(am__test_ats_mlp_averaging_SOURCES_DIST) @@ -256,6 +266,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -289,6 +300,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -427,7 +439,7 @@ libgnunetats_la_LIBADD = \ libgnunetats_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 1:0:1 + -version-info 2:0:2 gnunet_service_ats_SOURCES = \ gnunet-service-ats.c gnunet-service-ats.h\ @@ -471,7 +483,7 @@ gnunet_service_ats_LDADD = \ @HAVE_LIBGLPK_TRUE@perf_ats_mlp_LDADD = \ @HAVE_LIBGLPK_TRUE@ $(GN_LIBGLPK) \ @HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \ -@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la +@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la test_ats_api_scheduling_SOURCES = \ test_ats_api_scheduling.c @@ -480,6 +492,13 @@ test_ats_api_scheduling_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/ats/libgnunetats.la +test_ats_api_reset_backoff_SOURCES = \ + test_ats_api_reset_backoff.c + +test_ats_api_reset_backoff_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/ats/libgnunetats.la + #test_ats_api_scheduling_get_type_SOURCES = \ # test_ats_api_scheduling_get_type.c @@ -500,7 +519,7 @@ test_ats_api_scheduling_LDADD = \ # $(top_builddir)/src/ats/libgnunetats.la EXTRA_DIST = \ ats.h \ - test_ats_api.conf + test_ats_api.conf all: all-am @@ -629,6 +648,9 @@ gnunet-service-ats$(EXEEXT): $(gnunet_service_ats_OBJECTS) $(gnunet_service_ats_ perf_ats_mlp$(EXEEXT): $(perf_ats_mlp_OBJECTS) $(perf_ats_mlp_DEPENDENCIES) @rm -f perf_ats_mlp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(perf_ats_mlp_OBJECTS) $(perf_ats_mlp_LDADD) $(LIBS) +test_ats_api_reset_backoff$(EXEEXT): $(test_ats_api_reset_backoff_OBJECTS) $(test_ats_api_reset_backoff_DEPENDENCIES) + @rm -f test_ats_api_reset_backoff$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_ats_api_reset_backoff_OBJECTS) $(test_ats_api_reset_backoff_LDADD) $(LIBS) test_ats_api_scheduling$(EXEEXT): $(test_ats_api_scheduling_OBJECTS) $(test_ats_api_scheduling_DEPENDENCIES) @rm -f test_ats_api_scheduling$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_OBJECTS) $(test_ats_api_scheduling_LDADD) $(LIBS) @@ -654,6 +676,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_reservations.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_scheduling.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf_ats_mlp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_reset_backoff.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_mlp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_mlp_averaging.Po@am__quote@ diff --git a/src/ats/ats.conf.in b/src/ats/ats.conf.in index 6ea0d41..f81016e 100644 --- a/src/ats/ats.conf.in +++ b/src/ats/ats.conf.in @@ -10,10 +10,24 @@ ACCEPT_FROM6 = ::1; UNIXPATH = /tmp/gnunet-service-ats.sock UNIX_MATCH_UID = YES UNIX_MATCH_GID = YES + +# Enable MLP mode (default: NO) MLP = NO -WAN_QUOTA_IN = 65536 -WAN_QUOTA_OUT = 65536 +# Network specific inbound/outbound quotas +# LOOPBACK +LOOPBACK_QUOTA_IN = unlimited +LOOPBACK_QUOTA_OUT = unlimited +# LAN +LAN_QUOTA_IN = unlimited +LAN_QUOTA_OUT = unlimited +# WAN +WAN_QUOTA_IN = 64 KiB +WAN_QUOTA_OUT = 64 KiB +# WLAN +WLAN_QUOTA_IN = 1 MiB +WLAN_QUOTA_OUT = 1 MiB # ATS options + DUMP_MLP = NO DUMP_SOLUTION = NO DUMP_OVERWRITE = NO diff --git a/src/ats/ats.h b/src/ats/ats.h index 30ca295..f4c3d9f 100644 --- a/src/ats/ats.h +++ b/src/ats/ats.h @@ -61,6 +61,15 @@ struct RequestAddressMessage struct GNUNET_PeerIdentity peer; }; +struct ResetBackoffMessage +{ + struct GNUNET_MessageHeader header; + + uint32_t reserved GNUNET_PACKED; + + struct GNUNET_PeerIdentity peer; +}; + struct AddressUpdateMessage { diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c index 848c7ec..c98e1c2 100644 --- a/src/ats/ats_api_performance.c +++ b/src/ats/ats_api_performance.c @@ -395,7 +395,7 @@ process_ats_message (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_TIME_UNIT_FOREVER_REL); return; reconnect: - GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (ph->client); ph->client = NULL; ph->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task, @@ -493,7 +493,7 @@ GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph) } if (NULL != ph->client) { - GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (ph->client); ph->client = NULL; } GNUNET_free (ph); diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index 78e8d61..5a4e883 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c @@ -27,7 +27,6 @@ #include "gnunet_ats_service.h" #include "ats.h" -#define DEBUG_ATS GNUNET_EXTRA_LOGGING #define INTERFACE_PROCESSING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) @@ -146,7 +145,6 @@ struct GNUNET_ATS_SchedulingHandle */ struct ATS_Network * net_tail; - /** * Array of session objects (we need to translate them to numbers and back * for the protocol; the offset in the array is the session number on the @@ -163,7 +161,6 @@ struct GNUNET_ATS_SchedulingHandle /** * Task retrieving interfaces from the system */ - GNUNET_SCHEDULER_TaskIdentifier interface_task; @@ -213,7 +210,7 @@ static void force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) { sh->reconnect = GNUNET_NO; - GNUNET_CLIENT_disconnect (sh->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; sh->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task, @@ -319,10 +316,11 @@ static struct Session * find_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, const struct GNUNET_PeerIdentity *peer) { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Find session %u from peer %s in %p\n", + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", + "Find session %u from peer %s in %p\n", (unsigned int) session_id, GNUNET_i2s (peer), sh); -#endif + if (session_id >= sh->session_array_size) { GNUNET_break (0); @@ -366,11 +364,11 @@ get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, unsigned int i; unsigned int f; -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", "Get session ID for session %p from peer %s in %p\n", session, GNUNET_i2s (peer), sh); -#endif + if (NULL == session) return 0; f = 0; @@ -396,11 +394,11 @@ get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, sh->session_array[f].session = session; sh->session_array[f].peer = *peer; sh->session_array[f].slot_used = GNUNET_YES; -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", "Assigning session ID %u for session %p of peer %s in %p\n", f, session, GNUNET_i2s (peer), sh); -#endif + return f; } @@ -417,11 +415,13 @@ static void remove_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, const struct GNUNET_PeerIdentity *peer) { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Remove sessionID %u from peer %s in %p\n", + GNUNET_assert (peer != NULL); + GNUNET_assert (sh != NULL); + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", + "Release sessionID %u from peer %s in %p\n", (unsigned int) session_id, GNUNET_i2s (peer), sh); -#endif + if (0 == session_id) return; GNUNET_assert (session_id < sh->session_array_size); @@ -445,11 +445,11 @@ static void release_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, const struct GNUNET_PeerIdentity *peer) { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", "Release sessionID %u from peer %s in %p\n", (unsigned int) session_id, GNUNET_i2s (peer), sh); -#endif + if (session_id >= sh->session_array_size) { GNUNET_break (0); @@ -552,11 +552,10 @@ process_ats_message (void *cls, const struct GNUNET_MessageHeader *msg) s = find_session (sh, session_id, &m->peer); if (s == NULL) { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", "ATS tries to use outdated session `%s'\n", GNUNET_i2s (&m->peer)); -#endif GNUNET_CLIENT_receive (sh->client, &process_ats_message, sh, GNUNET_TIME_UNIT_FOREVER_REL); return; @@ -618,10 +617,10 @@ reconnect (struct GNUNET_ATS_SchedulingHandle *sh) do_transmit (sh); } + /** * delete the current network list */ - static void delete_networks (struct GNUNET_ATS_SchedulingHandle *sh) { @@ -734,7 +733,6 @@ interface_proc (void *cls, const char *name, } - /** * Periodically get list of addresses * @param cls closure @@ -752,15 +750,16 @@ get_addresses (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sh); } + /** * Returns where the address is located: LAN or WAN or ... + * * @param sh the scheduling handle * @param addr address * @param addrlen address length * @return location as GNUNET_ATS_Information */ - -const struct GNUNET_ATS_Information +struct GNUNET_ATS_Information GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const struct sockaddr * addr, socklen_t addrlen) { GNUNET_assert (sh != NULL); @@ -807,7 +806,8 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const stru if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) == net4->sin_addr.s_addr) { char * net = GNUNET_strdup (GNUNET_a2s ((const struct sockaddr *) net4, addrlen)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' is in network `%s'\n", + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", + "`%s' is in network `%s'\n", GNUNET_a2s ((const struct sockaddr *)a4, addrlen), net); GNUNET_free (net); @@ -845,33 +845,12 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const stru /* no local network found for this address, default: WAN */ if (type == GNUNET_ATS_NET_UNSPECIFIED) type = GNUNET_ATS_NET_WAN; - -#if VERBOSE - const char * range; - switch (type) { - case GNUNET_ATS_NET_WAN: - range = "WAN"; - break; - case GNUNET_ATS_NET_LAN: - range = "LAN"; - break; - case GNUNET_ATS_NET_LOOPBACK: - range = "LOOPBACK"; - break; - default: - - break; - } - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "`%s' is in network `%s'\n", - GNUNET_a2s ((const struct sockaddr *) addr, addrlen), - range); -#endif - ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); ats.value = htonl (type); return (const struct GNUNET_ATS_Information) ats; } + /** * Initialize the ATS subsystem. * @@ -918,7 +897,7 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) } if (NULL != sh->client) { - GNUNET_CLIENT_disconnect (sh->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; } if (GNUNET_SCHEDULER_NO_TASK != sh->task) @@ -938,6 +917,32 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) sh = NULL; } +/** + * We would like to reset the address suggestion block time for this + * peer + * + * @param sh handle + * @param peer identity of the peer we want to reset + */ +void +GNUNET_ATS_reset_backoff (struct GNUNET_ATS_SchedulingHandle *sh, + const struct GNUNET_PeerIdentity *peer) +{ + struct PendingMessage *p; + struct ResetBackoffMessage *m; + + p = GNUNET_malloc (sizeof (struct PendingMessage) + + sizeof (struct ResetBackoffMessage)); + p->size = sizeof (struct ResetBackoffMessage); + p->is_init = GNUNET_NO; + m = (struct ResetBackoffMessage *) &p[1]; + m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_RESET_BACKOFF); + m->header.size = htons (sizeof (struct ResetBackoffMessage)); + m->reserved = htonl (0); + m->peer = *peer; + GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); + do_transmit (sh); +} /** * We would like to establish a new connection with a peer. ATS @@ -953,6 +958,8 @@ GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh, struct PendingMessage *p; struct RequestAddressMessage *m; + // FIXME: ATS needs to remember this in case of + // a disconnect! p = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct RequestAddressMessage)); p->size = sizeof (struct RequestAddressMessage); @@ -993,6 +1000,7 @@ GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, do_transmit (sh); } + /** * We have updated performance statistics for a given address. Note * that this function can be called for addresses that are currently @@ -1117,10 +1125,10 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, memcpy (pm, address->address, address->address_length); memcpy (&pm[address->address_length], address->transport_name, namelen); GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); - do_transmit (sh); } + /** * A session got destroyed, stop including it as a valid address. * diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c index 7deca0b..aef72f1 100644 --- a/src/ats/gnunet-service-ats.c +++ b/src/ats/gnunet-service-ats.c @@ -39,6 +39,9 @@ */ struct GNUNET_STATISTICS_Handle *GSA_stats; +static struct GNUNET_SERVER_Handle *GSA_server; + + /** * We have received a 'ClientStartMessage' from a client. Find out which * type of client it is and notify the respective subsystem. @@ -54,7 +57,6 @@ handle_ats_start (void *cls, struct GNUNET_SERVER_Client *client, const struct ClientStartMessage *msg = (const struct ClientStartMessage *) message; enum StartFlag flag; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ATS_START"); flag = ntohl (msg->start_flag); switch (flag) @@ -111,6 +113,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GAS_scheduling_done (); GAS_performance_done (); GAS_reservations_done (); + GNUNET_SERVER_disconnect_notify_cancel (GSA_server, &client_disconnect_handler, NULL); if (NULL != GSA_stats) { GNUNET_STATISTICS_destroy (GSA_stats, GNUNET_NO); @@ -150,8 +153,12 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, sizeof (struct ReservationRequestMessage)}, {&GAS_handle_preference_change, NULL, GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE, 0}, + {&GAS_handle_reset_backoff, NULL, + GNUNET_MESSAGE_TYPE_ATS_RESET_BACKOFF, + sizeof (struct ResetBackoffMessage)}, {NULL, NULL, 0, 0} }; + GSA_server = server; GSA_stats = GNUNET_STATISTICS_create ("ats", cfg); GAS_reservations_init (); GAS_performance_init (server); diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index fb9bad0..9bf5ca6 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -37,6 +37,8 @@ #define VERBOSE GNUNET_NO +#define ATS_BLOCKING_DELTA GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100) + enum ATS_Mode { /* @@ -66,6 +68,25 @@ static unsigned int active_addr_count; static int ats_mode; +static int running; + + +static void +send_bw_notification (struct ATS_Address *aa) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New bandwidth for peer %s is %u/%u\n", + GNUNET_i2s (&aa->peer), ntohl (aa->assigned_bw_in.value__), + ntohl (aa->assigned_bw_out.value__)); + GAS_scheduling_transmit_address_suggestion (&aa->peer, aa->plugin, aa->addr, + aa->addr_len, aa->session_id, + aa->ats, aa->ats_count, + aa->assigned_bw_out, + aa->assigned_bw_in); + GAS_reservations_set_bandwidth (&aa->peer, aa->assigned_bw_in); + GAS_performance_notify_clients (&aa->peer, aa->plugin, aa->addr, aa->addr_len, + aa->ats, aa->ats_count, aa->assigned_bw_out, + aa->assigned_bw_in); +} /** * Update a bandwidth assignment for a peer. This trivial method currently @@ -90,18 +111,8 @@ update_bw_simple_it (void *cls, const GNUNET_HashCode * key, void *value) aa->assigned_bw_in.value__ = htonl (wan_quota_in / active_addr_count); aa->assigned_bw_out.value__ = htonl (wan_quota_out / active_addr_count); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New bandwidth for peer %s is %u/%u\n", - GNUNET_i2s (&aa->peer), ntohl (aa->assigned_bw_in.value__), - ntohl (aa->assigned_bw_out.value__)); - GAS_scheduling_transmit_address_suggestion (&aa->peer, aa->plugin, aa->addr, - aa->addr_len, aa->session_id, - aa->ats, aa->ats_count, - aa->assigned_bw_out, - aa->assigned_bw_in); - GAS_reservations_set_bandwidth (&aa->peer, aa->assigned_bw_in); - GAS_performance_notify_clients (&aa->peer, aa->plugin, aa->addr, aa->addr_len, - aa->ats, aa->ats_count, aa->assigned_bw_out, - aa->assigned_bw_in); + send_bw_notification (aa); + return GNUNET_OK; } @@ -159,9 +170,6 @@ create_address (const struct GNUNET_PeerIdentity *peer, memcpy (&aa[1], plugin_addr, plugin_addr_len); aa->plugin = GNUNET_strdup (plugin_name); aa->session_id = session_id; - aa->mlp_information = NULL; - aa->next = NULL; - aa->prev = NULL; return aa; } @@ -332,6 +340,11 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, struct ATS_Address *old; uint32_t i; + if (GNUNET_NO == running) + return; + + GNUNET_assert (NULL != addresses); + aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, @@ -342,11 +355,10 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, aa->ats_count = atsi_count; memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information)); -#if DEBUG_ATS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' %u\n", GNUNET_i2s (peer), session_id); -#endif + /* Get existing address or address with session == 0 */ old = find_address (peer, aa); if (old == NULL) @@ -445,11 +457,11 @@ destroy_by_session_id (void *cls, const GNUNET_HashCode * key, void *value) (aa->addr_len == info->addr_len) && (0 == memcmp (info->addr, aa->addr, aa->addr_len))) { -#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting address for peer `%s': `%s' %u\n", GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id); -#endif + if (GNUNET_YES == destroy_address (aa)) recalculate_assigned_bw (); return GNUNET_OK; @@ -503,6 +515,9 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, { struct ATS_Address *aa; + if (GNUNET_NO == running) + return; + GNUNET_break (0 < strlen (plugin_name)); aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id); @@ -529,6 +544,49 @@ find_address_it (void *cls, const GNUNET_HashCode * key, void *value) struct ATS_Address **ap = cls; struct ATS_Address *aa = (struct ATS_Address *) value; struct ATS_Address *ab = *ap; + struct GNUNET_TIME_Absolute now; + + now = GNUNET_TIME_absolute_get(); + + if (aa->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, aa->blocked_until).abs_value) + { + /* This address is blocked for suggestion */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Address %p blocked for suggestion for %llu ms \n", + aa, + GNUNET_TIME_absolute_get_difference(now, aa->blocked_until).rel_value); + return GNUNET_OK; + } + + aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval, ATS_BLOCKING_DELTA); + aa->blocked_until = GNUNET_TIME_absolute_add (now, aa->block_interval); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Address %p ready for suggestion, block interval now %llu \n", aa, aa->block_interval); + + /* FIXME this is a hack */ + + + if (NULL != ab) + { + if ((0 == strcmp (ab->plugin, "tcp")) && + (0 == strcmp (aa->plugin, "tcp"))) + { + if ((0 != ab->addr_len) && + (0 == aa->addr_len)) + { + /* saved address was an outbound address, but we have an inbound address */ + *ap = aa; + return GNUNET_OK; + } + if (0 == ab->addr_len) + { + /* saved address was an inbound address, so do not overwrite */ + return GNUNET_OK; + } + } + } + /* FIXME end of hack */ if (NULL == ab) { @@ -559,7 +617,7 @@ find_address_it (void *cls, const GNUNET_HashCode * key, void *value) } -void +int GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, uint32_t session_id, int in_use) @@ -573,19 +631,34 @@ GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer, struct ATS_Address *aa; struct ATS_Address *old; + if (GNUNET_NO == running) + return GNUNET_SYSERR; - aa = create_address(peer, plugin_name, plugin_addr, plugin_addr_len, session_id); + aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id); old = find_exact_address (peer, aa); free_address (aa); - GNUNET_assert (old != NULL); - GNUNET_assert (old->used != in_use); + if (NULL == old) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (old->used == in_use) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Address in use called multiple times for peer `%s': %s -> %s \n", + GNUNET_i2s (peer), + (GNUNET_NO == old->used) ? "NO" : "YES", + (GNUNET_NO == in_use) ? "NO" : "YES"); + return GNUNET_SYSERR; + } old->used = in_use; - #if HAVE_LIBGLPK if (ats_mode == MLP) GAS_mlp_address_update (mlp, addresses, old); #endif + return GNUNET_OK; } @@ -608,7 +681,7 @@ void request_address_mlp (const struct GNUNET_PeerIdentity *peer) if (aa == NULL) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer)); return; } @@ -617,18 +690,7 @@ void request_address_mlp (const struct GNUNET_PeerIdentity *peer) aa->active = GNUNET_YES; active_addr_count++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New bandwidth for peer %s is %u/%u\n", - GNUNET_i2s (&aa->peer), ntohl (aa->assigned_bw_in.value__), - ntohl (aa->assigned_bw_out.value__)); - GAS_scheduling_transmit_address_suggestion (&aa->peer, aa->plugin, aa->addr, - aa->addr_len, aa->session_id, - aa->ats, aa->ats_count, - aa->assigned_bw_out, - aa->assigned_bw_in); - GAS_reservations_set_bandwidth (&aa->peer, aa->assigned_bw_in); - GAS_performance_notify_clients (&aa->peer, aa->plugin, aa->addr, aa->addr_len, - aa->ats, aa->ats_count, aa->assigned_bw_out, - aa->assigned_bw_in); + send_bw_notification (aa); } else { @@ -652,11 +714,14 @@ void request_address_simple (const struct GNUNET_PeerIdentity *peer) &find_address_it, &aa); if (aa == NULL) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer)); return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, + "Suggesting address %p for peer `%s'\n", aa, GNUNET_i2s (peer)); + if (aa->active == GNUNET_NO) { aa->active = GNUNET_YES; @@ -681,6 +746,9 @@ void request_address_simple (const struct GNUNET_PeerIdentity *peer) void GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) { + if (GNUNET_NO == running) + return; + if (ats_mode == SIMPLE) { request_address_simple (peer); @@ -692,6 +760,30 @@ GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) } +static int +reset_address_it (void *cls, const GNUNET_HashCode * key, void *value) +{ + struct ATS_Address *aa = value; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Resetting interval for peer `%s' address %p from %llu to 0\n", GNUNET_i2s (&aa->peer), aa, aa->block_interval); + + aa->blocked_until = GNUNET_TIME_UNIT_ZERO_ABS; + aa->block_interval = GNUNET_TIME_UNIT_ZERO; + return GNUNET_OK; +} + +void +GAS_addresses_handle_backoff_reset (const struct GNUNET_PeerIdentity *peer) +{ + GNUNET_break (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_get_multiple (addresses, + &peer->hashPubKey, + &reset_address_it, + NULL)); +} + + + // FIXME: this function should likely end up in the LP-subsystem and // not with 'addresses' in the future... void @@ -699,6 +791,8 @@ GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind, float score) { + if (GNUNET_NO == running) + return; #if HAVE_LIBGLPK if (ats_mode == MLP) GAS_mlp_address_change_preference (mlp, peer, kind, score); @@ -717,42 +811,86 @@ void GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_STATISTICS_Handle *stats) { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_size (cfg, "ats", - "WAN_QUOTA_IN", - &wan_quota_in)); - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_size (cfg, "ats", - "WAN_QUOTA_OUT", - &wan_quota_out)); - - switch (GNUNET_CONFIGURATION_get_value_yesno (cfg, "ats", "MLP")) - { - /* MLP = YES */ - case GNUNET_YES: + int mode; + + char *quota_wan_in_str; + char *quota_wan_out_str; + + running = GNUNET_NO; + + addresses = GNUNET_CONTAINER_multihashmap_create (128); + GNUNET_assert (NULL != addresses); + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", "a_wan_in_str)) + { + if (0 == strcmp(quota_wan_in_str, "unlimited") || + (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_wan_in_str, &wan_quota_in))) + wan_quota_in = (UINT32_MAX) /10; + + GNUNET_free (quota_wan_in_str); + quota_wan_in_str = NULL; + } + else + { + wan_quota_in = (UINT32_MAX) /10; + } + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", "a_wan_out_str)) + { + if (0 == strcmp(quota_wan_out_str, "unlimited") || + (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_wan_out_str, &wan_quota_out))) + wan_quota_out = (UINT32_MAX) /10; + + GNUNET_free (quota_wan_out_str); + quota_wan_out_str = NULL; + } + else + { + wan_quota_out = (UINT32_MAX) /10; + } + + mode = GNUNET_CONFIGURATION_get_value_yesno (cfg, "ats", "MLP"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MLP mode %u", mode); + switch (mode) + { + /* MLP = YES */ + case GNUNET_YES: #if HAVE_LIBGLPK - ats_mode = MLP; - /* Init the MLP solver with default values */ - mlp = GAS_mlp_init (cfg, stats, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); - break; + ats_mode = MLP; + /* Init the MLP solver with default values */ + mlp = GAS_mlp_init (cfg, stats, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); + if (NULL == mlp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode\n"); + GNUNET_STATISTICS_update (GSA_stats, "MLP mode enabled", 0, GNUNET_NO); + break; + } + else + { + GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 1, GNUNET_NO); + break; + } #else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode"); - ats_mode = SIMPLE; - break; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode"); + GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO); + ats_mode = SIMPLE; + break; #endif - /* MLP = NO */ - case GNUNET_NO: - ats_mode = SIMPLE; - break; - /* No configuration value */ - case GNUNET_SYSERR: - ats_mode = SIMPLE; - break; - default: - break; + /* MLP = NO */ + case GNUNET_NO: + GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO); + ats_mode = SIMPLE; + break; + /* No configuration value */ + case GNUNET_SYSERR: + GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO); + ats_mode = SIMPLE; + break; + default: + break; } - - addresses = GNUNET_CONTAINER_multihashmap_create (128); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS started with %s mode\n", (SIMPLE == ats_mode) ? "SIMPLE" : "MLP"); + running = GNUNET_YES; } @@ -777,6 +915,9 @@ free_address_it (void *cls, const GNUNET_HashCode * key, void *value) void GAS_addresses_destroy_all () { + if (GNUNET_NO == running) + return; + if (addresses != NULL) GNUNET_CONTAINER_multihashmap_iterate (addresses, &free_address_it, NULL); GNUNET_assert (active_addr_count == 0); @@ -790,6 +931,7 @@ void GAS_addresses_done () { GAS_addresses_destroy_all (); + running = GNUNET_NO; GNUNET_CONTAINER_multihashmap_destroy (addresses); addresses = NULL; #if HAVE_LIBGLPK diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index 33ff586..fe07563 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -74,6 +74,16 @@ struct ATS_Address struct GNUNET_BANDWIDTH_Value32NBO assigned_bw_out; + /** + * Blocking interval + */ + struct GNUNET_TIME_Relative block_interval; + + /** + * Time when address can be suggested again + */ + struct GNUNET_TIME_Absolute blocked_until; + /** * Is this the active address for this peer? */ @@ -102,10 +112,13 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, void GAS_addresses_done (void); +void +GAS_addresses_handle_backoff_reset (const struct GNUNET_PeerIdentity *peer); + /** * This address is now used or not used anymore */ -void +int GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, uint32_t session_id, int in_use); diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c index 61aa733..8bfa010 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.c +++ b/src/ats/gnunet-service-ats_addresses_mlp.c @@ -505,7 +505,9 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON * c 10) obey network specific quota */ + /* Row for c4) minimum connection */ int min = mlp->n_min; + /* Number of minimum connections is min(|Peers|, n_min) */ if (mlp->n_min > mlp->c_p) min = mlp->c_p; @@ -565,6 +567,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON mlp->ci++; struct ATS_Peer * peer = mlp->peer_head; + /* For all peers */ while (peer != NULL) { struct ATS_Address *addr = peer->head; @@ -590,16 +593,15 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON /* Set -r */ ia[mlp->ci] = peer->r_c9; ja[mlp->ci] = mlp->c_r; - ar[mlp->ci] = -1; + ar[mlp->ci] = -peer->f; mlp->ci++; #endif - + /* For all addresses of this peer */ while (addr != NULL) { mlpi = (struct MLP_information *) addr->mlp_information; /* coefficient for c 2) */ - ia[mlp->ci] = peer->r_c2; ja[mlp->ci] = mlpi->c_n; ar[mlp->ci] = 1; @@ -625,8 +627,6 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON } /* c 7) For all quality metrics */ - - for (c = 0; c < mlp->m_q; c++) { struct ATS_Peer *tp; @@ -640,7 +640,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON glp_set_row_name (mlp->prob, mlp->r_q[c], name); GNUNET_free (name); /* Set row bound == 0 */ - glp_set_row_bnds (mlp->prob, mlp->r_q[c], GLP_LO, 0.0, 0.0); + glp_set_row_bnds (mlp->prob, mlp->r_q[c], GLP_FX, 0.0, 0.0); ia[mlp->ci] = mlp->r_q[c]; ja[mlp->ci] = mlp->c_q[c]; @@ -657,7 +657,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON ia[mlp->ci] = mlp->r_q[c]; ja[mlp->ci] = mlpi->c_b; - ar[mlp->ci] = tp->f * value; + ar[mlp->ci] = tp->f_q[c] * value; mlp->ci++; } } @@ -747,7 +747,6 @@ mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHas /* Adding invariant columns */ /* Diversity d column */ - col = glp_add_cols (mlp->prob, 1); mlp->c_d = col; /* Column name */ @@ -758,7 +757,6 @@ mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHas glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); /* Utilization u column */ - col = glp_add_cols (mlp->prob, 1); mlp->c_u = col; /* Column name */ @@ -806,14 +804,16 @@ mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHas return res; } + /** * Solves the LP problem * * @param mlp the MLP Handle + * @param s_ctx context to return results * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ static int -mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp) +mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) { int res; struct GNUNET_TIME_Relative duration; @@ -867,13 +867,13 @@ lp_solv: duration = GNUNET_TIME_absolute_get_difference (start, end); mlp->lp_solved++; mlp->lp_total_duration =+ duration.rel_value; + s_ctx->lp_duration = duration; GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO); - GNUNET_STATISTICS_set (mlp->stats,"# LP execution time", duration.rel_value, GNUNET_NO); - GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average", + GNUNET_STATISTICS_set (mlp->stats,"# LP execution time (ms)", duration.rel_value, GNUNET_NO); + GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average (ms)", mlp->lp_total_duration / mlp->lp_solved, GNUNET_NO); - /* Analyze problem status */ res = glp_get_status (mlp->prob); switch (res) { @@ -903,10 +903,11 @@ lp_solv: * Solves the MLP problem * * @param mlp the MLP Handle + * @param s_ctx context to return results * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ int -mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp) +mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) { int res; struct GNUNET_TIME_Relative duration; @@ -943,10 +944,11 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp) duration = GNUNET_TIME_absolute_get_difference (start, end); mlp->mlp_solved++; mlp->mlp_total_duration =+ duration.rel_value; + s_ctx->mlp_duration = duration; GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO); - GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time", duration.rel_value, GNUNET_NO); - GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average", + GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time (ms)", duration.rel_value, GNUNET_NO); + GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average (ms)", mlp->mlp_total_duration / mlp->mlp_solved, GNUNET_NO); /* Analyze problem status */ @@ -970,23 +972,24 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp) return GNUNET_OK; } -int GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp); +int GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx); + static void mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GAS_MLP_Handle *mlp = cls; + struct GAS_MLP_SolutionContext ctx; mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduled problem solving\n"); if (mlp->addr_in_problem != 0) - GAS_mlp_solve_problem(mlp); + GAS_mlp_solve_problem(mlp, &ctx); } @@ -994,17 +997,34 @@ mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * Solves the MLP problem * * @param mlp the MLP Handle + * @param ctx solution context * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ int -GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp) +GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx) { int res; - mlp->last_execution = GNUNET_TIME_absolute_get (); + /* Check if solving is already running */ + if (GNUNET_YES == mlp->semaphore) + { + if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel(mlp->mlp_task); + mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK; + } + mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp); + return GNUNET_SYSERR; + } + mlp->semaphore = GNUNET_YES; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solving\n"); + mlp->last_execution = GNUNET_TIME_absolute_get (); + ctx->lp_result = GNUNET_SYSERR; + ctx->mlp_result = GNUNET_SYSERR; + ctx->lp_duration = GNUNET_TIME_UNIT_FOREVER_REL; + ctx->mlp_duration = GNUNET_TIME_UNIT_FOREVER_REL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve LP problem\n"); #if WRITE_MLP char * name; static int i; @@ -1014,7 +1034,14 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp) GNUNET_free (name); # endif - res = mlp_solve_lp_problem (mlp); + res = mlp_solve_lp_problem (mlp, ctx); + ctx->lp_result = res; + if (res != GNUNET_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "LP Problem solving failed\n"); + mlp->semaphore = GNUNET_NO; + return GNUNET_SYSERR; + } #if WRITE_MLP GNUNET_asprintf(&name, "problem_%i_lp_solution", i); @@ -1022,31 +1049,24 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp) GNUNET_free (name); # endif + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve MLP problem\n"); + res = mlp_solve_mlp_problem (mlp, ctx); + ctx->mlp_result = res; if (res != GNUNET_OK) { - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "LP Problem solving failed\n"); - + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP Problem solving failed\n"); + mlp->semaphore = GNUNET_NO; return GNUNET_SYSERR; } - - res = mlp_solve_mlp_problem (mlp); - #if WRITE_MLP GNUNET_asprintf(&name, "problem_%i_mlp_solution", i); glp_print_mip (mlp->prob, name); GNUNET_free (name); # endif - if (res != GNUNET_OK) - { - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MLP Problem solving failed\n"); - return GNUNET_SYSERR; - } - - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solved\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solved %s (LP duration %llu / MLP duration %llu)\n", + (GNUNET_OK == res) ? "successfully" : "failed", ctx->lp_duration.rel_value, ctx->mlp_duration.rel_value); /* Process result */ struct ATS_Peer *p = NULL; struct ATS_Address *a = NULL; @@ -1082,6 +1102,7 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp) mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK; } mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp); + mlp->semaphore = GNUNET_NO; return res; } @@ -1105,20 +1126,46 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, double D; double R; double U; - long long unsigned int tmp; + unsigned long long tmp; unsigned int b_min; unsigned int n_min; struct GNUNET_TIME_Relative i_exec; int c; + char * quota_out_str; + char * quota_in_str; /* Init GLPK environment */ - GNUNET_assert (glp_init_env() == 0); + int res = glp_init_env(); + switch (res) { + case 0: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n", + "initialization successful"); + break; + case 1: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n", + "environment is already initialized"); + break; + case 2: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n", + "initialization failed (insufficient memory)"); + GNUNET_free(mlp); + return NULL; + break; + case 3: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n", + "initialization failed (unsupported programming model)"); + GNUNET_free(mlp); + return NULL; + break; + default: + break; + } /* Create initial MLP problem */ mlp->prob = glp_create_prob(); GNUNET_assert (mlp->prob != NULL); - mlp->BIG_M = (double) (UINT32_MAX) /10; + mlp->BIG_M = (double) BIG_M_VALUE; /* Get diversity coefficient from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", @@ -1231,37 +1278,57 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, if ((entry_in == NULL) || (entry_out == NULL)) continue; - if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", entry_out, "a_out)) + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str)) + { + if (0 == strcmp(quota_out_str, BIG_M_STRING) || + (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, "a_out))) + quota_out = mlp->BIG_M; + + GNUNET_free (quota_out_str); + quota_out_str = NULL; + } + else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c]) + { + quota_out = mlp->BIG_M; + } + else { quota_out = mlp->BIG_M; } - if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", entry_in, "a_in)) + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str)) + { + if (0 == strcmp(quota_in_str, BIG_M_STRING) || + (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, "a_in))) + quota_in = mlp->BIG_M; + + GNUNET_free (quota_in_str); + quota_in_str = NULL; + } + else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c]) { quota_in = mlp->BIG_M; } + else + { + quota_in = mlp->BIG_M; + } + /* Check if defined quota could make problem unsolvable */ - if ((n_min * b_min) > quota_out) + if (((n_min * b_min) > quota_out) && (GNUNET_ATS_NET_UNSPECIFIED != quotas[c])) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inconsistent quota configuration value `%s': " \ - "outbound quota (%u Bps) too small for combination of minimum connections and minimum bandwidth per peer (%u * %u Bps = %u)\n", entry_out, quota_out, n_min, b_min, n_min * b_min); - unsigned int default_min = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__); - if ((quota_out / n_min) > default_min) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Reducing minimum bandwidth per peer to %u Bps\n", - (quota_out / n_min)); - b_min = (quota_out / n_min); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Reducing minimum bandwidth per peer to %u Bps and minimum connections to %u \n", - default_min, (quota_out / default_min)); - b_min = default_min; - n_min = (quota_out / default_min); - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inconsistent quota configuration value `%s': " + "outbound quota (%u Bps) too small for combination of minimum connections and minimum bandwidth per peer (%u * %u Bps = %u)\n", entry_out, quota_out, n_min, b_min, n_min * b_min); + + GAS_mlp_done(mlp); + mlp = NULL; + return NULL; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' quota %llu and `%s' quota %llu\n", entry_out, quota_out, entry_in, quota_in); + GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_out, quota_out, GNUNET_NO); + GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_in, quota_in, GNUNET_NO); mlp->quota_out[c] = quota_out; mlp->quota_in[c] = quota_in; } @@ -1302,7 +1369,7 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, #endif mlp->control_param_mlp.tm_lim = max_duration.rel_value; - mlp->last_execution = GNUNET_TIME_absolute_get_forever(); + mlp->last_execution = GNUNET_TIME_UNIT_FOREVER_ABS; mlp->co_D = D; mlp->co_R = R; @@ -1310,7 +1377,7 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, mlp->b_min = b_min; mlp->n_min = n_min; mlp->m_q = GNUNET_ATS_QualityPropertiesCount; - + mlp->semaphore = GNUNET_NO; return mlp; } @@ -1320,12 +1387,15 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer `%s'\n", GNUNET_i2s (&address->peer)); + GNUNET_assert (NULL != address); + GNUNET_assert (NULL != address->mlp_information); + GNUNET_assert (NULL != address->ats); + struct MLP_information *mlpi = address->mlp_information; struct GNUNET_ATS_Information *ats = address->ats; GNUNET_assert (mlpi != NULL); int c; - for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) { int index = mlp_lookup_ats(address, mlp->q[c]); @@ -1374,7 +1444,7 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address) c3 ++; } } - if (c3 > 0) + if ((c3 > 0) && (avg > 0)) /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/ mlpi->q_averaged[c] = (double) c3 / avg; else @@ -1399,7 +1469,7 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address) c3 ++; } } - if (c3 > 0) + if ((c3 > 0) && (avg > 0)) /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/ mlpi->q_averaged[c] = (double) c3 / avg; else @@ -1487,8 +1557,9 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult { int new; struct MLP_information *mlpi; + struct GAS_MLP_SolutionContext ctx; - GNUNET_STATISTICS_update (mlp->stats,"# LP address updates", 1, GNUNET_NO); + GNUNET_STATISTICS_update (mlp->stats, "# MLP address updates", 1, GNUNET_NO); /* We add a new address */ if (address->mlp_information == NULL) @@ -1514,6 +1585,7 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult address->mlp_information = mlpi; mlp->addr_in_problem ++; + GNUNET_STATISTICS_update (mlp->stats, "# addresses in MLP", 1, GNUNET_NO); /* Check for and add peer */ struct ATS_Peer *peer = mlp_find_peer (mlp, &address->peer); @@ -1540,6 +1612,7 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address); GNUNET_CONTAINER_DLL_insert (mlp->peer_head, mlp->peer_tail, peer); mlp->c_p ++; + GNUNET_STATISTICS_update (mlp->stats, "# peers in MLP", 1, GNUNET_NO); } else { @@ -1549,7 +1622,6 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address); } - update_quality (mlp, address); } else @@ -1570,7 +1642,7 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult mlp->presolver_required = GNUNET_YES; } if (mlp->auto_solve == GNUNET_YES) - GAS_mlp_solve_problem (mlp); + GAS_mlp_solve_problem (mlp, &ctx); } /** @@ -1587,6 +1659,7 @@ void GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) { GNUNET_STATISTICS_update (mlp->stats,"# LP address deletions", 1, GNUNET_NO); + struct GAS_MLP_SolutionContext ctx; /* Free resources */ if (address->mlp_information != NULL) @@ -1595,6 +1668,7 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult address->mlp_information = NULL; mlp->addr_in_problem --; + GNUNET_STATISTICS_update (mlp->stats, "# addresses in MLP", -1, GNUNET_NO); } /* Remove from peer list */ @@ -1613,6 +1687,7 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult GNUNET_CONTAINER_DLL_remove (mlp->peer_head, mlp->peer_tail, head); GNUNET_free (head); mlp->c_p --; + GNUNET_STATISTICS_update (mlp->stats, "# peers in MLP", -1, GNUNET_NO); } /* Update problem */ @@ -1626,7 +1701,7 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult /* Recalculate */ mlp->presolver_required = GNUNET_YES; if (mlp->auto_solve == GNUNET_YES) - GAS_mlp_solve_problem (mlp); + GAS_mlp_solve_problem (mlp, &ctx); } } @@ -1705,7 +1780,7 @@ void GAS_mlp_done (struct GAS_MLP_Handle *mlp) { struct ATS_Peer * peer; - struct ATS_Peer * tmp; + struct ATS_Address *addr; GNUNET_assert (mlp != NULL); @@ -1719,10 +1794,16 @@ GAS_mlp_done (struct GAS_MLP_Handle *mlp) peer = mlp->peer_head; while (peer != NULL) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up peer `%s'\n", GNUNET_i2s (&peer->id)); GNUNET_CONTAINER_DLL_remove(mlp->peer_head, mlp->peer_tail, peer); - tmp = peer->next; + for (addr = peer->head; NULL != addr; addr = peer->head) + { + GNUNET_CONTAINER_DLL_remove(peer->head, peer->tail, addr); + GNUNET_free (addr->mlp_information); + addr->mlp_information = NULL; + } GNUNET_free (peer); - peer = tmp; + peer = mlp->peer_head; } mlp_delete_problem (mlp); diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h index 8f60a85..d37eea7 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.h +++ b/src/ats/gnunet-service-ats_addresses_mlp.h @@ -36,6 +36,9 @@ #define DEBUG_MLP GNUNET_EXTRA_LOGGING +#define BIG_M_VALUE (UINT32_MAX) /10 +#define BIG_M_STRING "unlimited" + #define MLP_AVERAGING_QUEUE_LENGTH 3 #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) @@ -70,6 +73,14 @@ struct ATS_PreferedAddress struct ATS_Address *address; }; +struct GAS_MLP_SolutionContext +{ + int lp_result; + int mlp_result; + struct GNUNET_TIME_Relative lp_duration; + struct GNUNET_TIME_Relative mlp_duration; +}; + /** * MLP Handle */ @@ -128,6 +139,8 @@ struct GAS_MLP_Handle */ int auto_solve; + int semaphore; + /* state information */ /** @@ -318,10 +331,11 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, * Solves the MLP problem on demand * * @param mlp the MLP Handle + * @param ctx solution context * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ int -GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp); +GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx); /** diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c index b127656..7ab8e9a 100644 --- a/src/ats/gnunet-service-ats_performance.c +++ b/src/ats/gnunet-service-ats_performance.c @@ -166,7 +166,7 @@ GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer, sizeof (struct PeerInformationMessage) + atsi_count * sizeof (struct GNUNET_ATS_Information) + plugin_addr_len + plugin_name_length; - char buf[msize]; + char buf[msize] GNUNET_ALIGN; struct GNUNET_ATS_Information *atsp; char *addrp; diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c index 72b72cd..0b66ac5 100644 --- a/src/ats/gnunet-service-ats_scheduling.c +++ b/src/ats/gnunet-service-ats_scheduling.c @@ -59,7 +59,6 @@ GAS_scheduling_add_client (struct GNUNET_SERVER_Client *client) } my_client = client; GNUNET_SERVER_notification_context_add (nc, client); - GNUNET_SERVER_client_keep (client); return GNUNET_OK; } @@ -76,7 +75,6 @@ GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client) if (my_client != client) return; GAS_addresses_destroy_all (); - GNUNET_SERVER_client_drop (client); my_client = NULL; } @@ -114,7 +112,7 @@ GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity sizeof (struct AddressSuggestionMessage) + atsi_count * sizeof (struct GNUNET_ATS_Information) + plugin_addr_len + plugin_name_length; - char buf[msize]; + char buf[msize] GNUNET_ALIGN; struct GNUNET_ATS_Information *atsp; char *addrp; @@ -200,6 +198,30 @@ GAS_handle_request_address_cancel (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); } +/** + * Handle 'reset backoff' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ +void +GAS_handle_reset_backoff (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct ResetBackoffMessage *msg = + (const struct ResetBackoffMessage *) message; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", + "RESET_BACKOFF"); + GNUNET_STATISTICS_update (GSA_stats, "# backoff reset requests received", 1, + GNUNET_NO); + GNUNET_break (0 == ntohl (msg->reserved)); + GAS_addresses_handle_backoff_reset (&msg->peer); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + /** * Handle 'address update' messages from clients. @@ -274,6 +296,7 @@ GAS_handle_address_in_use (void *cls, struct GNUNET_SERVER_Client *client, const struct AddressUseMessage *m; const char *address; const char *plugin_name; + int res; uint16_t address_length; uint16_t plugin_name_length; @@ -309,10 +332,21 @@ GAS_handle_address_in_use (void *cls, struct GNUNET_SERVER_Client *client, } in_use = ntohs (m->in_use); - GAS_addresses_in_use (&m->peer, plugin_name, address, address_length, - ntohl (m->session_id), in_use); + res = GAS_addresses_in_use (&m->peer, + plugin_name, + address, + address_length, + ntohl (m->session_id), + in_use); + + if (res == GNUNET_OK) + GNUNET_SERVER_receive_done (client, GNUNET_OK); + else + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + } - GNUNET_SERVER_receive_done (client, GNUNET_OK); } /** @@ -401,8 +435,13 @@ GAS_scheduling_init (struct GNUNET_SERVER_Handle *server) void GAS_scheduling_done () { + if (NULL != my_client) + { + my_client = NULL; + } GNUNET_SERVER_notification_context_destroy (nc); nc = NULL; + } diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h index 45fca2f..08a7f1b 100644 --- a/src/ats/gnunet-service-ats_scheduling.h +++ b/src/ats/gnunet-service-ats_scheduling.h @@ -50,6 +50,19 @@ void GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client); +/** + * Handle 'reset backoff' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ +void +GAS_handle_reset_backoff (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message); + + /** * Transmit the given address suggestion and bandwidth update to all scheduling * clients. diff --git a/src/ats/perf_ats_mlp.c b/src/ats/perf_ats_mlp.c index a15e4b4..b9ee5e4 100644 --- a/src/ats/perf_ats_mlp.c +++ b/src/ats/perf_ats_mlp.c @@ -18,8 +18,8 @@ Boston, MA 02111-1307, USA. */ /** - * @file ats/test_ats_mlp.c - * @brief test for the MLP solver + * @file ats/perf_ats_mlp + * @brief performance test for the MLP solver * @author Christian Grothoff * @author Matthias Wachs @@ -29,110 +29,344 @@ #include "gnunet_statistics_service.h" #include "gnunet-service-ats_addresses_mlp.h" -#define VERBOSE GNUNET_YES -#define VERBOSE_ARM GNUNET_NO - #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) #define MLP_MAX_ITERATIONS INT_MAX +#define DEF_PEERS 10 +#define DEF_ADDRESSES_PER_PEER 5 +#define DEF_ATS_VALUES 2 +#define DEF_ATS_MAX_DELAY 30 +#define DEF_ATS_MAX_DISTANCE 3 + +static unsigned int peers; +static unsigned int addresses; +static unsigned int numeric; +static unsigned int update_percentage; + +static int start; +static int end; + +struct ATS_Peer *p; +struct ATS_Address *a; static int ret; -struct GNUNET_STATISTICS_Handle * stats; +static struct GNUNET_CONTAINER_MultiHashMap * amap; -struct GNUNET_CONTAINER_MultiHashMap * addresses; +static struct GAS_MLP_Handle *mlp; -struct GAS_MLP_Handle *mlp; -static void -check (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) + + +GNUNET_SCHEDULER_TaskIdentifier shutdown_task; + +struct PeerContext { -#if !HAVE_LIBGLPK - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!"); - ret = 1; - return; -#endif - struct ATS_Address addr[10]; + struct GNUNET_PeerIdentity id; - stats = GNUNET_STATISTICS_create("ats", cfg); + struct Address *addr; +}; - addresses = GNUNET_CONTAINER_multihashmap_create (10); +struct Address +{ + char *plugin; + size_t plugin_len; - GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &addr[0].peer.hashPubKey); - addr[0].mlp_information = NULL; - addr[0].next = NULL; - addr[0].prev = NULL; - addr[0].plugin = strdup ("dummy"); + void *addr; + size_t addr_len; - addr[1].peer = addr[0].peer; - addr[1].mlp_information = NULL; - addr[1].next = NULL; - addr[1].prev = NULL; - addr[1].plugin = strdup ("dummy2"); + struct GNUNET_ATS_Information *ats; + int ats_count; - GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + void *session; +}; - mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); +void +do_shutdown (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + unsigned int ca; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown\n"); + + if (NULL != mlp) + { + GAS_mlp_done (mlp); + mlp = NULL; + } + + if (NULL != a) + { + for (ca=0; ca < (peers * addresses); ca++) + { + GNUNET_free (a[ca].plugin); + GNUNET_free (a[ca].ats); + } + } + + if (NULL != amap) + GNUNET_CONTAINER_multihashmap_destroy(amap); + GNUNET_free_non_null (a); + GNUNET_free_non_null (p); - /* Add a new address */ -#if 0 - GAS_mlp_address_update (mlp, addresses, &addr[0]); +} - GNUNET_assert (mlp != NULL); - GNUNET_assert (mlp->addr_in_problem == 1); +static void +update_addresses (struct ATS_Address * a, unsigned int addrs, unsigned int percentage) +{ + if (percentage == 0) + return; + + unsigned int ua = (addrs) * ((float) percentage / 100); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updating %u of %u addresses per peer\n", ua, addrs); + + unsigned int updated[addrs]; + unsigned int u_types[DEF_ATS_VALUES]; + unsigned int updates = 0; + unsigned int u_type = 0; + unsigned int u_val = 0; + unsigned int cur = 0; + + u_types[0] = 0; + u_types[1] = 0; + + for (cur = 0; cur < addrs; cur ++) + { + updated[cur] = 0; + } + cur = 0; + + while (updates < ua) + { + cur = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, addrs); + if (0 == updated[cur]) + { + u_type = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_VALUES); + switch (u_type) { + case 0: + do + { + u_val = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DELAY); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating DELAY from %u to %u\n",a[cur].ats[u_type].value, u_val); + } + while (a[cur].ats[u_type].value == u_val); + break; + case 1: + do + { + u_val = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DISTANCE); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating DISTANCE from %u to %u\n",a[cur].ats[u_type].value, u_val); + } + while (a[cur].ats[u_type].value == u_val); + break; + default: + GNUNET_break (0); + break; + } + u_types[u_type]++; + + a[cur].ats[u_type].value = u_val; + updated[cur] = 1; + GAS_mlp_address_update(mlp, amap, &a[cur]); + updates++; + } + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updated %u delay and %u distance values\n", u_types[0], u_types[1]); - /* Update an new address */ - GAS_mlp_address_update (mlp, addresses, &addr[0]); - GNUNET_assert (mlp->addr_in_problem == 1); +} - /* Add a second address for same peer */ - GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[1], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - GAS_mlp_address_update (mlp, addresses, &addr[1]); - GNUNET_assert (mlp->addr_in_problem == 2); - /* Delete an address */ - GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]); - GAS_mlp_address_delete (mlp, addresses, &addr[0]); - GAS_mlp_address_delete (mlp, addresses, &addr[1]); +static void +check (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + unsigned int c = 0; + unsigned int c2 = 0; + unsigned int ca = 0; + int update = GNUNET_NO; + int range = GNUNET_NO; + int res; + +#if !HAVE_LIBGLPK + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!"); + ret = 1; + return; #endif - GAS_mlp_done (mlp); - GNUNET_free (addr[0].plugin); - GNUNET_free (addr[1].plugin); - GNUNET_CONTAINER_multihashmap_destroy (addresses); - GNUNET_STATISTICS_destroy(stats, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up %u peers with %u addresses per peer\n", peers, addresses); + + mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); + if (NULL == mlp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to init MLP\n"); + ret = 1; + if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) + GNUNET_SCHEDULER_cancel(shutdown_task); + shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + } + + if (peers == 0) + peers = DEF_PEERS; + if (addresses == 0) + addresses = DEF_ADDRESSES_PER_PEER; + + p = GNUNET_malloc (peers * sizeof (struct ATS_Peer)); + a = GNUNET_malloc (peers * addresses * sizeof (struct ATS_Address)); + + amap = GNUNET_CONTAINER_multihashmap_create(addresses * peers); + + mlp->auto_solve = GNUNET_NO; + if (start == 0) + start = 0; + if (end == 0) + end = -1; + if ((start != -1) && (end != -1)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Solving problem starting from %u to %u\n", start , end); + range = GNUNET_YES; + } + else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Solving problem for %u peers\n", peers); + + if ((update_percentage >= 0) && (update_percentage <= 100)) + { + update = GNUNET_YES; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Benchmarking with existing presolution and %u%% updated addresses\n", update_percentage); + } + else if ((update_percentage > 100) && (update_percentage != UINT_MAX)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Invalid percentage: %u\n", update_percentage); + ret = 1; + return; + } + + for (c=0; c < peers; c++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up peer %u\n", c); + GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_NONCE, &p[c].id.hashPubKey); + + for (c2=0; c2 < addresses; c2++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up address %u for peer %u\n", c2, c); + /* Setting required information */ + a[ca].mlp_information = NULL; + a[ca].prev = NULL; + a[ca].next = NULL; + + /* Setting address */ + a[ca].peer = p[c].id; + a[ca].plugin = GNUNET_strdup("test"); + a[ca].atsp_network_type = GNUNET_ATS_NET_LOOPBACK; + + a[ca].ats = GNUNET_malloc (DEF_ATS_VALUES * sizeof (struct GNUNET_ATS_Information)); + a[ca].ats[0].type = GNUNET_ATS_QUALITY_NET_DELAY; + a[ca].ats[0].value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DELAY); + a[ca].ats[1].type = GNUNET_ATS_QUALITY_NET_DISTANCE; + a[ca].ats[1].value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DISTANCE); + a[ca].ats_count = 2; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up address %u\n", ca); + GNUNET_CONTAINER_multihashmap_put (amap, &a[ca].peer.hashPubKey, &a[ca], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GAS_mlp_address_update(mlp, amap, &a[ca]); + ca++; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Problem contains %u peers and %u adresses\n", mlp->c_p, mlp->addr_in_problem); + + if (((GNUNET_YES == range) && (((start >= 0) && ((c+1) >= start)) && (c <= end))) || ((c+1) == peers)) + { + GNUNET_assert ((c+1) == mlp->c_p); + GNUNET_assert ((c+1) * addresses == mlp->addr_in_problem); + + /* Solving the problem */ + struct GAS_MLP_SolutionContext ctx; + + res = GAS_mlp_solve_problem(mlp, &ctx); + + if (GNUNET_NO == update) + { + if (GNUNET_OK == res) + { + GNUNET_assert (GNUNET_OK == ctx.lp_result); + GNUNET_assert (GNUNET_OK == ctx.mlp_result); + if (GNUNET_YES == numeric) + printf ("%u;%u;%llu;%llu\n",mlp->c_p, mlp->addr_in_problem, (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value); + else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Problem solved for %u peers with %u address successfully (LP: %llu ms / MLP: %llu ms)\n", + mlp->c_p, mlp->addr_in_problem, ctx.lp_duration.rel_value, ctx.mlp_duration.rel_value); + } + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Solving problem with %u peers and %u addresses failed\n", c, c2); + } + else + { + struct GAS_MLP_SolutionContext uctx; + /* Update addresses */ + update_addresses (a, (c+1) * c2, update_percentage); + + /* Solve again */ + res = GAS_mlp_solve_problem(mlp, &uctx); + + if (GNUNET_OK == res) + { + GNUNET_assert (GNUNET_OK == uctx.lp_result); + GNUNET_assert (GNUNET_OK == uctx.mlp_result); + if (GNUNET_YES == numeric) + printf ("%u;%u;%llu;%llu;%llu;%llu\n",mlp->c_p, mlp->addr_in_problem, + (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value, + (unsigned long long) uctx.lp_duration.rel_value, (unsigned long long) uctx.mlp_duration.rel_value); + else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updated problem solved for %u peers with %u address successfully (Initial: LP/MLP: %llu/%llu ms, Update: %llu/%llu ms)\n", + mlp->c_p, mlp->addr_in_problem, + (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value, + (unsigned long long) uctx.lp_duration.rel_value, (unsigned long long) uctx.mlp_duration.rel_value); + } + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Solving updated problem with %u peers and %u addresses failed\n", c, c2); + } + } + } + + if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) + GNUNET_SCHEDULER_cancel(shutdown_task); + shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - ret = 0; - return; } int main (int argc, char *argv[]) { - - static char *const argv2[] = { "test_ats_mlp", - "-c", - "test_ats_api.conf", -#if VERBOSE - "-L", "DEBUG", -#else - "-L", "WARNING", -#endif - NULL - }; - + /* Init invalid */ + update_percentage = UINT_MAX; static struct GNUNET_GETOPT_CommandLineOption options[] = { + {'a', "addresses", NULL, + gettext_noop ("addresses per peer"), 1, + &GNUNET_GETOPT_set_uint, &addresses}, + {'p', "peers", NULL, + gettext_noop ("peers"), 1, + &GNUNET_GETOPT_set_uint, &peers}, + {'n', "numeric", NULL, + gettext_noop ("numeric output only"), 0, + &GNUNET_GETOPT_set_one, &numeric}, + {'e', "end", NULL, + gettext_noop ("end solving problem"), 1, + &GNUNET_GETOPT_set_uint, &end}, + {'s', "start", NULL, + gettext_noop ("start solving problem"), 1, + &GNUNET_GETOPT_set_uint, &start}, + {'u', "update", NULL, + gettext_noop ("benchmark with existing solution (address updates)"), 1, + &GNUNET_GETOPT_set_uint, &update_percentage}, GNUNET_GETOPT_OPTION_END }; - GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, - "test_ats_mlp", "nohelp", options, + + GNUNET_PROGRAM_run (argc, argv, + "perf_ats_mlp", "nohelp", options, &check, NULL); return ret; } -/* end of file test_ats_api_bandwidth_consumption.c */ +/* end of file perf_ats_mlp.c */ diff --git a/src/ats/test_ats_api.conf b/src/ats/test_ats_api.conf index fa379c9..efd7fc9 100644 --- a/src/ats/test_ats_api.conf +++ b/src/ats/test_ats_api.conf @@ -9,8 +9,6 @@ UNIXPATH = /tmp/test-ats-scheduling-arm.sock [ats] #DEBUG = YES #PREFIX = valgrind --leak-check=full -#WAN_QUOTA_OUT = 4294967295 -#WAN_QUOTA_IN = 4294967295 AUTOSTART = YES PORT = 12002 HOSTNAME = localhost @@ -21,4 +19,30 @@ ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; UNIXPATH = /tmp/test-ats-scheduling-ats.sock UNIX_MATCH_UID = YES -UNIX_MATCH_GID = YES \ No newline at end of file +UNIX_MATCH_GID = YES + +# Enable MLP mode (default: NO) +MLP = NO +# Network specific inbound/outbound quotas +# LOOPBACK +LOOPBACK_QUOTA_IN = unlimited +LOOPBACK_QUOTA_OUT = unlimited +# LAN +LAN_QUOTA_IN = unlimited +LAN_QUOTA_OUT = unlimited +# WAN +WAN_QUOTA_IN = 64 KiB +WAN_QUOTA_OUT = 64 KiB +# WLAN +WLAN_QUOTA_IN = 1 MiB +WLAN_QUOTA_OUT = 1 MiB + +# ATS extended options +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +DUMP_OVERWRITE = NO +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 diff --git a/src/ats/test_ats_api_reset_backoff.c b/src/ats/test_ats_api_reset_backoff.c new file mode 100644 index 0000000..38c18e1 --- /dev/null +++ b/src/ats/test_ats_api_reset_backoff.c @@ -0,0 +1,308 @@ +/* + This file is part of GNUnet. + (C) 2010,2011 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file ats/test_ats_api_reset_backoff.c + * @brief test case for block reset api + * @author Christian Grothoff + * @author Matthias Wachs + */ +#include "platform.h" +#include "gnunet_ats_service.h" +#include "ats.h" + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) +#define ATS_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 90) + +static GNUNET_SCHEDULER_TaskIdentifier die_task; + +static GNUNET_SCHEDULER_TaskIdentifier suggest_timeout_task; + +static struct GNUNET_ATS_SchedulingHandle *ats; + +struct GNUNET_OS_Process *arm_proc; + +static int ret; + +struct Address +{ + char *plugin; + size_t plugin_len; + + void *addr; + size_t addr_len; + + struct GNUNET_ATS_Information *ats; + int ats_count; + + void *session; +}; + +struct PeerContext +{ + struct GNUNET_PeerIdentity id; + + struct Address *addr; +}; + +struct GNUNET_HELLO_Address hello_addr; +struct Address address; +struct PeerContext peer; +struct GNUNET_ATS_Information atsi[2]; + +static void +stop_arm () +{ + if (0 != GNUNET_OS_process_kill (arm_proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm_proc); + GNUNET_OS_process_destroy (arm_proc); + arm_proc = NULL; +} + + +static void +end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + die_task = GNUNET_SCHEDULER_NO_TASK; + + if (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (suggest_timeout_task); + suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (ats != NULL) + { + GNUNET_ATS_scheduling_done (ats); + ats = NULL; + } + + ret = GNUNET_SYSERR; + + stop_arm (); +} + + +static void +end () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n"); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (suggest_timeout_task); + suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_ATS_scheduling_done (ats); + + ret = 0; + + stop_arm (); +} + + +static void +suggest_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting address for peer timed out\n"); + + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + + die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); +} + +static void +address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *a, + struct Session *session, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + const struct GNUNET_ATS_Information *atsi, + uint32_t ats_count) +{ + static int suggestions; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS suggests address `%s'\n", + GNUNET_i2s (&a->peer)); + + if (0 != memcmp (&a->peer, &peer.id, + sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + if (0 != strcmp (a->transport_name, address.plugin)) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + if (a->address_length != address.addr_len) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + if (0 != memcmp (a->address, address.addr, + a->address_length)) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + if (session != address.session) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + suggestions ++; + + if (2 == suggestions) + { + GNUNET_SCHEDULER_add_now(&end, NULL); + return; + } + + if (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (suggest_timeout_task); + suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + suggest_timeout_task = GNUNET_SCHEDULER_add_delayed(ATS_TIMEOUT, &suggest_timeout, NULL); +} + +void +start_arm (const char *cfgname) +{ + arm_proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", + "-c", cfgname, NULL); +} + +static void +check (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + ret = GNUNET_SYSERR; + + die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); + start_arm (cfgfile); + + ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL); + + if (ats == NULL) + { + ret = GNUNET_SYSERR; + end (); + return; + } + + /* set up peer */ + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, + &peer.id.hashPubKey); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n", GNUNET_i2s (&peer.id)); + + address.plugin = "test"; + address.session = NULL; + address.addr = GNUNET_strdup ("test"); + address.addr_len = 4; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding address\n"); + + hello_addr.peer = peer.id; + hello_addr.transport_name = address.plugin; + hello_addr.address = address.addr; + hello_addr.address_length = address.addr_len; + GNUNET_ATS_address_update (ats, &hello_addr, address.session, NULL, 0); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting address for peer `%s'\n", + GNUNET_i2s (&peer.id)); + /* Increase block timout far beyond ATS_TIMEOUT */ + GNUNET_ATS_suggest_address (ats, &peer.id); + + GNUNET_ATS_reset_backoff(ats, &peer.id); + GNUNET_ATS_suggest_address (ats, &peer.id); +} + +int +main (int argc, char *argv[]) +{ + static char *const argv2[] = { "test_ats_api_scheduling", + "-c", + "test_ats_api.conf", + "-L", "WARNING", + NULL + }; + + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test_ats_api_scheduling", "nohelp", options, &check, + NULL); + + + return ret; +} +/* end of file test_ats_api_reset_backoff.c */ diff --git a/src/ats/test_ats_api_scheduling.c b/src/ats/test_ats_api_scheduling.c index 892186c..c9d2206 100644 --- a/src/ats/test_ats_api_scheduling.c +++ b/src/ats/test_ats_api_scheduling.c @@ -34,10 +34,6 @@ #include "gnunet_ats_service.h" #include "ats.h" -#define VERBOSE GNUNET_NO - -#define VERBOSE_ARM GNUNET_NO - #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) static GNUNET_SCHEDULER_TaskIdentifier die_task; @@ -81,7 +77,7 @@ stop_arm () if (0 != GNUNET_OS_process_kill (arm_proc, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (arm_proc); - GNUNET_OS_process_close (arm_proc); + GNUNET_OS_process_destroy (arm_proc); arm_proc = NULL; } @@ -158,9 +154,6 @@ start_arm (const char *cfgname) arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE_ARM - "-L", "DEBUG", -#endif "-c", cfgname, NULL); } @@ -241,11 +234,7 @@ main (int argc, char *argv[]) static char *const argv2[] = { "test_ats_api_scheduling", "-c", "test_ats_api.conf", -#if VERBOSE - "-L", "DEBUG", -#else "-L", "WARNING", -#endif NULL }; diff --git a/src/ats/test_ats_mlp.c b/src/ats/test_ats_mlp.c index 14df2d0..c467210 100644 --- a/src/ats/test_ats_mlp.c +++ b/src/ats/test_ats_mlp.c @@ -30,9 +30,6 @@ #include "gnunet_ats_service.h" #include "gnunet-service-ats_addresses_mlp.h" -#define VERBOSE GNUNET_YES -#define VERBOSE_ARM GNUNET_NO - #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) #define MLP_MAX_ITERATIONS INT_MAX @@ -52,7 +49,7 @@ create_address (struct ATS_Address *addr, char * plugin, int ats_count, struct G addr->mlp_information = NULL; addr->next = NULL; addr->prev = NULL; - addr->plugin = strdup (plugin); + addr->plugin = GNUNET_strdup (plugin); addr->ats_count = ats_count; addr->ats = ats; } @@ -75,6 +72,7 @@ check (void *cls, char *const *args, const char *cfgfile, #endif struct ATS_Address addr[10]; struct ATS_PreferedAddress *res[10]; + struct GAS_MLP_SolutionContext ctx; stats = GNUNET_STATISTICS_create("ats", cfg); @@ -140,7 +138,9 @@ check (void *cls, char *const *args, const char *cfgfile, GAS_mlp_address_update (mlp, addresses, &addr[2]); GNUNET_assert (mlp->addr_in_problem == 3); - GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp)); + GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx)); + GNUNET_assert (GNUNET_OK == ctx.lp_result); + GNUNET_assert (GNUNET_OK == ctx.mlp_result); res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out); @@ -176,11 +176,7 @@ main (int argc, char *argv[]) static char *const argv2[] = { "test_ats_mlp", "-c", "test_ats_api.conf", -#if VERBOSE - "-L", "DEBUG", -#else "-L", "WARNING", -#endif NULL }; diff --git a/src/ats/test_ats_mlp_averaging.c b/src/ats/test_ats_mlp_averaging.c index f7b7b1d..97e9aa7 100644 --- a/src/ats/test_ats_mlp_averaging.c +++ b/src/ats/test_ats_mlp_averaging.c @@ -30,9 +30,6 @@ #include "gnunet_ats_service.h" #include "gnunet-service-ats_addresses_mlp.h" -#define VERBOSE GNUNET_YES -#define VERBOSE_ARM GNUNET_NO - #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) #define MLP_MAX_ITERATIONS INT_MAX @@ -52,7 +49,7 @@ create_address (struct ATS_Address *addr, char * plugin, int ats_count, struct G addr->mlp_information = NULL; addr->next = NULL; addr->prev = NULL; - addr->plugin = strdup (plugin); + addr->plugin = GNUNET_strdup (plugin); addr->ats_count = ats_count; addr->ats = ats; } @@ -76,6 +73,7 @@ check (void *cls, char *const *args, const char *cfgfile, struct ATS_Address addr[10]; struct ATS_PreferedAddress *res[10]; struct MLP_information *mlpi; + struct GAS_MLP_SolutionContext ctx; stats = GNUNET_STATISTICS_create("ats", cfg); @@ -129,7 +127,9 @@ check (void *cls, char *const *args, const char *cfgfile, GNUNET_assert (mlp->addr_in_problem == 1); - GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp)); + GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx)); + GNUNET_assert (GNUNET_OK == ctx.lp_result); + GNUNET_assert (GNUNET_OK == ctx.mlp_result); res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out); @@ -159,11 +159,7 @@ main (int argc, char *argv[]) static char *const argv2[] = { "test_ats_mlp", "-c", "test_ats_api.conf", -#if VERBOSE - "-L", "DEBUG", -#else "-L", "WARNING", -#endif NULL }; diff --git a/src/block/Makefile.in b/src/block/Makefile.in index b494dfa..37701e8 100644 --- a/src/block/Makefile.in +++ b/src/block/Makefile.in @@ -200,6 +200,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -233,6 +234,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/block/block.c b/src/block/block.c index 7c447f0..51dab78 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -102,7 +102,7 @@ add_plugin (void *cls, const char *library_name, void *lib_ret) struct GNUNET_BLOCK_PluginFunctions *api = lib_ret; struct Plugin *plugin; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading block plugin `%s'\n"), + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Loading block plugin `%s'\n"), library_name); plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->api = api; diff --git a/src/block/plugin_block_test.c b/src/block/plugin_block_test.c index 08d3096..81e80e3 100644 --- a/src/block/plugin_block_test.c +++ b/src/block/plugin_block_test.c @@ -66,8 +66,11 @@ block_plugin_test_evaluate (void *cls, enum GNUNET_BLOCK_Type type, if (type != GNUNET_BLOCK_TYPE_TEST) return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; if (xquery_size != 0) + { + GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; - if (reply_block_size == 0) + } + if (NULL == reply_block) return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; if (NULL != bf) diff --git a/src/chat/Makefile.in b/src/chat/Makefile.in index 96c673c..fe310ce 100644 --- a/src/chat/Makefile.in +++ b/src/chat/Makefile.in @@ -272,6 +272,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -305,6 +306,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/chat/chat.c b/src/chat/chat.c index ae73b96..72c49a0 100644 --- a/src/chat/chat.c +++ b/src/chat/chat.c @@ -599,7 +599,7 @@ GNUNET_CHAT_leave_room (struct GNUNET_CHAT_Room *chat_room) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Leaving the room '%s'\n", chat_room->room_name); #endif - GNUNET_CLIENT_disconnect (chat_room->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (chat_room->client); GNUNET_free (chat_room->room_name); GNUNET_CONTAINER_meta_data_destroy (chat_room->member_info); GNUNET_CRYPTO_rsa_key_free (chat_room->my_private_key); diff --git a/src/chat/gnunet-chat.c b/src/chat/gnunet-chat.c index 4abc58c..7b11c0d 100644 --- a/src/chat/gnunet-chat.c +++ b/src/chat/gnunet-chat.c @@ -44,13 +44,14 @@ static struct GNUNET_CONTAINER_MetaData *meta; static struct GNUNET_CHAT_Room *room; -static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task = - GNUNET_SCHEDULER_NO_TASK; +static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task; + +typedef int (*ActionFunction)(const char *argumetns, const void *xtra); struct ChatCommand { const char *command; - int (*Action) (const char *arguments, const void *xtra); + ActionFunction Action; const char *helptext; }; @@ -114,14 +115,27 @@ receive_cb (void *cls, struct GNUNET_CHAT_Room *room, const char *message, struct GNUNET_TIME_Absolute timestamp, enum GNUNET_CHAT_MsgOptions options) { + char *non_unique_nick; char *nick; + int nick_is_a_dup; char *time; const char *fmt; - if (NULL != sender) - nick = GNUNET_PSEUDONYM_id_to_name (cfg, sender); - else + if (NULL == sender) nick = GNUNET_strdup (_("anonymous")); + else + { + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + sender, NULL, NULL, &non_unique_nick, &nick_is_a_dup) + || (nick_is_a_dup == GNUNET_YES)) + { + GNUNET_free (non_unique_nick); + non_unique_nick = GNUNET_strdup (_("anonymous")); + } + nick = GNUNET_PSEUDONYM_name_uniquify (cfg, sender, non_unique_nick, NULL); + GNUNET_free (non_unique_nick); + } + fmt = NULL; switch ((int) options) { @@ -188,9 +202,20 @@ confirmation_cb (void *cls, struct GNUNET_CHAT_Room *room, const GNUNET_HashCode * receiver) { char *nick; + char *unique_nick; + int nick_is_a_dup; - nick = GNUNET_PSEUDONYM_id_to_name (cfg, receiver); - FPRINTF (stdout, _("'%s' acknowledged message #%d\n"), nick, orig_seq_number); + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + receiver, NULL, NULL, &nick, &nick_is_a_dup) + || (nick_is_a_dup == GNUNET_YES)) + { + GNUNET_free (nick); + nick = GNUNET_strdup (_("anonymous")); + } + unique_nick = GNUNET_PSEUDONYM_name_uniquify (cfg, receiver, nick, NULL); + GNUNET_free (nick); + FPRINTF (stdout, _("'%s' acknowledged message #%d\n"), unique_nick, orig_seq_number); + GNUNET_free (unique_nick); return GNUNET_OK; } @@ -211,6 +236,8 @@ member_list_cb (void *cls, const struct GNUNET_CONTAINER_MetaData *member_info, enum GNUNET_CHAT_MsgOptions options) { char *nick; + char *non_unique_nick; + int nick_is_a_dup; GNUNET_HashCode id; struct UserList *pos; struct UserList *prev; @@ -218,7 +245,16 @@ member_list_cb (void *cls, const struct GNUNET_CONTAINER_MetaData *member_info, GNUNET_CRYPTO_hash (member_id, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &id); - nick = GNUNET_PSEUDONYM_id_to_name (cfg, &id); + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &id, NULL, NULL, &non_unique_nick, &nick_is_a_dup) + || (nick_is_a_dup == GNUNET_YES)) + { + GNUNET_free (non_unique_nick); + non_unique_nick = GNUNET_strdup (_("anonymous")); + } + nick = GNUNET_PSEUDONYM_name_uniquify (cfg, &id, non_unique_nick, NULL); + GNUNET_free (non_unique_nick); + FPRINTF (stdout, member_info != NULL ? _("`%s' entered the room\n") : _("`%s' left the room\n"), @@ -267,6 +303,7 @@ static int do_join (const char *arg, const void *xtra) { char *my_name; + int my_name_is_a_dup; GNUNET_HashCode me; if (arg[0] == '#') @@ -284,7 +321,16 @@ do_join (const char *arg, const void *xtra) FPRINTF (stdout, "%s", _("Could not change username\n")); return GNUNET_SYSERR; } - my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); + if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &me, NULL, NULL, &my_name, &my_name_is_a_dup)) || + (my_name_is_a_dup == GNUNET_YES)) + { + GNUNET_free (my_name); + my_name = GNUNET_strdup (_("anonymous")); + } + /* Don't uniquify our own name - other people will have a different + * suffix for our own name anyway. + */ FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name, my_name); GNUNET_free (my_name); @@ -296,6 +342,7 @@ static int do_nick (const char *msg, const void *xtra) { char *my_name; + int my_name_is_a_dup; GNUNET_HashCode me; GNUNET_CHAT_leave_room (room); @@ -316,7 +363,13 @@ do_nick (const char *msg, const void *xtra) FPRINTF (stdout, "%s", _("Could not change username\n")); return GNUNET_SYSERR; } - my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); + if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &me, NULL, NULL, &my_name, &my_name_is_a_dup)) || + (my_name_is_a_dup == GNUNET_YES)) + { + GNUNET_free (my_name); + my_name = GNUNET_strdup (_("anonymous")); + } FPRINTF (stdout, _("Changed username to `%s'\n"), my_name); GNUNET_free (my_name); return GNUNET_OK; @@ -327,6 +380,8 @@ static int do_names (const char *msg, const void *xtra) { char *name; + char *unique_name; + int name_is_a_dup; struct UserList *pos; GNUNET_HashCode pid; @@ -337,9 +392,17 @@ do_names (const char *msg, const void *xtra) GNUNET_CRYPTO_hash (&pos->pkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pid); - name = GNUNET_PSEUDONYM_id_to_name (cfg, &pid); - FPRINTF (stdout, "`%s' ", name); + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &pid, NULL, NULL, &name, &name_is_a_dup) + || (name_is_a_dup == GNUNET_YES)) + { + GNUNET_free (name); + name = GNUNET_strdup (_("anonymous")); + } + unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &pid, name, NULL); GNUNET_free (name); + FPRINTF (stdout, "`%s' ", unique_name); + GNUNET_free (unique_name); pos = pos->next; } FPRINTF (stdout, "%s", "\n"); @@ -376,7 +439,9 @@ do_send_pm (const char *msg, const void *xtra) msg += strlen (user) + 1; if (GNUNET_OK != GNUNET_PSEUDONYM_name_to_id (cfg, user, &uid)) { - FPRINTF (stderr, _("Unknown user `%s'\n"), user); + FPRINTF (stderr, + _("Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n"), + user); GNUNET_free (user); return GNUNET_OK; } @@ -598,6 +663,7 @@ run (void *cls, char *const *args, const char *cfgfile, { GNUNET_HashCode me; char *my_name; + int my_name_is_a_dup; cfg = c; /* check arguments */ @@ -626,7 +692,13 @@ run (void *cls, char *const *args, const char *cfgfile, ret = -1; return; } - my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); + if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &me, NULL, NULL, &my_name, &my_name_is_a_dup)) || + (my_name_is_a_dup == GNUNET_YES)) + { + GNUNET_free (my_name); + my_name = GNUNET_strdup (_("anonymous")); + } FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name, my_name); GNUNET_free (my_name); diff --git a/src/chat/test_chat.c b/src/chat/test_chat.c index fec5db0..2e8272d 100644 --- a/src/chat/test_chat.c +++ b/src/chat/test_chat.c @@ -140,7 +140,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); diff --git a/src/chat/test_chat_private.c b/src/chat/test_chat_private.c index cbc9065..8b61392 100644 --- a/src/chat/test_chat_private.c +++ b/src/chat/test_chat_private.c @@ -154,7 +154,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); diff --git a/src/core/Makefile.am b/src/core/Makefile.am index ad9bddc..e95cbcf 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -20,7 +20,8 @@ lib_LTLIBRARIES = \ libgnunetcore_la_SOURCES = \ core_api.c core.h \ - core_api_iterate_peers.c + core_api_iterate_peers.c \ + core_api_is_connected.c libgnunetcore_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) $(XLIB) @@ -31,7 +32,7 @@ libgnunetcore_la_LDFLAGS = \ bin_PROGRAMS = \ gnunet-service-core \ - gnunet-core-list-connections + gnunet-core gnunet_service_core_SOURCES = \ gnunet-service-core.c gnunet-service-core.h \ @@ -49,14 +50,12 @@ gnunet_service_core_LDADD = \ $(GN_LIBINTL) -lz -gnunet_core_list_connections_SOURCES = \ - gnunet-core-list-connections.c -gnunet_core_list_connections_LDADD = \ +gnunet_core_SOURCES = \ + gnunet-core.c +gnunet_core_LDADD = \ $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la -gnunet_core_list_connections_DEPENDENCIES = \ +gnunet_core_DEPENDENCIES = \ libgnunetcore.la check_PROGRAMS = \ diff --git a/src/core/Makefile.in b/src/core/Makefile.in index 42177b4..f181a54 100644 --- a/src/core/Makefile.in +++ b/src/core/Makefile.in @@ -37,8 +37,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -bin_PROGRAMS = gnunet-service-core$(EXEEXT) \ - gnunet-core-list-connections$(EXEEXT) +bin_PROGRAMS = gnunet-service-core$(EXEEXT) gnunet-core$(EXEEXT) check_PROGRAMS = test_core_api_start_only$(EXEEXT) \ test_core_api$(EXEEXT) test_core_api_reliability$(EXEEXT) \ test_core_quota_compliance_symmetric$(EXEEXT) \ @@ -95,7 +94,8 @@ am__DEPENDENCIES_1 = libgnunetcore_la_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_libgnunetcore_la_OBJECTS = core_api.lo core_api_iterate_peers.lo +am_libgnunetcore_la_OBJECTS = core_api.lo core_api_iterate_peers.lo \ + core_api_is_connected.lo libgnunetcore_la_OBJECTS = $(am_libgnunetcore_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) @@ -105,10 +105,8 @@ libgnunetcore_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_CFLAGS) $(CFLAGS) $(libgnunetcore_la_LDFLAGS) $(LDFLAGS) \ -o $@ PROGRAMS = $(bin_PROGRAMS) -am_gnunet_core_list_connections_OBJECTS = \ - gnunet-core-list-connections.$(OBJEXT) -gnunet_core_list_connections_OBJECTS = \ - $(am_gnunet_core_list_connections_OBJECTS) +am_gnunet_core_OBJECTS = gnunet-core.$(OBJEXT) +gnunet_core_OBJECTS = $(am_gnunet_core_OBJECTS) am_gnunet_service_core_OBJECTS = gnunet-service-core.$(OBJEXT) \ gnunet-service-core_clients.$(OBJEXT) \ gnunet-service-core_neighbours.$(OBJEXT) \ @@ -203,8 +201,7 @@ am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libgnunetcore_la_SOURCES) \ - $(gnunet_core_list_connections_SOURCES) \ +SOURCES = $(libgnunetcore_la_SOURCES) $(gnunet_core_SOURCES) \ $(gnunet_service_core_SOURCES) $(test_core_api_SOURCES) \ $(test_core_api_reliability_SOURCES) \ $(test_core_api_send_to_self_SOURCES) \ @@ -212,8 +209,7 @@ SOURCES = $(libgnunetcore_la_SOURCES) \ $(test_core_quota_compliance_asymmetric_recv_limited_SOURCES) \ $(test_core_quota_compliance_asymmetric_send_limited_SOURCES) \ $(test_core_quota_compliance_symmetric_SOURCES) -DIST_SOURCES = $(libgnunetcore_la_SOURCES) \ - $(gnunet_core_list_connections_SOURCES) \ +DIST_SOURCES = $(libgnunetcore_la_SOURCES) $(gnunet_core_SOURCES) \ $(gnunet_service_core_SOURCES) $(test_core_api_SOURCES) \ $(test_core_api_reliability_SOURCES) \ $(test_core_api_send_to_self_SOURCES) \ @@ -282,6 +278,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -315,6 +312,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -444,7 +442,8 @@ lib_LTLIBRARIES = \ libgnunetcore_la_SOURCES = \ core_api.c core.h \ - core_api_iterate_peers.c + core_api_iterate_peers.c \ + core_api_is_connected.c libgnunetcore_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -470,16 +469,14 @@ gnunet_service_core_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) -lz -gnunet_core_list_connections_SOURCES = \ - gnunet-core-list-connections.c +gnunet_core_SOURCES = \ + gnunet-core.c -gnunet_core_list_connections_LDADD = \ +gnunet_core_LDADD = \ $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la -gnunet_core_list_connections_DEPENDENCIES = \ +gnunet_core_DEPENDENCIES = \ libgnunetcore.la @ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) @@ -675,9 +672,9 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -gnunet-core-list-connections$(EXEEXT): $(gnunet_core_list_connections_OBJECTS) $(gnunet_core_list_connections_DEPENDENCIES) - @rm -f gnunet-core-list-connections$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(gnunet_core_list_connections_OBJECTS) $(gnunet_core_list_connections_LDADD) $(LIBS) +gnunet-core$(EXEEXT): $(gnunet_core_OBJECTS) $(gnunet_core_DEPENDENCIES) + @rm -f gnunet-core$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_core_OBJECTS) $(gnunet_core_LDADD) $(LIBS) gnunet-service-core$(EXEEXT): $(gnunet_service_core_OBJECTS) $(gnunet_service_core_DEPENDENCIES) @rm -f gnunet-service-core$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_service_core_OBJECTS) $(gnunet_service_core_LDADD) $(LIBS) @@ -710,8 +707,9 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_api_is_connected.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_api_iterate_peers.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-core-list-connections.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-core.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-core.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-core_clients.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-core_kx.Po@am__quote@ diff --git a/src/core/core.conf.in b/src/core/core.conf.in index 84e2df9..61ac84e 100644 --- a/src/core/core.conf.in +++ b/src/core/core.conf.in @@ -1,6 +1,6 @@ [core] AUTOSTART = YES -@UNIXONLY@ PORT = 2092 +@JAVAPORT@PORT = 2092 HOSTNAME = localhost HOME = $SERVICEHOME CONFIG = $DEFAULTCONFIG diff --git a/src/core/core.h b/src/core/core.h index 4942ad0..03e328c 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -112,7 +112,6 @@ struct ConnectNotifyMessage /** * Number of ATS key-value pairs that follow this struct - * (excluding the 0-terminator). */ uint32_t ats_count GNUNET_PACKED; @@ -222,12 +221,11 @@ struct NotifyTrafficMessage */ struct GNUNET_PeerIdentity peer; - /** - * First of the ATS information blocks (we must have at least - * one due to the 0-termination requirement). + /* Followed by ATS information blocks: + * struct GNUNET_ATS_Information ats[ats_count] */ - struct GNUNET_ATS_Information ats; + /* Followed by payload (message or just header), variable size */ }; @@ -332,7 +330,7 @@ struct SendMessage struct GNUNET_TIME_AbsoluteNBO deadline; /** - * Identity of the receiver or sender. + * Identity of the intended receiver. */ struct GNUNET_PeerIdentity peer; @@ -349,32 +347,6 @@ struct SendMessage }; -/** - * Client asking core to connect to a particular target. There is no - * response from the core to this type of request (however, if an - * actual connection is created or destroyed, be it because of this - * type request or not, the core generally needs to notify the - * clients). - */ -struct ConnectMessage -{ - /** - * Header with type GNUNET_MESSAGE_TYPE_REQUEST_CONNECT or - * GNUNET_MESSAGE_TYPE_REQUEST_DISCONNECT. - */ - struct GNUNET_MessageHeader header; - - /** - * For alignment. - */ - uint32_t reserved GNUNET_PACKED; - - /** - * Identity of the other peer. - */ - struct GNUNET_PeerIdentity peer; - -}; GNUNET_NETWORK_STRUCT_END #endif /* end of core.h */ diff --git a/src/core/core_api.c b/src/core/core_api.c index 66df134..526dc9f 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c @@ -367,9 +367,7 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_CORE_Handle *h = cls; h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CORE service after delay\n"); -#endif reconnect (h); } @@ -450,7 +448,7 @@ reconnect_later (struct GNUNET_CORE_Handle *h) } if (h->client != NULL) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } h->currently_down = GNUNET_YES; @@ -546,11 +544,9 @@ request_next_transmission (struct PeerRecord *pr) smr->smr_id = htons (th->smr_id = pr->smr_id_gen++); GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, h->control_pending_tail, cm); -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding SEND REQUEST for peer `%s' to message queue\n", GNUNET_i2s (&pr->peer)); -#endif trigger_next_request (h, GNUNET_NO); } @@ -580,10 +576,15 @@ transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * us from the 'ready' list */ GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr); } -#if DEBUG_CORE + if (NULL != th->cm) + { + /* we're currently in the control queue, remove */ + GNUNET_CONTAINER_DLL_remove (h->control_pending_head, + h->control_pending_tail, th->cm); + GNUNET_free (th->cm); + } LOG (GNUNET_ERROR_TYPE_DEBUG, "Signalling timeout of request for transmission to CORE service\n"); -#endif request_next_transmission (pr); GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL)); GNUNET_free (th); @@ -592,6 +593,11 @@ transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) /** * Transmit the next message to the core service. + * + * @param cls closure with the 'struct GNUNET_CORE_Handle' + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf */ static size_t transmit_message (void *cls, size_t size, void *buf) @@ -609,10 +615,8 @@ transmit_message (void *cls, size_t size, void *buf) h->cth = NULL; if (buf == NULL) { -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed, initiating reconnect\n"); -#endif reconnect_later (h); return 0; } @@ -626,11 +630,9 @@ transmit_message (void *cls, size_t size, void *buf) trigger_next_request (h, GNUNET_NO); return 0; } -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting control message with %u bytes of type %u to core.\n", (unsigned int) msize, (unsigned int) ntohs (hdr->type)); -#endif memcpy (buf, hdr, msize); GNUNET_CONTAINER_DLL_remove (h->control_pending_head, h->control_pending_tail, cm); @@ -660,11 +662,9 @@ transmit_message (void *cls, size_t size, void *buf) GNUNET_SCHEDULER_cancel (pr->timeout_task); pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; } -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting SEND request to `%s' with %u bytes.\n", GNUNET_i2s (&pr->peer), (unsigned int) th->msize); -#endif sm = (struct SendMessage *) buf; sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND); sm->priority = htonl (th->priority); @@ -676,28 +676,22 @@ transmit_message (void *cls, size_t size, void *buf) th->get_message (th->get_message_cls, size - sizeof (struct SendMessage), &sm[1]); -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting SEND request to `%s' yielded %u bytes.\n", GNUNET_i2s (&pr->peer), ret); -#endif GNUNET_free (th); if (0 == ret) { -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Size of clients message to peer %s is 0!\n", GNUNET_i2s (&pr->peer)); -#endif /* client decided to send nothing! */ request_next_transmission (pr); return 0; } -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Produced SEND message to core with %u bytes payload\n", (unsigned int) ret); -#endif GNUNET_assert (ret >= sizeof (struct GNUNET_MessageHeader)); if (ret + sizeof (struct SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) { @@ -729,17 +723,13 @@ trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down) if ((GNUNET_YES == h->currently_down) && (ignore_currently_down == GNUNET_NO)) { -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Core connection down, not processing queue\n"); -#endif return; } if (NULL != h->cth) { -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Request pending, not processing queue\n"); -#endif return; } if (h->control_pending_head != NULL) @@ -751,10 +741,8 @@ trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down) h->ready_peer_head->pending_head->msize + sizeof (struct SendMessage); else { -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Request queue empty, not processing queue\n"); -#endif return; /* no pending message */ } h->cth = @@ -791,7 +779,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) uint16_t et; uint32_t ats_count; - if (msg == NULL) + if (NULL == msg) { LOG (GNUNET_ERROR_TYPE_INFO, _ @@ -800,11 +788,9 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) return; } msize = ntohs (msg->size); -#if DEBUG_CORE > 2 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing message of type %u and size %u from core service\n", ntohs (msg->type), msize); -#endif switch (ntohs (msg->type)) { case GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY: @@ -828,22 +814,18 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) { /* mark so we don't call init on reconnect */ h->init = NULL; -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to core service of peer `%s'.\n", GNUNET_i2s (&h->me)); -#endif init (h->cls, h, &h->me); } else { -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Successfully reconnected to core service.\n"); -#endif } /* fake 'connect to self' */ pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &h->me.hashPubKey); - GNUNET_assert (pr == NULL); + GNUNET_assert (NULL == pr); pr = GNUNET_malloc (sizeof (struct PeerRecord)); pr->peer = h->me; pr->ch = h; @@ -871,11 +853,9 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) reconnect_later (h); return; } -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received notification about connection from `%s'.\n", GNUNET_i2s (&cnm->peer)); -#endif if (0 == memcmp (&h->me, &cnm->peer, sizeof (struct GNUNET_PeerIdentity))) { /* connect to self!? */ @@ -883,7 +863,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) return; } pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &cnm->peer.hashPubKey); - if (pr != NULL) + if (NULL != pr) { GNUNET_break (0); reconnect_later (h); @@ -915,13 +895,11 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) return; } GNUNET_break (0 == ntohl (dnm->reserved)); -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received notification about disconnect from `%s'.\n", GNUNET_i2s (&dnm->peer)); -#endif pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &dnm->peer.hashPubKey); - if (pr == NULL) + if (NULL == pr) { GNUNET_break (0); reconnect_later (h); @@ -941,31 +919,21 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) return; } ntm = (const struct NotifyTrafficMessage *) msg; - ats_count = ntohl (ntm->ats_count); if ((msize < sizeof (struct NotifyTrafficMessage) + ats_count * sizeof (struct GNUNET_ATS_Information) + - sizeof (struct GNUNET_MessageHeader)) || - (GNUNET_ATS_ARRAY_TERMINATOR != ntohl ((&ntm->ats)[ats_count].type))) + sizeof (struct GNUNET_MessageHeader)) ) { GNUNET_break (0); reconnect_later (h); return; } - em = (const struct GNUNET_MessageHeader *) &(&ntm->ats)[ats_count + 1]; -#if DEBUG_CORE + ats = (const struct GNUNET_ATS_Information*) &ntm[1]; + em = (const struct GNUNET_MessageHeader *) &ats[ats_count]; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u and size %u from peer `%4s'\n", ntohs (em->type), ntohs (em->size), GNUNET_i2s (&ntm->peer)); -#endif - pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &ntm->peer.hashPubKey); - if (pr == NULL) - { - GNUNET_break (0); - reconnect_later (h); - return; - } if ((GNUNET_NO == h->inbound_hdr_only) && (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage) + @@ -989,8 +957,15 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break_op (0); continue; } + pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &ntm->peer.hashPubKey); + if (NULL == pr) + { + GNUNET_break (0); + reconnect_later (h); + return; + } if (GNUNET_OK != - h->handlers[hpos].callback (h->cls, &ntm->peer, em, &ntm->ats, + h->handlers[hpos].callback (h->cls, &ntm->peer, em, ats, ats_count)) { /* error in processing, do not process other messages! */ @@ -998,7 +973,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) } } if (NULL != h->inbound_notify) - h->inbound_notify (h->cls, &ntm->peer, em, &ntm->ats, ats_count); + h->inbound_notify (h->cls, &ntm->peer, em, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND: if (msize < sizeof (struct NotifyTrafficMessage)) @@ -1008,36 +983,21 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) return; } ntm = (const struct NotifyTrafficMessage *) msg; - if (0 == memcmp (&h->me, &ntm->peer, sizeof (struct GNUNET_PeerIdentity))) - { - /* self-change!? */ - GNUNET_break (0); - return; - } ats_count = ntohl (ntm->ats_count); if ((msize < sizeof (struct NotifyTrafficMessage) + ats_count * sizeof (struct GNUNET_ATS_Information) + - sizeof (struct GNUNET_MessageHeader)) || - (GNUNET_ATS_ARRAY_TERMINATOR != ntohl ((&ntm->ats)[ats_count].type))) - { - GNUNET_break (0); - reconnect_later (h); - return; - } - em = (const struct GNUNET_MessageHeader *) &(&ntm->ats)[ats_count + 1]; - pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &ntm->peer.hashPubKey); - if (pr == NULL) + sizeof (struct GNUNET_MessageHeader)) ) { GNUNET_break (0); reconnect_later (h); return; } -#if DEBUG_CORE + ats = (const struct GNUNET_ATS_Information*) &ntm[1]; + em = (const struct GNUNET_MessageHeader *) &ats[ats_count]; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received notification about transmission to `%s'.\n", GNUNET_i2s (&ntm->peer)); -#endif if ((GNUNET_NO == h->outbound_hdr_only) && (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage) + @@ -1052,7 +1012,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); break; } - h->outbound_notify (h->cls, &ntm->peer, em, &ntm->ats, ats_count); + h->outbound_notify (h->cls, &ntm->peer, em, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_CORE_SEND_READY: if (msize != sizeof (struct SendMessageReady)) @@ -1063,18 +1023,16 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) } smr = (const struct SendMessageReady *) msg; pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &smr->peer.hashPubKey); - if (pr == NULL) + if (NULL == pr) { GNUNET_break (0); reconnect_later (h); return; } -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received notification about transmission readiness to `%s'.\n", GNUNET_i2s (&smr->peer)); -#endif - if (pr->pending_head == NULL) + if (NULL == pr->pending_head) { /* request must have been cancelled between the original request * and the response from core, ignore core's readiness */ @@ -1088,7 +1046,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) * ignore! (we should have already sent another request) */ break; } - if ((pr->prev != NULL) || (pr->next != NULL) || (h->ready_peer_head == pr)) + if ((NULL != pr->prev) || (NULL != pr->next) || (h->ready_peer_head == pr)) { /* we should not already be on the ready list... */ GNUNET_break (0); @@ -1119,14 +1077,12 @@ init_done_task (void *cls, int success) { struct GNUNET_CORE_Handle *h = cls; - if (success == GNUNET_SYSERR) + if (GNUNET_SYSERR == success) return; /* shutdown */ - if (success == GNUNET_NO) + if (GNUNET_NO == success) { -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to exchange INIT with core, retrying\n"); -#endif if (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK) reconnect_later (h); return; @@ -1152,13 +1108,10 @@ reconnect (struct GNUNET_CORE_Handle *h) uint16_t *ts; unsigned int hpos; -#if DEBUG_CORE - LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting to CORE service\n"); -#endif - GNUNET_assert (h->client == NULL); + GNUNET_assert (NULL == h->client); GNUNET_assert (h->currently_down == GNUNET_YES); h->client = GNUNET_CLIENT_connect ("core", h->cfg); - if (h->client == NULL) + if (NULL == h->client) { reconnect_later (h); return; @@ -1185,6 +1138,10 @@ reconnect (struct GNUNET_CORE_Handle *h) else opt |= GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND; } + LOG (GNUNET_ERROR_TYPE_INFO, + "(Re)connecting to CORE service, monitoring messages of type %u\n", + opt); + init->options = htonl (opt); ts = (uint16_t *) & init[1]; for (hpos = 0; hpos < h->hcnt; hpos++) @@ -1203,8 +1160,8 @@ reconnect (struct GNUNET_CORE_Handle *h) * @param cfg configuration to use * @param queue_size size of the per-peer message queue * @param cls closure for the various callbacks that follow (including handlers in the handlers array) - * @param init callback to call on timeout or once we have successfully - * connected to the core service; note that timeout is only meaningful if init is not NULL + * @param init callback to call once we have successfully + * connected to the core service * @param connects function to call on peer connect, can be NULL * @param disconnects function to call on peer disconnect / timeout, can be NULL * @param inbound_notify function to call for all inbound messages, can be NULL @@ -1255,9 +1212,7 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_assert (h->hcnt < (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct InitMessage)) / sizeof (uint16_t)); -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CORE service\n"); -#endif reconnect (h); return h; } @@ -1275,10 +1230,8 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) { struct ControlMessage *cm; -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from CORE service\n"); -#endif - if (handle->cth != NULL) + if (NULL != handle->cth) { GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth); handle->cth = NULL; @@ -1287,15 +1240,15 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) { GNUNET_CONTAINER_DLL_remove (handle->control_pending_head, handle->control_pending_tail, cm); - if (cm->th != NULL) + if (NULL != cm->th) cm->th->cm = NULL; - if (cm->cont != NULL) + if (NULL != cm->cont) cm->cont (cm->cont_cls, GNUNET_SYSERR); GNUNET_free (cm); } - if (handle->client != NULL) + if (NULL != handle->client) { - GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (handle->client); handle->client = NULL; } GNUNET_CONTAINER_multihashmap_iterate (handle->peers, @@ -1340,8 +1293,7 @@ run_request_next_transmission (void *cls, * @param cork is corking allowed for this transmission? * @param priority how important is the message? * @param maxdelay how long can the message wait? - * @param target who should receive the message, - * use NULL for this peer (loopback) + * @param target who should receive the message, never NULL (can be this peer's identity for loopback) * @param notify_size how many bytes of buffer space does notify want? * @param notify function to call when buffer space is available * @param notify_cls closure for notify @@ -1402,18 +1354,14 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, int cork, GNUNET_break (handle->queue_size != 0); GNUNET_break (pr->queue_size == 1); GNUNET_free (th); -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Dropping transmission request: cannot drop queue head and limit is one\n"); -#endif return NULL; } if (priority <= minp->priority) { -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Dropping transmission request: priority too low\n"); -#endif GNUNET_free (th); return NULL; /* priority too low */ } @@ -1432,7 +1380,7 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, int cork, /* insertion sort */ prev = pos; - while ((pos != NULL) && (pos->timeout.abs_value < th->timeout.abs_value)) + while ((NULL != pos) && (pos->timeout.abs_value < th->timeout.abs_value)) { prev = pos; pos = pos->next; @@ -1441,9 +1389,7 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, int cork, th); pr->queue_size++; /* was the request queue previously empty? */ -#if DEBUG_CORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission request added to queue\n"); -#endif if ((pr->pending_head == th) && (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK) && (pr->next == NULL) && (pr->prev == NULL) && (handle->ready_peer_head != pr)) @@ -1468,7 +1414,7 @@ GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th) was_head = (pr->pending_head == th); GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); pr->queue_size--; - if (th->cm != NULL) + if (NULL != th->cm) { /* we're currently in the control queue, remove */ GNUNET_CONTAINER_DLL_remove (h->control_pending_head, @@ -1478,14 +1424,15 @@ GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th) GNUNET_free (th); if (was_head) { - if ((pr->prev != NULL) || (pr->next != NULL) || (pr == h->ready_peer_head)) + if ((NULL != pr->prev) || (NULL != pr->next) || (pr == h->ready_peer_head)) { /* the request that was 'approved' by core was * canceled before it could be transmitted; remove * us from the 'ready' list */ GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr); } - request_next_transmission (pr); + if (NULL != h->client) + request_next_transmission (pr); } } diff --git a/src/core/core_api_is_connected.c b/src/core/core_api_is_connected.c new file mode 100644 index 0000000..2e01b36 --- /dev/null +++ b/src/core/core_api_is_connected.c @@ -0,0 +1,232 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file core/core_api_is_connected.c + * @brief implementation of the 'GNUNET_CORE_is_peer_connected function + * @author Christian Grothoff + * @author Nathan Evans + * + * TODO: + * - define nice structs for the IPC messages in core.h + * - consider NOT always sending the 'END' message -- it is redundant! + */ +#include "platform.h" +#include "gnunet_core_service.h" +#include "core.h" + + +/** + * Closure for 'transmit_is_connected_request" + */ +struct GNUNET_CORE_ConnectTestHandle +{ + + /** + * Our connection to the service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Handle for transmitting a request. + */ + struct GNUNET_CLIENT_TransmitHandle *th; + + /** + * Function called with the peer. + */ + GNUNET_CORE_ConnectEventHandler peer_cb; + + /** + * Peer to check for. + */ + struct GNUNET_PeerIdentity peer; + + /** + * Closure for peer_cb. + */ + void *cb_cls; + +}; + + +/** + * Receive reply from core service with information about a peer. + * + * @param cls our 'struct GNUNET_CORE_RequestContext *' + * @param msg NULL on error or last entry + */ +static void +receive_connect_info (void *cls, const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_CORE_ConnectTestHandle *cth = cls; + const struct ConnectNotifyMessage *connect_message; + uint32_t ats_count; + uint16_t msize; + + if (NULL == msg) + { + /* core died, failure */ + cth->peer_cb (cth->cb_cls, NULL, NULL, 0); + GNUNET_CORE_is_peer_connected_cancel (cth); + return; + } + if ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END) && + (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader))) + { + /* end of transmissions */ + cth->peer_cb (cth->cb_cls, NULL, NULL, 0); + GNUNET_CORE_is_peer_connected_cancel (cth); + return; + } + msize = ntohs (msg->size); + /* Handle incorrect message type or size, disconnect and clean up */ + if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) || + (msize < sizeof (struct ConnectNotifyMessage))) + { + GNUNET_break (0); + cth->peer_cb (cth->cb_cls, NULL, NULL, 0); + GNUNET_CORE_is_peer_connected_cancel (cth); + return; + } + connect_message = (const struct ConnectNotifyMessage *) msg; + ats_count = ntohl (connect_message->ats_count); + if (msize != + sizeof (struct ConnectNotifyMessage) + + ats_count * sizeof (struct GNUNET_ATS_Information)) + { + GNUNET_break (0); + cth->peer_cb (cth->cb_cls, NULL, NULL, 0); + GNUNET_CORE_is_peer_connected_cancel (cth); + return; + } + /* Normal case */ + cth->peer_cb (cth->cb_cls, &connect_message->peer, + (const struct GNUNET_ATS_Information *) + &connect_message[1], ats_count); + GNUNET_CLIENT_receive (cth->client, &receive_connect_info, + cth, GNUNET_TIME_UNIT_FOREVER_REL); +} + + +/** + * Function called to notify a client about the socket + * begin ready to queue more data. "buf" will be + * NULL and "size" zero if the socket was closed for + * writing in the meantime. + * + * @param cls closure + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_is_connected_request (void *cls, size_t size, void *buf) +{ + struct GNUNET_CORE_ConnectTestHandle *cth = cls; + struct GNUNET_MessageHeader *msg; + unsigned int msize; + + cth->th = NULL; + msize = + sizeof (struct GNUNET_MessageHeader) + + sizeof (struct GNUNET_PeerIdentity); + if ( (NULL == buf) || (0 == size) ) + { + cth->peer_cb (cth->cb_cls, + NULL, + NULL, 0); + GNUNET_CLIENT_disconnect (cth->client); + GNUNET_free (cth); + return 0; + } + GNUNET_assert (size >= msize); + msg = (struct GNUNET_MessageHeader *) buf; + msg->size = htons (msize); + msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_PEER_CONNECTED); + memcpy (&msg[1], &cth->peer, sizeof (struct GNUNET_PeerIdentity)); + GNUNET_CLIENT_receive (cth->client, &receive_connect_info, cth, + GNUNET_TIME_UNIT_FOREVER_REL); + return msize; +} + + +/** + * Iterate over all currently connected peers. + * Calls peer_cb with each connected peer, and then + * once with NULL to indicate that all peers have + * been handled. + * + * @param cfg configuration to use + * @param peer the specific peer to check for + * @param peer_cb function to call with the peer information + * @param cb_cls closure for peer_cb + * + * @return GNUNET_OK if iterating, GNUNET_SYSERR on error + */ +struct GNUNET_CORE_ConnectTestHandle * +GNUNET_CORE_is_peer_connected (const struct GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *peer, + GNUNET_CORE_ConnectEventHandler peer_cb, + void *cb_cls) +{ + struct GNUNET_CORE_ConnectTestHandle *cth; + struct GNUNET_CLIENT_Connection *client; + + GNUNET_assert (NULL != peer); + GNUNET_assert (NULL != peer_cb); + client = GNUNET_CLIENT_connect ("core", cfg); + if (NULL == client) + return NULL; + cth = GNUNET_malloc (sizeof (struct GNUNET_CORE_ConnectTestHandle)); + cth->peer = *peer; + cth->client = client; + cth->peer_cb = peer_cb; + cth->cb_cls = cb_cls; + cth->th = + GNUNET_CLIENT_notify_transmit_ready (client, + sizeof (struct GNUNET_MessageHeader) + + sizeof (struct GNUNET_PeerIdentity), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, &transmit_is_connected_request, cth); + GNUNET_assert (NULL != cth->th); + return cth; +} + + +/** + * Abort 'is_connected' test operation. + * + * @param cth handle for operation to cancel + */ +void +GNUNET_CORE_is_peer_connected_cancel (struct GNUNET_CORE_ConnectTestHandle *cth) +{ + if (NULL != cth->th) + { + GNUNET_CLIENT_notify_transmit_ready_cancel (cth->th); + cth->th = NULL; + } + GNUNET_CLIENT_disconnect (cth->client); + GNUNET_free (cth); +} + + +/* end of core_api_is_connected.c */ diff --git a/src/core/core_api_iterate_peers.c b/src/core/core_api_iterate_peers.c index 7b28842..7db9486 100644 --- a/src/core/core_api_iterate_peers.c +++ b/src/core/core_api_iterate_peers.c @@ -80,7 +80,7 @@ receive_info (void *cls, const struct GNUNET_MessageHeader *msg) { if (request_context->peer_cb != NULL) request_context->peer_cb (request_context->cb_cls, NULL, NULL, 0); - GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (request_context->client); GNUNET_free (request_context); return; } @@ -93,7 +93,7 @@ receive_info (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); if (request_context->peer_cb != NULL) request_context->peer_cb (request_context->cb_cls, NULL, NULL, 0); - GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (request_context->client); GNUNET_free (request_context); return; } @@ -106,7 +106,7 @@ receive_info (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); if (request_context->peer_cb != NULL) request_context->peer_cb (request_context->cb_cls, NULL, NULL, 0); - GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (request_context->client); GNUNET_free (request_context); return; } @@ -119,6 +119,7 @@ receive_info (void *cls, const struct GNUNET_MessageHeader *msg) request_context, GNUNET_TIME_UNIT_FOREVER_REL); } + /** * Function called to notify a client about the socket * begin ready to queue more data. "buf" will be @@ -143,10 +144,8 @@ transmit_request (void *cls, size_t size, void *buf) msize = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_PeerIdentity); - if ((size < msize) || (buf == NULL)) return 0; - msg = (struct GNUNET_MessageHeader *) buf; msg->size = htons (msize); if (peer != NULL) @@ -160,50 +159,7 @@ transmit_request (void *cls, size_t size, void *buf) return msize; } -/** - * Iterate over all currently connected peers. - * Calls peer_cb with each connected peer, and then - * once with NULL to indicate that all peers have - * been handled. - * - * @param cfg configuration to use - * @param peer the specific peer to check for - * @param peer_cb function to call with the peer information - * @param cb_cls closure for peer_cb - * - * @return GNUNET_OK if iterating, GNUNET_SYSERR on error - */ -int -GNUNET_CORE_is_peer_connected (const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_PeerIdentity *peer, - GNUNET_CORE_ConnectEventHandler peer_cb, - void *cb_cls) -{ - struct GNUNET_CORE_RequestContext *request_context; - struct GNUNET_CLIENT_Connection *client; - - client = GNUNET_CLIENT_connect ("core", cfg); - if (client == NULL) - return GNUNET_SYSERR; - GNUNET_assert (peer != NULL); - request_context = GNUNET_malloc (sizeof (struct GNUNET_CORE_RequestContext)); - request_context->client = client; - request_context->peer_cb = peer_cb; - request_context->cb_cls = cb_cls; - request_context->peer = peer; - request_context->th = - GNUNET_CLIENT_notify_transmit_ready (client, - sizeof (struct GNUNET_MessageHeader) - + - sizeof (struct GNUNET_PeerIdentity), - GNUNET_TIME_relative_get_forever (), - GNUNET_YES, &transmit_request, peer); - GNUNET_assert (request_context->th != NULL); - GNUNET_CLIENT_receive (client, &receive_info, request_context, - GNUNET_TIME_relative_get_forever ()); - return GNUNET_OK; -} /** * Iterate over all currently connected peers. @@ -236,11 +192,11 @@ GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, request_context->th = GNUNET_CLIENT_notify_transmit_ready (client, sizeof (struct GNUNET_MessageHeader), - GNUNET_TIME_relative_get_forever (), + GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &transmit_request, NULL); GNUNET_CLIENT_receive (client, &receive_info, request_context, - GNUNET_TIME_relative_get_forever ()); + GNUNET_TIME_UNIT_FOREVER_REL); return GNUNET_OK; } diff --git a/src/core/gnunet-core-list-connections.c b/src/core/gnunet-core-list-connections.c deleted file mode 100644 index fcd0765..0000000 --- a/src/core/gnunet-core-list-connections.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2011 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -/** - * @file core/gnunet-core-list-connections.c - * @brief Print information about other known _connected_ peers. - * @author Nathan Evans - */ -#include "platform.h" -#include "gnunet_crypto_lib.h" -#include "gnunet_configuration_lib.h" -#include "gnunet_getopt_lib.h" -#include "gnunet_peerinfo_service.h" -#include "gnunet_transport_service.h" -#include "gnunet_core_service.h" -#include "gnunet_program_lib.h" - -#define VERBOSE 0 -static int no_resolve; - -#if VERBOSE -static unsigned int peer_count; -#endif - -static const struct GNUNET_CONFIGURATION_Handle *cfg; - -struct AddressStringList -{ - /** - * Pointer to previous element. - */ - struct AddressStringList *prev; - - /** - * Pointer to next element. - */ - struct AddressStringList *next; - - /** - * Address as string. - */ - char *address_string; -}; - -struct PrintContext -{ - struct GNUNET_PeerIdentity peer; - struct AddressStringList *address_list_head; - struct AddressStringList *address_list_tail; -}; - - -static void -dump_pc (struct PrintContext *pc) -{ - struct GNUNET_CRYPTO_HashAsciiEncoded enc; - struct AddressStringList *address; - - GNUNET_CRYPTO_hash_to_enc (&pc->peer.hashPubKey, &enc); - printf (_("Peer `%s'\n"), (const char *) &enc); - while (NULL != (address = pc->address_list_head)) - { - printf ("\t%s\n", address->address_string); - GNUNET_free (address->address_string); - GNUNET_CONTAINER_DLL_remove (pc->address_list_head, pc->address_list_tail, - address); - GNUNET_free (address); - } - - printf ("\n"); - - GNUNET_free (pc); -} - - -/** - * Function to call with a human-readable format of an address - * - * @param cls closure - * @param peer peer this update is about - * @param address NULL on error, otherwise 0-terminated printable UTF-8 string - */ -static void -process_resolved_address (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address) -{ - struct PrintContext *pc = cls; - -// struct AddressStringList *new_address; - - if (address == NULL) - { - dump_pc (pc); - return; - } - - /* This does exactly the same as gnunet-transport -i ! */ - /* - * new_address = GNUNET_malloc (sizeof (struct AddressStringList)); - * #if VERBOSE - * FPRINTF (stderr, "Received address %s\n", address); - * #endif - * - * new_address->address_string = GNUNET_strdup ("FIXME"); - * GNUNET_CONTAINER_DLL_insert (pc->address_list_head, pc->address_list_tail, - * new_address); - */ -} - - -/** - * Callback for retrieving a list of connected peers. - */ -static void -connected_peer_callback (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_ATS_Information *atsi, - unsigned int atsi_count) -{ - struct PrintContext *pc; - - if (peer != NULL) /* Not yet finished */ - { -#if VERBOSE - FPRINTF (stderr, "Learned about peer %s\n", GNUNET_i2s (peer)); - peer_count++; -#endif - pc = GNUNET_malloc (sizeof (struct PrintContext)); - pc->peer = *peer; - GNUNET_TRANSPORT_peer_get_active_addresses (cfg, peer, GNUNET_YES, - GNUNET_TIME_UNIT_MINUTES, - &process_resolved_address, pc); - } -#if VERBOSE - else - { - FPRINTF (stderr, "Counted %u total connected peers.\n", peer_count); - } -#endif -} - - -/** - * Main function that will be run by the scheduler. - * - * @param cls closure - * @param args remaining command-line arguments - * @param cfgfile name of the configuration file used (for saving, can be NULL!) - * @param c configuration - */ -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *c) -{ - - cfg = c; - if (args[0] != NULL) - { - FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); - return; - } - - GNUNET_CORE_iterate_peers (cfg, &connected_peer_callback, NULL); - -} - - -/** - * The main function to obtain peer information. - * - * @param argc number of arguments from the command line - * @param argv command line arguments - * @return 0 ok, 1 on error - */ -int -main (int argc, char *const *argv) -{ - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'n', "numeric", NULL, - gettext_noop ("don't resolve host names"), - 0, &GNUNET_GETOPT_set_one, &no_resolve}, - GNUNET_GETOPT_OPTION_END - }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-list-connections", - gettext_noop - ("Print information about connected peers."), - options, &run, NULL)) ? 0 : 1; -} - -/* end of gnunet-core-list-connections.c */ diff --git a/src/core/gnunet-core.c b/src/core/gnunet-core.c new file mode 100644 index 0000000..4fe0a4f --- /dev/null +++ b/src/core/gnunet-core.c @@ -0,0 +1,99 @@ +/* + This file is part of GNUnet. + (C) 2011, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file core/gnunet-core.c + * @brief Print information about other known _connected_ peers. + * @author Nathan Evans + */ +#include "platform.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_configuration_lib.h" +#include "gnunet_getopt_lib.h" +#include "gnunet_peerinfo_service.h" +#include "gnunet_transport_service.h" +#include "gnunet_core_service.h" +#include "gnunet_program_lib.h" + + +/** + * Callback for retrieving a list of connected peers. + * + * @param cls closure (unused) + * @param peer peer identity this notification is about + * @param atsi performance data for the connection + * @param atsi_count number of records in 'atsi' + */ +static void +connected_peer_callback (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count) +{ + struct GNUNET_CRYPTO_HashAsciiEncoded enc; + + if (NULL == peer) + return; + GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc); + printf (_("Peer `%s'\n"), (const char *) &enc); +} + + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + if (args[0] != NULL) + { + FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); + return; + } + GNUNET_CORE_iterate_peers (cfg, &connected_peer_callback, NULL); +} + + +/** + * The main function to obtain peer information. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + return (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-core", + gettext_noop + ("Print information about connected peers."), + options, &run, NULL)) ? 0 : 1; +} + +/* end of gnunet-core.c */ diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index 2eb71c2..59d9383 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c @@ -56,9 +56,7 @@ struct GNUNET_STATISTICS_Handle *GSC_stats; static void cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n"); -#endif GSC_CLIENTS_done (); GSC_NEIGHBOURS_done (); GSC_SESSIONS_done (); diff --git a/src/core/gnunet-service-core_clients.c b/src/core/gnunet-service-core_clients.c index 4098b45..1076f34 100644 --- a/src/core/gnunet-service-core_clients.c +++ b/src/core/gnunet-service-core_clients.c @@ -95,6 +95,11 @@ struct GSC_Client }; +/** + * Big "or" of all client options. + */ +static uint32_t all_client_options; + /** * Head of linked list of our clients. */ @@ -146,12 +151,10 @@ static void send_to_client (struct GSC_Client *client, const struct GNUNET_MessageHeader *msg, int can_drop) { -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Preparing to send %u bytes of message of type %u to client.\n", (unsigned int) ntohs (msg->size), (unsigned int) ntohs (msg->type)); -#endif GNUNET_SERVER_notification_context_unicast (notifier, client->client_handle, msg, can_drop); } @@ -207,7 +210,7 @@ type_match (uint16_t type, struct GSC_Client *c) * Send a message to all of our current clients that have the right * options set. * - * @param sender origin of the message (used to check that this peer is + * @param partner origin (or destination) of the message (used to check that this peer is * known to be connected to the respective client) * @param msg message to multicast * @param can_drop can this message be discarded if the queue is too long @@ -215,27 +218,37 @@ type_match (uint16_t type, struct GSC_Client *c) * @param type type of the embedded message, 0 for none */ static void -send_to_all_clients (const struct GNUNET_PeerIdentity *sender, +send_to_all_clients (const struct GNUNET_PeerIdentity *partner, const struct GNUNET_MessageHeader *msg, int can_drop, - int options, uint16_t type) + uint32_t options, uint16_t type) { struct GSC_Client *c; + int tm; for (c = client_head; c != NULL; c = c->next) { - if ((0 == (options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) && - (GNUNET_YES == type_match (type, c))) - continue; /* not the full message, but we'd like the full one! */ - if ((0 == (c->options & options)) && (GNUNET_YES != type_match (type, c))) - continue; /* neither options nor type match permit the message */ -#if DEBUG_CORE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending message to client interested in messages of type %u.\n", + tm = type_match (type, c); + if (! ( (0 != (c->options & options)) || + ( (0 != (options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) && + (GNUNET_YES == tm) ) ) ) + continue; /* neither options nor type match permit the message */ + if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)) && + ( (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) || + (GNUNET_YES == tm) ) ) + continue; + if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) && + (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) ) + continue; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Sending %u message with %u bytes to client interested in messages of type %u.\n", + options, + ntohs (msg->size), (unsigned int) type); -#endif - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_contains (c->connectmap, - &sender->hashPubKey)); + GNUNET_assert ( (0 == (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) || + (GNUNET_YES != tm) || + (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_contains (c->connectmap, + &partner->hashPubKey)) ); send_to_client (c, msg, can_drop); } } @@ -283,6 +296,7 @@ handle_client_init (void *cls, struct GNUNET_SERVER_Client *client, c->client_handle = client; c->tcnt = msize / sizeof (uint16_t); c->options = ntohl (im->options); + all_client_options |= c->options; c->types = (const uint16_t *) &c[1]; c->connectmap = GNUNET_CONTAINER_multihashmap_create (16); GNUNET_assert (GNUNET_YES == @@ -295,11 +309,9 @@ handle_client_init (void *cls, struct GNUNET_SERVER_Client *client, wtypes[i] = ntohs (types[i]); GSC_TYPEMAP_add (wtypes, c->tcnt); GNUNET_CONTAINER_DLL_insert (client_head, client_tail, c); -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connecting to core service is interested in %u message types\n", (unsigned int) c->tcnt); -#endif /* send init reply message */ irm.header.size = htons (sizeof (struct InitReplyMessage)); irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY); @@ -338,11 +350,9 @@ handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client, } if (c->requests == NULL) c->requests = GNUNET_CONTAINER_multihashmap_create (16); -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client asked for transmission to `%s'\n", GNUNET_i2s (&req->peer)); -#endif is_loopback = (0 == memcmp (&req->peer, &GSC_my_identity, @@ -472,11 +482,9 @@ handle_client_send (void *cls, struct GNUNET_SERVER_Client *client, &sm->peer.hashPubKey, tc.car)); tc.cork = ntohl (sm->cork); -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client asked for transmission of %u bytes to `%s' %s\n", msize, GNUNET_i2s (&sm->peer), tc.cork ? "now" : ""); -#endif GNUNET_SERVER_mst_receive (client_mst, &tc, (const char *) &sm[1], msize, GNUNET_YES, GNUNET_NO); if (0 != @@ -498,7 +506,7 @@ handle_client_send (void *cls, struct GNUNET_SERVER_Client *client, * @param client reservation request ('struct GSC_ClientActiveRequest') * @param message the actual message */ -static void +static int client_tokenizer_callback (void *cls, void *client, const struct GNUNET_MessageHeader *message) { @@ -509,29 +517,36 @@ client_tokenizer_callback (void *cls, void *client, memcmp (&car->target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) { -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Delivering message of type %u to myself\n", ntohs (message->type)); -#endif GSC_CLIENTS_deliver_message (&GSC_my_identity, NULL, 0, message, - ntohs (message->size), - GNUNET_CORE_OPTION_SEND_FULL_INBOUND | - GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND); + ntohs (message->size), + GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND); + GSC_CLIENTS_deliver_message (&GSC_my_identity, NULL, 0, message, + sizeof (struct GNUNET_MessageHeader), + GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND); + GSC_CLIENTS_deliver_message (&GSC_my_identity, NULL, 0, message, + ntohs (message->size), + GNUNET_CORE_OPTION_SEND_FULL_INBOUND); GSC_CLIENTS_deliver_message (&GSC_my_identity, NULL, 0, message, - sizeof (struct GNUNET_MessageHeader), - GNUNET_CORE_OPTION_SEND_HDR_INBOUND | - GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND); + sizeof (struct GNUNET_MessageHeader), + GNUNET_CORE_OPTION_SEND_HDR_INBOUND); } else { -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Delivering message of type %u to %s\n", ntohs (message->type), GNUNET_i2s (&car->target)); -#endif + GSC_CLIENTS_deliver_message (&car->target, NULL, 0, message, + ntohs (message->size), + GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND); + GSC_CLIENTS_deliver_message (&car->target, NULL, 0, message, + sizeof (struct GNUNET_MessageHeader), + GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND); GSC_SESSIONS_transmit (car, message, tc->cork); } + return GNUNET_OK; } @@ -573,10 +588,8 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) if (client == NULL) return; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p has disconnected from core service.\n", client); -#endif c = find_client (client); if (c == NULL) return; /* client never sent INIT */ @@ -592,6 +605,11 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) c->connectmap = NULL; GSC_TYPEMAP_remove (c->types, c->tcnt); GNUNET_free (c); + + /* recalculate 'all_client_options' */ + all_client_options = 0; + for (c = client_head; NULL != c ; c = c->next) + all_client_options |= c->options; } @@ -673,7 +691,7 @@ GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client, { struct ConnectNotifyMessage *cnm; size_t size; - char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; + char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; struct GNUNET_ATS_Information *a; struct DisconnectNotifyMessage dcm; int old_match; @@ -715,10 +733,8 @@ GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client, cnm->ats_count = htonl (atsi_count); a = (struct GNUNET_ATS_Information *) &cnm[1]; memcpy (a, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count); -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); -#endif cnm->peer = *neighbour; send_to_client (client, &cnm->header, GNUNET_NO); } @@ -786,12 +802,13 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, const struct GNUNET_ATS_Information *atsi, unsigned int atsi_count, const struct GNUNET_MessageHeader *msg, - uint16_t msize, int options) + uint16_t msize, + uint32_t options) { size_t size = msize + sizeof (struct NotifyTrafficMessage) + atsi_count * sizeof (struct GNUNET_ATS_Information); - char buf[size]; + char buf[size] GNUNET_ALIGN; struct NotifyTrafficMessage *ntm; struct GNUNET_ATS_Information *a; @@ -809,22 +826,24 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, atsi_count = 0; size = msize + sizeof (struct NotifyTrafficMessage); } -#if DEBUG_CORE + if (! ( (0 != (all_client_options & options)) || + (0 != (options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) )) + return; /* no client cares about this message notification */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service passes message from `%4s' of type %u to client.\n", GNUNET_i2s (sender), (unsigned int) ntohs (msg->type)); -#endif GSC_SESSIONS_add_to_typemap (sender, ntohs (msg->type)); ntm = (struct NotifyTrafficMessage *) buf; ntm->header.size = htons (size); - ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND); + if (0 != (options & (GNUNET_CORE_OPTION_SEND_FULL_INBOUND | GNUNET_CORE_OPTION_SEND_HDR_INBOUND))) + ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND); + else + ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND); ntm->ats_count = htonl (atsi_count); ntm->peer = *sender; - a = &ntm->ats; + a = (struct GNUNET_ATS_Information*) &ntm[1]; memcpy (a, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count); - a[atsi_count].type = htonl (GNUNET_ATS_ARRAY_TERMINATOR); - a[atsi_count].value = htonl (0); - memcpy (&a[atsi_count + 1], msg, msize); + memcpy (&a[atsi_count], msg, msize); send_to_all_clients (sender, &ntm->header, GNUNET_YES, options, ntohs (msg->type)); } diff --git a/src/core/gnunet-service-core_clients.h b/src/core/gnunet-service-core_clients.h index bdad20d..8ece1ce 100644 --- a/src/core/gnunet-service-core_clients.h +++ b/src/core/gnunet-service-core_clients.h @@ -105,7 +105,8 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, const struct GNUNET_ATS_Information *atsi, unsigned int atsi_count, const struct GNUNET_MessageHeader *msg, - uint16_t msize, int options); + uint16_t msize, + uint32_t options); /** diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index c2acc6b..1fce2e5 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -37,6 +37,12 @@ #include "gnunet_protocols.h" #include "core.h" + +/** + * Set to GNUNET_YES to perform some slightly expensive internal invariant checks. + */ +#define EXTRA_CHECKS GNUNET_YES + /** * How long do we wait for SET_KEY confirmation initially? */ @@ -47,6 +53,12 @@ */ #define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) +/** + * How often do we rekey? + */ +#define REKEY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 90) + + /** * What is the maximum age of a message for us to consider processing * it? Note that this looks at the timestamp used by the other peer, @@ -216,6 +228,8 @@ struct EncryptedMessage }; GNUNET_NETWORK_STRUCT_END + + /** * Number of bytes (at the beginning) of "struct EncryptedMessage" * that are NOT encrypted. @@ -253,7 +267,19 @@ enum KxStateMachine * encrypted with his session key (which we got). Key exchange * is done. */ - KX_STATE_UP + KX_STATE_UP, + + /** + * We're rekeying, so we have received the other peer's session + * key, but he didn't get ours yet. + */ + KX_STATE_REKEY, + + /** + * We're rekeying but have not yet received confirmation for our new + * key from the other peer. + */ + KX_STATE_REKEY_SENT }; @@ -391,7 +417,6 @@ struct GSC_KeyExchangeInfo }; - /** * Handle to peerinfo service. */ @@ -413,9 +438,45 @@ static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; static struct GNUNET_SERVER_MessageStreamTokenizer *mst; +#if EXTRA_CHECKS +/** + * Check internal invariants of the given KX record. + * + * @param kx record to check + * @param file filename for error reporting + * @param line line number for error reporting + */ +static void +check_kx_record (struct GSC_KeyExchangeInfo *kx, + const char *file, + int line) +{ + struct GNUNET_HashCode hc; + + if (NULL == kx->public_key) + return; + GNUNET_CRYPTO_hash (kx->public_key, sizeof (*kx->public_key), &hc); + GNUNET_assert_at (0 == memcmp (&hc, &kx->peer, sizeof (struct GNUNET_HashCode)), file, line); +} + + +/** + * Check internal invariants of the given KX record. + * + * @param kx record to check + */ +#define CHECK_KX(kx) check_kx_record(kx, __FILE__, __LINE__) +#else +#define CHECK_KX(kx) +#endif /** * Derive an authentication key from "set key" information + * + * @param akey authentication key to derive + * @param skey session key to use + * @param seed seed to use + * @param creation_time creation time to use */ static void derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, @@ -425,7 +486,6 @@ derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, static const char ctx[] = "authentication key"; struct GNUNET_TIME_AbsoluteNBO ctbe; - ctbe = GNUNET_TIME_absolute_hton (creation_time); GNUNET_CRYPTO_hmac_derive_key (akey, skey, &seed, sizeof (seed), &skey->key, sizeof (skey->key), &ctbe, sizeof (ctbe), ctx, @@ -435,6 +495,11 @@ derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, /** * Derive an IV from packet information + * + * @param iv initialization vector to initialize + * @param skey session key to use + * @param seed seed to use + * @param identity identity of the other peer to use */ static void derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, @@ -449,8 +514,15 @@ derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, sizeof (ctx), NULL); } + /** * Derive an IV from pong packet information + * + * @param iv initialization vector to initialize + * @param skey session key to use + * @param seed seed to use + * @param challenge nonce to use + * @param identity identity of the other peer to use */ static void derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, @@ -492,7 +564,9 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx, &kx->encrypt_key, iv, out)); GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes encrypted"), size, GNUNET_NO); -#if DEBUG_CORE > 2 + /* the following is too sensitive to write to log files by accident, + so we require manual intervention to get this one... */ +#if 0 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted %u bytes for `%4s' using key %u, IV %u\n", (unsigned int) size, GNUNET_i2s (&kx->peer), @@ -504,8 +578,6 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx, } - - /** * Decrypt size bytes from in and write the result to out. Use the * key for inbound traffic of the given neighbour. This function does @@ -528,7 +600,9 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx, GNUNET_break (0); return GNUNET_NO; } - if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP)) + if ( (kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) && + (kx->status != KX_STATE_REKEY_SENT) && + (kx->status != KX_STATE_REKEY) ) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -542,7 +616,9 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx, } GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes decrypted"), size, GNUNET_NO); -#if DEBUG_CORE > 1 + /* the following is too sensitive to write to log files by accident, + so we require manual intervention to get this one... */ +#if 0 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypted %u bytes from `%4s' using key %u, IV %u\n", (unsigned int) size, GNUNET_i2s (&kx->peer), @@ -598,36 +674,40 @@ process_hello (void *cls, const struct GNUNET_PeerIdentity *peer, struct GSC_KeyExchangeInfo *kx = cls; struct SetKeyMessage *skm; - if (err_msg != NULL) + CHECK_KX (kx); + if (NULL != err_msg) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Error in communication with PEERINFO service\n")); kx->pitr = NULL; + if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) + GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); kx->retry_set_key_task = GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, &set_key_retry_task, kx); return; } - if (peer == NULL) + if (NULL == peer) { kx->pitr = NULL; - if (kx->public_key != NULL) + if (NULL != kx->public_key) return; /* done here */ -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n", GNUNET_i2s (&kx->peer)); -#endif GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# Delayed connecting due to lack of public key"), 1, GNUNET_NO); + if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) + GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); kx->retry_set_key_task = GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, &set_key_retry_task, kx); return; } - if (kx->public_key != NULL) + GNUNET_break (0 == memcmp (peer, &kx->peer, sizeof (struct GNUNET_PeerIdentity))); + if (NULL != kx->public_key) { /* already have public key, why are we here? */ GNUNET_break (0); @@ -641,8 +721,10 @@ process_hello (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_break (0); GNUNET_free (kx->public_key); kx->public_key = NULL; + CHECK_KX (kx); return; } + CHECK_KX (kx); send_key (kx); if (NULL != kx->skm_received) { @@ -665,10 +747,8 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid) { struct GSC_KeyExchangeInfo *kx; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initiating key exchange with `%s'\n", GNUNET_i2s (pid)); -#endif GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# key exchanges initiated"), 1, GNUNET_NO); @@ -679,6 +759,7 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid) GNUNET_PEERINFO_iterate (peerinfo, pid, GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */ , &process_hello, kx); + CHECK_KX (kx); return kx; } @@ -693,7 +774,7 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx) { GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# key exchanges stopped"), 1, GNUNET_NO); - if (kx->pitr != NULL) + if (NULL != kx->pitr) { GNUNET_PEERINFO_iterate_cancel (kx->pitr); kx->pitr = NULL; @@ -735,7 +816,8 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, struct PongMessage *pong; enum KxStateMachine sender_status; uint16_t size; - + + CHECK_KX (kx); size = ntohs (msg->size); if (size != sizeof (struct SetKeyMessage)) { @@ -746,12 +828,10 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# session keys received"), 1, GNUNET_NO); -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service receives `%s' request from `%4s'.\n", "SET_KEY", GNUNET_i2s (&kx->peer)); -#endif - if (kx->public_key == NULL) + if (NULL == kx->public_key) { GNUNET_free_non_null (kx->skm_received); kx->skm_received = (struct SetKeyMessage *) GNUNET_copy_message (msg); @@ -776,6 +856,7 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, &m->signature, kx->public_key))) { /* invalid signature */ + CHECK_KX (kx); GNUNET_break_op (0); return; } @@ -796,16 +877,20 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k))) { /* failed to decrypt !? */ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid key %x decrypted by %s from message %u (origin: %s)\n", + (unsigned int) GNUNET_CRYPTO_crc32_n (&k, sizeof (struct GNUNET_CRYPTO_AesSessionKey)), + GNUNET_i2s (&GSC_my_identity), + (unsigned int) GNUNET_CRYPTO_crc32_n (&m->encrypted_key, sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)), + GNUNET_h2s (&kx->peer.hashPubKey)); GNUNET_break_op (0); return; } GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# SET_KEY messages decrypted"), 1, GNUNET_NO); -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received SET_KEY from `%s'\n", GNUNET_i2s (&kx->peer)); -#endif kx->decrypt_key = k; if (kx->decrypt_key_created.abs_value != t.abs_value) { @@ -815,7 +900,6 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, kx->decrypt_key_created = t; } sender_status = (enum KxStateMachine) ntohl (m->sender_status); - switch (kx->status) { case KX_STATE_DOWN: @@ -829,7 +913,17 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, case KX_STATE_KEY_RECEIVED: /* we're not up, so we are already doing 'send_key' */ break; - case KX_STATE_UP: + case KX_STATE_UP: + if ((sender_status == KX_STATE_DOWN) || + (sender_status == KX_STATE_KEY_SENT)) + send_key (kx); /* we are up, but other peer is not! */ + break; + case KX_STATE_REKEY: + if ((sender_status == KX_STATE_DOWN) || + (sender_status == KX_STATE_KEY_SENT)) + send_key (kx); /* we are up, but other peer is not! */ + break; + case KX_STATE_REKEY_SENT: if ((sender_status == KX_STATE_DOWN) || (sender_status == KX_STATE_KEY_SENT)) send_key (kx); /* we are up, but other peer is not! */ @@ -838,14 +932,14 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, GNUNET_break (0); break; } - if (kx->ping_received != NULL) + if (NULL != kx->ping_received) { ping = kx->ping_received; kx->ping_received = NULL; GSC_KX_handle_ping (kx, &ping->header); GNUNET_free (ping); } - if (kx->pong_received != NULL) + if (NULL != kx->pong_received) { pong = kx->pong_received; kx->pong_received = NULL; @@ -882,7 +976,8 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# PING messages received"), 1, GNUNET_NO); - if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP)) + if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) && + (kx->status != KX_STATE_REKEY_SENT)) { /* defer */ GNUNET_free_non_null (kx->ping_received); @@ -890,11 +985,9 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, return; } m = (const struct PingMessage *) msg; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service receives `%s' request from `%4s'.\n", "PING", GNUNET_i2s (&kx->peer)); -#endif derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); if (GNUNET_OK != do_decrypt (kx, &iv, &m->target, &t.target, @@ -919,10 +1012,8 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, GNUNET_break_op (0); return; } -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PING from `%s'\n", GNUNET_i2s (&kx->peer)); -#endif /* construct PONG */ tx.reserved = GNUNET_BANDWIDTH_VALUE_MAX; tx.challenge = t.challenge; @@ -966,12 +1057,20 @@ setup_fresh_setkey (struct GSC_KeyExchangeInfo *kx) skm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY); skm->creation_time = GNUNET_TIME_absolute_hton (kx->encrypt_key_created); skm->target = kx->peer; + CHECK_KX (kx); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_rsa_encrypt (&kx->encrypt_key, sizeof (struct GNUNET_CRYPTO_AesSessionKey), kx->public_key, &skm->encrypted_key)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Encrypting key %x for %s resulting in message %u (origin: %s)\n", + (unsigned int) GNUNET_CRYPTO_crc32_n (&kx->encrypt_key, sizeof (struct GNUNET_CRYPTO_AesSessionKey)), + GNUNET_i2s (&kx->peer), + (unsigned int) GNUNET_CRYPTO_crc32_n (&skm->encrypted_key, sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)), + GNUNET_h2s (&GSC_my_identity.hashPubKey)); + GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_rsa_sign (my_private_key, &skm->purpose, &skm->signature)); @@ -1020,19 +1119,18 @@ send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; left = GNUNET_TIME_absolute_get_remaining (kx->timeout); - if (left.rel_value == 0) + if (0 == left.rel_value) { GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# sessions terminated by timeout"), 1, GNUNET_NO); GSC_SESSIONS_end (&kx->peer); kx->status = KX_STATE_DOWN; + send_key (kx); return; } -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending KEEPALIVE to `%s'\n", GNUNET_i2s (&kx->peer)); -#endif GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# keepalive messages sent"), 1, GNUNET_NO); @@ -1069,6 +1167,49 @@ update_timeout (struct GSC_KeyExchangeInfo *kx) } +/** + * Trigger rekeying event. + * + * @param cls the 'struct GSC_KeyExchangeInfo' + * @param tc schedule context (unused) + */ +static void +trigger_rekey (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GSC_KeyExchangeInfo *kx = cls; + + GNUNET_break (KX_STATE_UP == kx->status); + kx->status = KX_STATE_REKEY; + kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; + kx->retry_set_key_task = + GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, + &set_key_retry_task, kx); +} + + +/** + * Schedule rekey operation. + * + * @param kx key exchange to schedule rekey for + */ +static void +schedule_rekey (struct GSC_KeyExchangeInfo *kx) +{ + struct GNUNET_TIME_Relative rdelay; + + if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) + GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); + rdelay = REKEY_FREQUENCY; + /* randomize rekey frequency by one minute to avoid synchronization */ + rdelay.rel_value += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, + 60 * 1000); + kx->retry_set_key_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, + &trigger_rekey, + kx); +} + + /** * We received a PONG message. Validate and update our status. * @@ -1086,7 +1227,7 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, uint16_t msize; msize = ntohs (msg->size); - if (msize != sizeof (struct PongMessage)) + if (sizeof (struct PongMessage) != msize) { GNUNET_break_op (0); return; @@ -1094,21 +1235,30 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# PONG messages received"), 1, GNUNET_NO); - if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP)) + switch (kx->status) { - if (kx->status == KX_STATE_KEY_SENT) - { - GNUNET_free_non_null (kx->pong_received); - kx->pong_received = (struct PongMessage *) GNUNET_copy_message (msg); - } + case KX_STATE_DOWN: + return; + case KX_STATE_KEY_SENT: + GNUNET_free_non_null (kx->pong_received); + kx->pong_received = (struct PongMessage *) GNUNET_copy_message (msg); + return; + case KX_STATE_KEY_RECEIVED: + break; + case KX_STATE_UP: + break; + case KX_STATE_REKEY: + break; + case KX_STATE_REKEY_SENT: + break; + default: + GNUNET_break (0); return; } m = (const struct PongMessage *) msg; -#if DEBUG_HANDSHAKE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service receives `%s' response from `%4s'.\n", "PONG", GNUNET_i2s (&kx->peer)); -#endif /* mark as garbage, just to be sure */ memset (&t, 255, sizeof (t)); derive_pong_iv (&iv, &kx->decrypt_key, m->iv_seed, kx->ping_challenge, @@ -1128,7 +1278,6 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, || (kx->ping_challenge != t.challenge)) { /* PONG malformed */ -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received malformed `%s' wanted sender `%4s' with challenge %u\n", "PONG", GNUNET_i2s (&kx->peer), @@ -1136,13 +1285,10 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received malformed `%s' received from `%4s' with challenge %u\n", "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge); -#endif return; } -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PONG from `%s'\n", GNUNET_i2s (&kx->peer)); -#endif switch (kx->status) { case KX_STATE_DOWN: @@ -1158,13 +1304,10 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, GNUNET_NO); kx->status = KX_STATE_UP; GSC_SESSIONS_create (&kx->peer, kx); - if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) - { - GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); - kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; - } - GNUNET_assert (kx->keep_alive_task == GNUNET_SCHEDULER_NO_TASK); - if (kx->emsg_received != NULL) + CHECK_KX (kx); + schedule_rekey (kx); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); + if (NULL != kx->emsg_received) { emsg = kx->emsg_received; kx->emsg_received = NULL; @@ -1177,6 +1320,18 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, case KX_STATE_UP: update_timeout (kx); break; + case KX_STATE_REKEY: + update_timeout (kx); + break; + case KX_STATE_REKEY_SENT: + GNUNET_STATISTICS_update (GSC_stats, + gettext_noop + ("# rekey operations confirmed via PONG"), 1, + GNUNET_NO); + kx->status = KX_STATE_UP; + schedule_rekey (kx); + update_timeout (kx); + break; default: GNUNET_break (0); break; @@ -1192,17 +1347,20 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, static void send_key (struct GSC_KeyExchangeInfo *kx) { - GNUNET_assert (kx->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK); + CHECK_KX (kx); + if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) + { + GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); + kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; + } if (KX_STATE_UP == kx->status) return; /* nothing to do */ - if (kx->public_key == NULL) + if (NULL == kx->public_key) { /* lookup public key, then try again */ -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to obtain public key for `%s'\n", GNUNET_i2s (&kx->peer)); -#endif kx->pitr = GNUNET_PEERINFO_iterate (peerinfo, &kx->peer, GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */ , @@ -1230,17 +1388,33 @@ send_key (struct GSC_KeyExchangeInfo *kx) case KX_STATE_UP: GNUNET_break (0); return; + case KX_STATE_REKEY: + kx->status = KX_STATE_REKEY_SENT; + /* setup fresh SET KEY message */ + setup_fresh_setkey (kx); + setup_fresh_ping (kx); + GNUNET_STATISTICS_update (GSC_stats, + gettext_noop + ("# SET_KEY and PING messages created"), 1, + GNUNET_NO); + GNUNET_STATISTICS_update (GSC_stats, + gettext_noop + ("# REKEY operations performed"), 1, + GNUNET_NO); + break; + case KX_STATE_REKEY_SENT: + break; default: GNUNET_break (0); return; } /* always update sender status in SET KEY message */ - kx->skm.sender_status = htonl ((int32_t) kx->status); -#if DEBUG_CORE + /* Not sending rekey sent state to be compatible with GNUnet 0.9.2 */ + kx->skm.sender_status = htonl ((int32_t) ((kx->status == KX_STATE_REKEY_SENT) ? + KX_STATE_KEY_RECEIVED : kx->status)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SET_KEY and PING to `%s'\n", GNUNET_i2s (&kx->peer)); -#endif GSC_NEIGHBOURS_transmit (&kx->peer, &kx->skm.header, kx->set_key_retry_frequency); GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header, @@ -1288,10 +1462,8 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, do_encrypt (kx, &iv, &ph->sequence_number, &em->sequence_number, used - ENCRYPTED_HEADER_SIZE)); -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted %u bytes for %s\n", used - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer)); -#endif derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed, kx->encrypt_key_created); GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number, @@ -1348,7 +1520,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, struct GNUNET_CRYPTO_AuthKey auth_key; struct DeliverMessageContext dmc; uint16_t size = ntohs (msg->size); - char buf[size]; + char buf[size] GNUNET_ALIGN; if (size < sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader)) @@ -1357,7 +1529,8 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, return; } m = (const struct EncryptedMessage *) msg; - if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP)) + if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) && + (kx->status != KX_STATE_REKEY_SENT) ) { GNUNET_STATISTICS_update (GSC_stats, gettext_noop @@ -1365,10 +1538,10 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, 1, GNUNET_NO); return; } - if (kx->status == KX_STATE_KEY_RECEIVED) + if (KX_STATE_KEY_RECEIVED == kx->status) { /* defer */ - GNUNET_free_non_null (kx->ping_received); + GNUNET_free_non_null (kx->emsg_received); kx->emsg_received = (struct EncryptedMessage *) GNUNET_copy_message (msg); return; } @@ -1389,10 +1562,8 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, do_decrypt (kx, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE], size - ENCRYPTED_HEADER_SIZE)) return; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypted %u bytes from %s\n", size - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer)); -#endif pt = (struct EncryptedMessage *) buf; /* validate sequence number */ @@ -1487,7 +1658,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, * @param client who sent us the message (struct GSC_KeyExchangeInfo) * @param m the message */ -static void +static int deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m) { struct DeliverMessageContext *dmc = client; @@ -1497,7 +1668,7 @@ deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m) case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP: case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP: GSC_SESSIONS_set_typemap (dmc->peer, m); - return; + return GNUNET_OK; default: GSC_CLIENTS_deliver_message (dmc->peer, dmc->atsi, dmc->atsi_count, m, ntohs (m->size), @@ -1506,6 +1677,7 @@ deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m) sizeof (struct GNUNET_MessageHeader), GNUNET_CORE_OPTION_SEND_HDR_INBOUND); } + return GNUNET_OK; } @@ -1530,7 +1702,7 @@ GSC_KX_init () } my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); GNUNET_free (keyfile); - if (my_private_key == NULL) + if (NULL == my_private_key) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Core service could not access hostkey. Exiting.\n")); @@ -1559,17 +1731,17 @@ GSC_KX_init () void GSC_KX_done () { - if (my_private_key != NULL) + if (NULL != my_private_key) { GNUNET_CRYPTO_rsa_key_free (my_private_key); my_private_key = NULL; } - if (peerinfo != NULL) + if (NULL != peerinfo) { GNUNET_PEERINFO_disconnect (peerinfo); peerinfo = NULL; } - if (mst != NULL) + if (NULL != mst) { GNUNET_SERVER_mst_destroy (mst); mst = NULL; diff --git a/src/core/gnunet-service-core_neighbours.c b/src/core/gnunet-service-core_neighbours.c index c4db40a..97737a6 100644 --- a/src/core/gnunet-service-core_neighbours.c +++ b/src/core/gnunet-service-core_neighbours.c @@ -129,6 +129,8 @@ static struct GNUNET_TRANSPORT_Handle *transport; static struct Neighbour * find_neighbour (const struct GNUNET_PeerIdentity *peer) { + if (NULL == neighbours) + return NULL; return GNUNET_CONTAINER_multihashmap_get (neighbours, &peer->hashPubKey); } @@ -143,11 +145,9 @@ free_neighbour (struct Neighbour *n) { struct NeighbourMessageEntry *m; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying neighbour entry for peer `%4s'\n", GNUNET_i2s (&n->peer)); -#endif while (NULL != (m = n->message_head)) { GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); @@ -222,13 +222,11 @@ transmit_ready (void *cls, size_t size, void *buf) GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); if (buf == NULL) { -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission of message of type %u and size %u failed\n", (unsigned int) ntohs (((struct GNUNET_MessageHeader *) &m[1])->type), (unsigned int) m->size); -#endif GNUNET_free (m); process_queue (n); return 0; @@ -237,13 +235,11 @@ transmit_ready (void *cls, size_t size, void *buf) GNUNET_assert (size >= m->size); memcpy (cbuf, &m[1], m->size); ret = m->size; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Copied message of type %u and size %u into transport buffer for `%4s'\n", (unsigned int) ntohs (((struct GNUNET_MessageHeader *) &m[1])->type), (unsigned int) ret, GNUNET_i2s (&n->peer)); -#endif GNUNET_free (m); process_queue (n); GNUNET_STATISTICS_update (GSC_stats, @@ -275,13 +271,11 @@ process_queue (struct Neighbour *n) GSC_SESSIONS_solicit (&n->peer); return; } -#if DEBUG_CORE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking transport for transmission of %u bytes to `%4s' in next %llu ms\n", (unsigned int) m->size, GNUNET_i2s (&n->peer), (unsigned long long) GNUNET_TIME_absolute_get_remaining (m->deadline).rel_value); -#endif n->th = GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer, m->size, 0, GNUNET_TIME_absolute_get_remaining @@ -328,10 +322,8 @@ handle_transport_notify_connect (void *cls, GNUNET_break (0); return; } -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received connection from `%4s'.\n", GNUNET_i2s (peer)); -#endif n = GNUNET_malloc (sizeof (struct Neighbour)); n->peer = *peer; GNUNET_assert (GNUNET_OK == @@ -359,11 +351,9 @@ handle_transport_notify_disconnect (void *cls, { struct Neighbour *n; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%4s' disconnected from us; received notification from transport.\n", GNUNET_i2s (peer)); -#endif n = find_neighbour (peer); if (n == NULL) { @@ -392,11 +382,9 @@ handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer, struct Neighbour *n; uint16_t type; -#if DEBUG_CORE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u from `%4s', demultiplexing.\n", (unsigned int) ntohs (message->type), GNUNET_i2s (peer)); -#endif if (0 == memcmp (peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) { GNUNET_break (0); diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index 1f697cf..054ad97 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c @@ -176,10 +176,8 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid) session = find_session (pid); if (NULL == session) return; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying session for peer `%4s'\n", GNUNET_i2s (&session->peer)); -#endif if (GNUNET_SCHEDULER_NO_TASK != session->cork_task) { GNUNET_SCHEDULER_cancel (session->cork_task); @@ -205,7 +203,7 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid) &session-> peer.hashPubKey, session)); - GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# entries in session map"), + GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# peers connected"), GNUNET_CONTAINER_multihashmap_size (sessions), GNUNET_NO); GSC_TYPEMAP_destroy (session->tmap); @@ -255,10 +253,8 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer, { struct Session *session; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating session for peer `%4s'\n", GNUNET_i2s (peer)); -#endif session = GNUNET_malloc (sizeof (struct Session)); session->tmap = GSC_TYPEMAP_create (); session->peer = *peer; @@ -270,7 +266,7 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer, GNUNET_CONTAINER_multihashmap_put (sessions, &peer->hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# entries in session map"), + GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# peers connected"), GNUNET_CONTAINER_multihashmap_size (sessions), GNUNET_NO); GSC_CLIENTS_notify_clients_about_neighbour (peer, NULL, 0 /* FIXME: ATSI */ , @@ -341,10 +337,8 @@ GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car) session = find_session (&car->target); if (session == NULL) { -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Dropped client request for transmission (am disconnected)\n"); -#endif GNUNET_break (0); /* should have been rejected earlier */ GSC_CLIENTS_reject_request (car); return; @@ -355,10 +349,8 @@ GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car) GSC_CLIENTS_reject_request (car); return; } -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received client transmission request. queueing\n"); -#endif GNUNET_CONTAINER_DLL_insert (session->active_client_request_head, session->active_client_request_tail, car); try_transmission (session); diff --git a/src/core/test_core_api.c b/src/core/test_core_api.c index 271c2ce..37d1669 100644 --- a/src/core/test_core_api.c +++ b/src/core/test_core_api.c @@ -362,7 +362,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); diff --git a/src/core/test_core_api_peer2.conf b/src/core/test_core_api_peer2.conf index 2e848b8..cd29e3f 100644 --- a/src/core/test_core_api_peer2.conf +++ b/src/core/test_core_api_peer2.conf @@ -3,33 +3,39 @@ SERVICEHOME = /tmp/test-gnunet-core-peer-2/ DEFAULTCONFIG = test_core_api_peer2.conf -[transport-tcp] -PORT = 22468 - [arm] -PORT = 22466 +PORT = 22460 UNIXPATH = /tmp/gnunet-p2-service-arm.sock [statistics] -PORT = 22467 +PORT = 22461 UNIXPATH = /tmp/gnunet-p2-service-statistics.sock [resolver] -PORT = 22464 +PORT = 22462 UNIXPATH = /tmp/gnunet-p2-service-resolver.sock [peerinfo] -PORT = 22469 +PORT = 22463 UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] -PORT = 22465 +PORT = 22464 UNIXPATH = /tmp/gnunet-p2-service-transport.sock [core] -PORT = 22470 +PORT = 22475 UNIXPATH = /tmp/gnunet-p2-service-core.sock [ats] -PORT = 22471 +PORT = 22476 UNIXPATH = /tmp/gnunet-p2-service-ats.sock + +[transport-tcp] +PORT = 22467 + +[transport-unix] +PORT = 22468 + +[transport-http] +PORT = 22469 \ No newline at end of file diff --git a/src/core/test_core_api_reliability.c b/src/core/test_core_api_reliability.c index 645b27e..e18d8c4 100644 --- a/src/core/test_core_api_reliability.c +++ b/src/core/test_core_api_reliability.c @@ -33,8 +33,6 @@ #include "gnunet_transport_service.h" #include -#define VERBOSE GNUNET_NO - #define START_ARM GNUNET_YES /** @@ -89,11 +87,7 @@ static int ok; static int32_t tr_n; -#if VERBOSE #define OKPP do { ok++; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) -#else -#define OKPP do { ok++; } while (0) -#endif struct TestMessage { @@ -113,9 +107,11 @@ get_size (unsigned int iter) return sizeof (struct TestMessage) + (ret % 60000); } + static void process_hello (void *cls, const struct GNUNET_MessageHeader *message); + static void terminate_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -183,6 +179,7 @@ try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_TRANSPORT_try_connect (p1.th, &p2.id); } + static size_t transmit_ready (void *cls, size_t size, void *buf) { @@ -210,10 +207,8 @@ transmit_ready (void *cls, size_t size, void *buf) cbuf = buf; do { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message %u of size %u at offset %u\n", tr_n, s, ret); -#endif hdr.header.size = htons (s); hdr.header.type = htons (MTYPE); hdr.num = htonl (tr_n); @@ -237,7 +232,6 @@ transmit_ready (void *cls, size_t size, void *buf) } - static void connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *atsi, @@ -289,10 +283,8 @@ inbound_notify (void *cls, const struct GNUNET_PeerIdentity *other, const struct GNUNET_ATS_Information *atsi, unsigned int atsi_count) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core provides inbound data from `%4s'.\n", GNUNET_i2s (other)); -#endif return GNUNET_OK; } @@ -303,11 +295,9 @@ outbound_notify (void *cls, const struct GNUNET_PeerIdentity *other, const struct GNUNET_ATS_Information *atsi, unsigned int atsi_count) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core notifies about outbound data for `%4s'.\n", GNUNET_i2s (other)); -#endif return GNUNET_OK; } @@ -315,6 +305,7 @@ outbound_notify (void *cls, const struct GNUNET_PeerIdentity *other, static size_t transmit_ready (void *cls, size_t size, void *buf); + static int process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, @@ -347,10 +338,8 @@ process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer, err_task = GNUNET_SCHEDULER_add_now (&terminate_task_error, NULL); return GNUNET_SYSERR; } -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got message %u of size %u\n", ntohl (hdr->num), ntohs (message->size)); -#endif n++; if (0 == (n % (TOTAL_MSGS / 100))) FPRINTF (stderr, "%s", "."); @@ -378,7 +367,6 @@ static struct GNUNET_CORE_MessageHandler handlers[] = { }; - static void init_notify (void *cls, struct GNUNET_CORE_Handle *server, const struct GNUNET_PeerIdentity *my_identity) @@ -435,7 +423,6 @@ process_hello (void *cls, const struct GNUNET_MessageHeader *message) } - static void setup_peer (struct PeerContext *p, const char *cfgname) { @@ -444,9 +431,6 @@ setup_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); @@ -482,7 +466,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); @@ -494,9 +478,6 @@ check () char *const argv[] = { "test-core-api-reliability", "-c", "test_core_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -511,17 +492,14 @@ check () return ok; } + int main (int argc, char *argv[]) { int ret; GNUNET_log_setup ("test-core-api", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-1"); diff --git a/src/core/test_core_api_send_to_self.c b/src/core/test_core_api_send_to_self.c index 4fa73d9..b1340dc 100644 --- a/src/core/test_core_api_send_to_self.c +++ b/src/core/test_core_api_send_to_self.c @@ -81,7 +81,7 @@ cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tskctx) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (arm_proc)); - GNUNET_OS_process_close (arm_proc); + GNUNET_OS_process_destroy (arm_proc); arm_proc = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n"); diff --git a/src/core/test_core_api_start_only.c b/src/core/test_core_api_start_only.c index 2eca575..8c81320 100644 --- a/src/core/test_core_api_start_only.c +++ b/src/core/test_core_api_start_only.c @@ -208,7 +208,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); diff --git a/src/core/test_core_defaults.conf b/src/core/test_core_defaults.conf index 098c0ba..9525ca2 100644 --- a/src/core/test_core_defaults.conf +++ b/src/core/test_core_defaults.conf @@ -57,3 +57,9 @@ AUTOSTART = NO [vpn] AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[lockmanager] +AUTOSTART = NO diff --git a/src/core/test_core_quota_asymmetric_recv_limited_peer2.conf b/src/core/test_core_quota_asymmetric_recv_limited_peer2.conf index 0c89523..62fc69e 100644 --- a/src/core/test_core_quota_asymmetric_recv_limited_peer2.conf +++ b/src/core/test_core_quota_asymmetric_recv_limited_peer2.conf @@ -3,8 +3,6 @@ SERVICEHOME = /tmp/test-gnunet-core-quota-asym-recv-lim-peer-2/ DEFAULTCONFIG = test_core_quota_asymmetric_recv_limited_peer2.conf -[transport-tcp] -PORT = 22488 [arm] PORT = 22486 @@ -37,3 +35,11 @@ UNIXPATH = /tmp/gnunet-core-asym-recv-p2-service-ats.sock WAN_QUOTA_IN = 10 kiB WAN_QUOTA_OUT = 10 kiB +[transport-tcp] +PORT = 22467 + +[transport-unix] +PORT = 22468 + +[transport-http] +PORT = 22469 \ No newline at end of file diff --git a/src/core/test_core_quota_asymmetric_send_limit_peer2.conf b/src/core/test_core_quota_asymmetric_send_limit_peer2.conf index 5474ce9..614358b 100644 --- a/src/core/test_core_quota_asymmetric_send_limit_peer2.conf +++ b/src/core/test_core_quota_asymmetric_send_limit_peer2.conf @@ -3,9 +3,6 @@ SERVICEHOME = /tmp/test-gnunet-core-quota-asym-send-lim-peer-2/ DEFAULTCONFIG = test_core_quota_asymmetric_send_limit_peer2.conf -[transport-tcp] -PORT = 22488 - [arm] PORT = 22486 UNIXPATH = /tmp/gnunet-core-asym-send-p2-service-arm.sock @@ -36,3 +33,12 @@ PORT = 22491 UNIXPATH = /tmp/gnunet-core-asym-send-p2-service-ats.sock WAN_QUOTA_IN = 1 MB WAN_QUOTA_OUT = 1 MB + +[transport-tcp] +PORT = 22467 + +[transport-unix] +PORT = 22468 + +[transport-http] +PORT = 22469 \ No newline at end of file diff --git a/src/core/test_core_quota_compliance.c b/src/core/test_core_quota_compliance.c index 7c16531..df602b3 100644 --- a/src/core/test_core_quota_compliance.c +++ b/src/core/test_core_quota_compliance.c @@ -33,7 +33,6 @@ #include "gnunet_transport_service.h" #include "gnunet_statistics_service.h" -#define VERBOSE GNUNET_NO #define SYMMETRIC 0 #define ASYMMETRIC_SEND_LIMITED 1 @@ -126,6 +125,8 @@ terminate_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_CORE_Handle *ch; err_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_STATISTICS_destroy (p1.stats, GNUNET_NO); + GNUNET_STATISTICS_destroy (p2.stats, GNUNET_NO); GNUNET_TRANSPORT_get_hello_cancel (p2.ghh); GNUNET_TRANSPORT_get_hello_cancel (p1.ghh); if (p1.nth != NULL) @@ -168,14 +169,17 @@ terminate_task_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_TRANSPORT_get_hello_cancel (p1.ghh); GNUNET_TRANSPORT_get_hello_cancel (p2.ghh); - - GNUNET_CORE_disconnect (p1.ch); + if (NULL != p1.ch) + GNUNET_CORE_disconnect (p1.ch); p1.ch = NULL; - GNUNET_CORE_disconnect (p2.ch); + if (NULL != p2.ch) + GNUNET_CORE_disconnect (p2.ch); p2.ch = NULL; - GNUNET_TRANSPORT_disconnect (p1.th); + if (NULL != p1.th) + GNUNET_TRANSPORT_disconnect (p1.th); p1.th = NULL; - GNUNET_TRANSPORT_disconnect (p2.th); + if (NULL != p2.th) + GNUNET_TRANSPORT_disconnect (p2.th); p2.th = NULL; ok = 42; } @@ -237,15 +241,15 @@ measurement_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) max_quota_in = GNUNET_MIN (current_quota_p1_in, current_quota_p2_in); max_quota_out = GNUNET_MIN (current_quota_p1_out, current_quota_p2_out); if (max_quota_out < max_quota_in) - quota_delta = max_quota_in / 5; + quota_delta = max_quota_in / 3; else - quota_delta = max_quota_out / 5; + quota_delta = max_quota_out / 3; if ((throughput_out > (max_quota_out + quota_delta)) || (throughput_in > (max_quota_in + quota_delta))) - ok = 1; + ok = 1; /* fail */ else - ok = 0; + ok = 0; /* pass */ GNUNET_STATISTICS_get (p1.stats, "core", "# discarded CORE_SEND requests", GNUNET_TIME_UNIT_FOREVER_REL, NULL, &print_stat, &p1); @@ -277,17 +281,17 @@ measurement_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { case SYMMETRIC: GNUNET_log (kind, "Core quota compliance test with symmetric quotas: %s\n", - (ok != 0) ? "PASSED" : "FAILED"); + (0 == ok) ? "PASSED" : "FAILED"); break; case ASYMMETRIC_SEND_LIMITED: GNUNET_log (kind, "Core quota compliance test with limited sender quota: %s\n", - (ok != 0) ? "PASSED" : "FAILED"); + (0 == ok) ? "PASSED" : "FAILED"); break; case ASYMMETRIC_RECV_LIMITED: GNUNET_log (kind, "Core quota compliance test with limited receiver quota: %s\n", - (ok != 0) ? "PASSED" : "FAILED"); + (0 == ok) ? "PASSED" : "FAILED"); break; }; GNUNET_log (kind, "Peer 1 send rate: %llu b/s (%llu bytes in %llu ms)\n", @@ -571,9 +575,6 @@ setup_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); @@ -644,23 +645,19 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); } + static int check () { - - char *const argv[] = { "test-core-quota-compliance", "-c", "test_core_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -675,6 +672,7 @@ check () return ok; } + int main (int argc, char *argv[]) { @@ -715,11 +713,7 @@ main (int argc, char *argv[]) } GNUNET_log_setup ("test-core-quota-compliance", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); if (test == SYMMETRIC) @@ -741,10 +735,7 @@ main (int argc, char *argv[]) GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-quota-asym-recv-lim-peer-2/"); } - - - return ret; } -/* end of test_core_api_reliability.c */ +/* end of test_core_quota_compliance.c */ diff --git a/src/core/test_core_quota_peer2.conf b/src/core/test_core_quota_peer2.conf index 61e03fb..1fd4ec8 100644 --- a/src/core/test_core_quota_peer2.conf +++ b/src/core/test_core_quota_peer2.conf @@ -3,9 +3,6 @@ SERVICEHOME = /tmp/test-gnunet-core-quota-sym-peer-2/ DEFAULTCONFIG = test_core_quota_peer2.conf -[transport-tcp] -PORT = 22478 - [arm] PORT = 22476 UNIXPATH = /tmp/gnunet-core-sym-p2-service-arm.sock @@ -36,3 +33,12 @@ PORT = 22482 UNIXPATH = /tmp/gnunet-core-sym-p2-service-ats.sock WAN_QUOTA_IN = 10 kiB WAN_QUOTA_OUT = 10 kiB + +[transport-tcp] +PORT = 22467 + +[transport-unix] +PORT = 22468 + +[transport-http] +PORT = 22469 \ No newline at end of file diff --git a/src/datacache/Makefile.am b/src/datacache/Makefile.am index 6b3f916..d34e6e8 100644 --- a/src/datacache/Makefile.am +++ b/src/datacache/Makefile.am @@ -59,6 +59,7 @@ libgnunet_plugin_datacache_mysql_la_SOURCES = \ plugin_datacache_mysql.c libgnunet_plugin_datacache_mysql_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient libgnunet_plugin_datacache_mysql_la_CPPFLAGS = \ @@ -69,6 +70,7 @@ libgnunet_plugin_datacache_mysql_la_LDFLAGS = \ libgnunet_plugin_datacache_postgres_la_SOURCES = \ plugin_datacache_postgres.c libgnunet_plugin_datacache_postgres_la_LIBADD = \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_PLUGIN_LDFLAGS) $(POSTGRES_LDFLAGS) -lpq diff --git a/src/datacache/Makefile.in b/src/datacache/Makefile.in index fd0d3e2..2acd972 100644 --- a/src/datacache/Makefile.in +++ b/src/datacache/Makefile.in @@ -86,6 +86,7 @@ LTLIBRARIES = $(lib_LTLIBRARIES) $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = libgnunet_plugin_datacache_mysql_la_DEPENDENCIES = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libgnunet_plugin_datacache_mysql_la_OBJECTS = \ @@ -103,6 +104,7 @@ libgnunet_plugin_datacache_mysql_la_LINK = $(LIBTOOL) $(AM_V_lt) \ @HAVE_MYSQL_TRUE@am_libgnunet_plugin_datacache_mysql_la_rpath = \ @HAVE_MYSQL_TRUE@ -rpath $(plugindir) libgnunet_plugin_datacache_postgres_la_DEPENDENCIES = \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @@ -333,6 +335,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -366,6 +369,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -530,6 +534,7 @@ libgnunet_plugin_datacache_mysql_la_SOURCES = \ libgnunet_plugin_datacache_mysql_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient @@ -543,6 +548,7 @@ libgnunet_plugin_datacache_postgres_la_SOURCES = \ plugin_datacache_postgres.c libgnunet_plugin_datacache_postgres_la_LIBADD = \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_PLUGIN_LDFLAGS) $(POSTGRES_LDFLAGS) -lpq diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c index 936031b..b440af1 100644 --- a/src/datacache/datacache.c +++ b/src/datacache/datacache.c @@ -29,7 +29,6 @@ #include "gnunet_statistics_service.h" #include "gnunet_datacache_plugin.h" -#define DEBUG_DATACACHE GNUNET_EXTRA_LOGGING #define LOG(kind,...) GNUNET_log_from (kind, "datacache", __VA_ARGS__) @@ -108,10 +107,8 @@ env_delete_notify (void *cls, const GNUNET_HashCode * key, size_t size) { struct GNUNET_DATACACHE_Handle *h = cls; -#if DEBUG_DATACACHE LOG (GNUNET_ERROR_TYPE_DEBUG, "Content under key `%s' discarded\n", GNUNET_h2s (key)); -#endif GNUNET_assert (h->utilization >= size); h->utilization -= size; GNUNET_CONTAINER_bloomfilter_remove (h->filter, key); @@ -248,10 +245,8 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, GNUNET_break (0); return GNUNET_SYSERR; } -#if DEBUG_DATACACHE LOG (GNUNET_ERROR_TYPE_DEBUG, "Stored data under key `%s' in cache\n", GNUNET_h2s (key)); -#endif GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), size, GNUNET_NO); GNUNET_CONTAINER_bloomfilter_add (h->filter, key); @@ -280,20 +275,16 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, { GNUNET_STATISTICS_update (h->stats, gettext_noop ("# requests received"), 1, GNUNET_NO); -#if DEBUG_DATACACHE LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing request for key `%s'\n", GNUNET_h2s (key)); -#endif if (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key)) { GNUNET_STATISTICS_update (h->stats, gettext_noop ("# requests filtered by bloom filter"), 1, GNUNET_NO); -#if DEBUG_DATACACHE LOG (GNUNET_ERROR_TYPE_DEBUG, "Bloomfilter filters request for key `%s'\n", GNUNET_h2s (key)); -#endif return 0; /* can not be present */ } return h->api->get (h->api->cls, key, type, iter, iter_cls); diff --git a/src/datacache/plugin_datacache_mysql.c b/src/datacache/plugin_datacache_mysql.c index 9185c5c..8103429 100644 --- a/src/datacache/plugin_datacache_mysql.c +++ b/src/datacache/plugin_datacache_mysql.c @@ -80,21 +80,15 @@ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_datacache_plugin.h" +#include "gnunet_mysql_lib.h" #include -#define DEBUG_DATACACHE_MYSQL GNUNET_EXTRA_LOGGING /** * Estimate of the per-entry overhead (including indices). */ #define OVERHEAD ((4*2+4*2+8*2+8*2+sizeof(GNUNET_HashCode)*5+8)) -/** - * Maximum number of supported parameters for a prepared - * statement. Increase if needed. - */ -#define MAX_PARAM 16 - /** * Die with an error message that indicates * a failure of the command 'cmd' with the message given @@ -109,20 +103,6 @@ */ #define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } while(0); -struct GNUNET_MysqlStatementHandle -{ - struct GNUNET_MysqlStatementHandle *next; - - struct GNUNET_MysqlStatementHandle *prev; - - char *query; - - MYSQL_STMT *statement; - - int valid; - -}; - /** * Context for all functions in this plugin. @@ -137,535 +117,31 @@ struct Plugin /** * Handle to the mysql database. */ - MYSQL *dbf; - - struct GNUNET_MysqlStatementHandle *shead; - - struct GNUNET_MysqlStatementHandle *stail; - - /** - * Filename of "my.cnf" (msyql configuration). - */ - char *cnffile; + struct GNUNET_MYSQL_Context *mc; #define SELECT_VALUE_STMT "SELECT value,expire FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?" - struct GNUNET_MysqlStatementHandle *select_value; + struct GNUNET_MYSQL_StatementHandle *select_value; #define COUNT_VALUE_STMT "SELECT count(*) FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ?" - struct GNUNET_MysqlStatementHandle *count_value; + struct GNUNET_MYSQL_StatementHandle *count_value; #define SELECT_OLD_VALUE_STMT "SELECT hash, vhash, type, value FROM gn080dstore FORCE INDEX (expireidx) ORDER BY puttime ASC LIMIT 1" - struct GNUNET_MysqlStatementHandle *select_old_value; + struct GNUNET_MYSQL_StatementHandle *select_old_value; #define DELETE_VALUE_STMT "DELETE FROM gn080dstore WHERE hash = ? AND vhash = ? AND type = ? AND value = ?" - struct GNUNET_MysqlStatementHandle *delete_value; + struct GNUNET_MYSQL_StatementHandle *delete_value; #define INSERT_VALUE_STMT "INSERT INTO gn080dstore (type, puttime, expire, hash, vhash, value) "\ "VALUES (?, ?, ?, ?, ?, ?)" - struct GNUNET_MysqlStatementHandle *insert_value; + struct GNUNET_MYSQL_StatementHandle *insert_value; #define UPDATE_VALUE_STMT "UPDATE gn080dstore FORCE INDEX (allidx) SET puttime=?, expire=? "\ "WHERE hash=? AND vhash=? AND type=?" - struct GNUNET_MysqlStatementHandle *update_value; + struct GNUNET_MYSQL_StatementHandle *update_value; }; -/** - * Obtain the location of ".my.cnf". - * - * @param cfg our configuration - * @return NULL on error - */ -static char * -get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - char *cnffile; - char *home_dir; - struct stat st; - -#ifndef WINDOWS - struct passwd *pw; -#endif - int configured; - -#ifndef WINDOWS - pw = getpwuid (getuid ()); - if (!pw) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getpwuid"); - return NULL; - } - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (cfg, "datacache-mysql", "CONFIG")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_filename (cfg, - "datacache-mysql", - "CONFIG", - &cnffile)); - configured = GNUNET_YES; - } - else - { - home_dir = GNUNET_strdup (pw->pw_dir); - GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); - GNUNET_free (home_dir); - configured = GNUNET_NO; - } -#else - home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1); - plibc_conv_to_win_path ("~/", home_dir); - GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); - GNUNET_free (home_dir); - configured = GNUNET_NO; -#endif - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Trying to use file `%s' for MySQL configuration.\n"), cnffile); - if ((0 != STAT (cnffile, &st)) || (0 != ACCESS (cnffile, R_OK)) || - (!S_ISREG (st.st_mode))) - { - if (configured == GNUNET_YES) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not access file `%s': %s\n"), cnffile, - STRERROR (errno)); - GNUNET_free (cnffile); - return NULL; - } - return cnffile; -} - - -/** - * Free a prepared statement. - * - * @param plugin plugin context - * @param s prepared statement - */ -static void -prepared_statement_destroy (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s) -{ - GNUNET_CONTAINER_DLL_remove (plugin->shead, plugin->stail, s); - if (s->valid) - mysql_stmt_close (s->statement); - GNUNET_free (s->query); - GNUNET_free (s); -} - - -/** - * Close database connection and all prepared statements (we got a DB - * disconnect error). - */ -static int -iclose (struct Plugin *plugin) -{ - while (NULL != plugin->shead) - prepared_statement_destroy (plugin, plugin->shead); - if (plugin->dbf != NULL) - { - mysql_close (plugin->dbf); - plugin->dbf = NULL; - } - return GNUNET_OK; -} - - -/** - * Open the connection with the database (and initialize - * our default options). - * - * @return GNUNET_OK on success - */ -static int -iopen (struct Plugin *ret) -{ - char *mysql_dbname; - char *mysql_server; - char *mysql_user; - char *mysql_password; - unsigned long long mysql_port; - my_bool reconnect; - unsigned int timeout; - - ret->dbf = mysql_init (NULL); - if (ret->dbf == NULL) - return GNUNET_SYSERR; - if (ret->cnffile != NULL) - mysql_options (ret->dbf, MYSQL_READ_DEFAULT_FILE, ret->cnffile); - mysql_options (ret->dbf, MYSQL_READ_DEFAULT_GROUP, "client"); - reconnect = 0; - mysql_options (ret->dbf, MYSQL_OPT_RECONNECT, &reconnect); - mysql_options (ret->dbf, MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout); - mysql_options (ret->dbf, MYSQL_SET_CHARSET_NAME, "UTF8"); - timeout = 60; /* in seconds */ - mysql_options (ret->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout); - mysql_options (ret->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout); - mysql_dbname = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql", - "DATABASE")) - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, - "datacache-mysql", - "DATABASE", - &mysql_dbname)); - else - mysql_dbname = GNUNET_strdup ("gnunet"); - mysql_user = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql", - "USER")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, - "datacache-mysql", - "USER", &mysql_user)); - } - mysql_password = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql", - "PASSWORD")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, - "datacache-mysql", - "PASSWORD", - &mysql_password)); - } - mysql_server = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql", - "HOST")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, - "datacache-mysql", - "HOST", - &mysql_server)); - } - mysql_port = 0; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql", - "PORT")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (ret->env->cfg, - "datacache-mysql", - "PORT", &mysql_port)); - } - - GNUNET_assert (mysql_dbname != NULL); - mysql_real_connect (ret->dbf, mysql_server, mysql_user, mysql_password, - mysql_dbname, (unsigned int) mysql_port, NULL, - CLIENT_IGNORE_SIGPIPE); - GNUNET_free_non_null (mysql_server); - GNUNET_free_non_null (mysql_user); - GNUNET_free_non_null (mysql_password); - GNUNET_free (mysql_dbname); - if (mysql_error (ret->dbf)[0]) - { - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_real_connect", ret); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Run the given MySQL statement. - * - * @return GNUNET_OK on success, GNUNET_SYSERR on error - */ -static int -run_statement (struct Plugin *plugin, const char *statement) -{ - if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) - return GNUNET_SYSERR; - mysql_query (plugin->dbf, statement); - if (mysql_error (plugin->dbf)[0]) - { - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_query", plugin); - iclose (plugin); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - -/** - * Create a prepared statement. - * - * @return NULL on error - */ -static struct GNUNET_MysqlStatementHandle * -prepared_statement_create (struct Plugin *plugin, const char *statement) -{ - struct GNUNET_MysqlStatementHandle *ret; - - ret = GNUNET_malloc (sizeof (struct GNUNET_MysqlStatementHandle)); - ret->query = GNUNET_strdup (statement); - GNUNET_CONTAINER_DLL_insert (plugin->shead, plugin->stail, ret); - return ret; -} - - -/** - * Prepare a statement for running. - * - * @return GNUNET_OK on success - */ -static int -prepare_statement (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *ret) -{ - if (GNUNET_YES == ret->valid) - return GNUNET_OK; - if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) - return GNUNET_SYSERR; - ret->statement = mysql_stmt_init (plugin->dbf); - if (ret->statement == NULL) - { - iclose (plugin); - return GNUNET_SYSERR; - } - if (mysql_stmt_prepare (ret->statement, ret->query, strlen (ret->query))) - { - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", plugin); - mysql_stmt_close (ret->statement); - ret->statement = NULL; - iclose (plugin); - return GNUNET_SYSERR; - } - ret->valid = GNUNET_YES; - return GNUNET_OK; - -} - - -/** - * Bind the parameters for the given MySQL statement - * and run it. - * - * @param plugin plugin context - * @param s statement to bind and run - * @param ap arguments for the binding - * @return GNUNET_SYSERR on error, GNUNET_OK on success - */ -static int -init_params (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *s, - va_list ap) -{ - MYSQL_BIND qbind[MAX_PARAM]; - unsigned int pc; - unsigned int off; - enum enum_field_types ft; - - pc = mysql_stmt_param_count (s->statement); - if (pc > MAX_PARAM) - { - /* increase internal constant! */ - GNUNET_break (0); - return GNUNET_SYSERR; - } - memset (qbind, 0, sizeof (qbind)); - off = 0; - ft = 0; - while ((pc > 0) && (-1 != (int) (ft = va_arg (ap, enum enum_field_types)))) - { - qbind[off].buffer_type = ft; - switch (ft) - { - case MYSQL_TYPE_FLOAT: - qbind[off].buffer = va_arg (ap, float *); - - break; - case MYSQL_TYPE_LONGLONG: - qbind[off].buffer = va_arg (ap, unsigned long long *); - qbind[off].is_unsigned = va_arg (ap, int); - - break; - case MYSQL_TYPE_LONG: - qbind[off].buffer = va_arg (ap, unsigned int *); - qbind[off].is_unsigned = va_arg (ap, int); - - break; - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_BLOB: - qbind[off].buffer = va_arg (ap, void *); - qbind[off].buffer_length = va_arg (ap, unsigned long); - qbind[off].length = va_arg (ap, unsigned long *); - - break; - default: - /* unsupported type */ - GNUNET_break (0); - return GNUNET_SYSERR; - } - pc--; - off++; - } - if (!((pc == 0) && (-1 != (int) ft) && (va_arg (ap, int) == -1))) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (mysql_stmt_bind_param (s->statement, qbind)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_param", __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - if (mysql_stmt_execute (s->statement)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_execute", __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - -/** - * Type of a callback that will be called for each - * data set returned from MySQL. - * - * @param cls user-defined argument - * @param num_values number of elements in values - * @param values values returned by MySQL - * @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort - */ -typedef int (*GNUNET_MysqlDataProcessor) (void *cls, unsigned int num_values, - MYSQL_BIND * values); - - -/** - * Run a prepared SELECT statement. - * - * @param plugin plugin context - * @param s handle to SELECT statment - * @param result_size number of elements in results array - * @param results pointer to already initialized MYSQL_BIND - * array (of sufficient size) for passing results - * @param processor function to call on each result - * @param processor_cls extra argument to processor - * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective - * values (size + buffer-reference for pointers); terminated - * with "-1" - * @return GNUNET_SYSERR on error, otherwise - * the number of successfully affected (or queried) rows - */ -static int -prepared_statement_run_select (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s, - unsigned int result_size, MYSQL_BIND * results, - GNUNET_MysqlDataProcessor processor, - void *processor_cls, ...) -{ - va_list ap; - int ret; - unsigned int rsize; - int total; - - if (GNUNET_OK != prepare_statement (plugin, s)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - va_start (ap, processor_cls); - if (GNUNET_OK != init_params (plugin, s, ap)) - { - GNUNET_break (0); - va_end (ap); - return GNUNET_SYSERR; - } - va_end (ap); - rsize = mysql_stmt_field_count (s->statement); - if (rsize > result_size) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (mysql_stmt_bind_result (s->statement, results)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_result", __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - - total = 0; - while (1) - { - ret = mysql_stmt_fetch (s->statement); - if (ret == MYSQL_NO_DATA) - break; - if (ret != 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_fetch", __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - if (processor != NULL) - if (GNUNET_OK != processor (processor_cls, rsize, results)) - break; - total++; - } - mysql_stmt_reset (s->statement); - return total; -} - - - -/** - * Run a prepared statement that does NOT produce results. - * - * @param plugin plugin context - * @param s handle to SELECT statment - * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective - * values (size + buffer-reference for pointers); terminated - * with "-1" - * @param insert_id NULL or address where to store the row ID of whatever - * was inserted (only for INSERT statements!) - * @return GNUNET_SYSERR on error, otherwise - * the number of successfully affected rows - */ -static int -prepared_statement_run (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s, - unsigned long long *insert_id, ...) -{ - va_list ap; - int affected; - - if (GNUNET_OK != prepare_statement (plugin, s)) - return GNUNET_SYSERR; - va_start (ap, insert_id); - if (GNUNET_OK != init_params (plugin, s, ap)) - { - va_end (ap); - return GNUNET_SYSERR; - } - va_end (ap); - affected = mysql_stmt_affected_rows (s->statement); - if (NULL != insert_id) - *insert_id = (unsigned long long) mysql_stmt_insert_id (s->statement); - mysql_stmt_reset (s->statement); - return affected; -} - - /** * Create temporary table and prepare statements. * @@ -675,7 +151,7 @@ prepared_statement_run (struct Plugin *plugin, static int itable (struct Plugin *plugin) { -#define MRUNS(a) (GNUNET_OK != run_statement (plugin, a) ) +#define MRUNS(a) (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, a) ) if (MRUNS ("CREATE TEMPORARY TABLE gn080dstore (" " type INT(11) UNSIGNED NOT NULL DEFAULT 0," @@ -689,7 +165,7 @@ itable (struct Plugin *plugin) ") ENGINE=InnoDB") || MRUNS ("SET AUTOCOMMIT = 1")) return GNUNET_SYSERR; #undef MRUNS -#define PINIT(a,b) (NULL == (a = prepared_statement_create(plugin, b))) +#define PINIT(a,b) (NULL == (a = GNUNET_MYSQL_statement_prepare (plugin->mc, b))) if (PINIT (plugin->select_value, SELECT_VALUE_STMT) || PINIT (plugin->count_value, COUNT_VALUE_STMT) || PINIT (plugin->select_old_value, SELECT_OLD_VALUE_STMT) || @@ -742,7 +218,7 @@ mysql_plugin_put (void *cls, const GNUNET_HashCode * key, size_t size, v_now = (unsigned long long) now.abs_value; v_discard_time = (unsigned long long) discard_time.abs_value; if (GNUNET_OK == - prepared_statement_run (plugin, plugin->update_value, NULL, + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->update_value, NULL, MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES, MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES, MYSQL_TYPE_BLOB, key, sizeof (GNUNET_HashCode), @@ -757,7 +233,7 @@ mysql_plugin_put (void *cls, const GNUNET_HashCode * key, size_t size, v_length = size; if (GNUNET_OK != (ret = - prepared_statement_run (plugin, plugin->insert_value, NULL, + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->insert_value, NULL, MYSQL_TYPE_LONG, &type, GNUNET_YES, MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES, MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES, @@ -825,7 +301,7 @@ mysql_plugin_get (void *cls, const GNUNET_HashCode * key, v_now = (unsigned long long) now.abs_value; if ((GNUNET_OK != (ret = - prepared_statement_run_select (plugin, plugin->count_value, 1, rbind, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_value, 1, rbind, return_ok, NULL, MYSQL_TYPE_BLOB, key, sizeof (GNUNET_HashCode), &h_length, MYSQL_TYPE_LONG, &v_type, GNUNET_YES, @@ -854,7 +330,7 @@ mysql_plugin_get (void *cls, const GNUNET_HashCode * key, off = (off + 1) % total; if (GNUNET_OK != (ret = - prepared_statement_run_select (plugin, plugin->select_value, 2, rbind, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->select_value, 2, rbind, return_ok, NULL, MYSQL_TYPE_BLOB, key, sizeof (GNUNET_HashCode), &h_length, MYSQL_TYPE_LONG, &v_type, GNUNET_YES, @@ -917,11 +393,11 @@ mysql_plugin_del (void *cls) rbind[3].buffer = buffer; if ((GNUNET_OK != (ret = - prepared_statement_run_select (plugin, plugin->select_old_value, 4, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->select_old_value, 4, rbind, return_ok, NULL, -1))) || (GNUNET_OK != (ret = - prepared_statement_run (plugin, plugin->delete_value, NULL, + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->delete_value, NULL, MYSQL_TYPE_BLOB, &v_key, sizeof (GNUNET_HashCode), &k_length, MYSQL_TYPE_BLOB, &vhash, @@ -956,17 +432,12 @@ libgnunet_plugin_datacache_mysql_init (void *cls) plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->env = env; - plugin->cnffile = get_my_cnf_path (env->cfg); - if (GNUNET_OK != iopen (plugin)) - { - GNUNET_free_non_null (plugin->cnffile); - GNUNET_free (plugin); - return NULL; - } - if (GNUNET_OK != itable (plugin)) + plugin->mc = GNUNET_MYSQL_context_create (env->cfg, "datacache-mysql"); + if ( (NULL == plugin->mc) || + (GNUNET_OK != itable (plugin)) ) { - iclose (plugin); - GNUNET_free_non_null (plugin->cnffile); + if (NULL != plugin->mc) + GNUNET_MYSQL_context_destroy (plugin->mc); GNUNET_free (plugin); return NULL; } @@ -993,11 +464,9 @@ libgnunet_plugin_datacache_mysql_done (void *cls) struct GNUNET_DATACACHE_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; - iclose (plugin); - GNUNET_free_non_null (plugin->cnffile); + GNUNET_MYSQL_context_destroy (plugin->mc); GNUNET_free (plugin); GNUNET_free (api); - mysql_library_end (); return NULL; } diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index 3486d76..b40f1fd 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2006, 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2006, 2009, 2010, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -25,10 +25,11 @@ */ #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet_postgres_lib.h" #include "gnunet_datacache_plugin.h" #include -#define DEBUG_POSTGRES GNUNET_EXTRA_LOGGING +#define LOG(kind,...) GNUNET_log_from (kind, "datacache-postgres", __VA_ARGS__) /** * Per-entry overhead estimate @@ -53,105 +54,21 @@ struct Plugin }; -/** - * Check if the result obtained from Postgres has - * the desired status code. If not, log an error, clear the - * result and return GNUNET_SYSERR. - * - * @return GNUNET_OK if the result is acceptable - */ -static int -check_result (struct Plugin *plugin, PGresult * ret, int expected_status, - const char *command, const char *args, int line) -{ - if (ret == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "datastore-postgres", - "Postgres failed to allocate result for `%s:%s' at %d\n", - command, args, line); - return GNUNET_SYSERR; - } - if (PQresultStatus (ret) != expected_status) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "datastore-postgres", - _("`%s:%s' failed at %s:%d with error: %s"), command, args, - __FILE__, line, PQerrorMessage (plugin->dbh)); - PQclear (ret); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Run simple SQL statement (without results). - */ -static int -pq_exec (struct Plugin *plugin, const char *sql, int line) -{ - PGresult *ret; - - ret = PQexec (plugin->dbh, sql); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexec", sql, line)) - return GNUNET_SYSERR; - PQclear (ret); - return GNUNET_OK; -} - - -/** - * Prepare SQL statement. - */ -static int -pq_prepare (struct Plugin *plugin, const char *name, const char *sql, - int nparms, int line) -{ - PGresult *ret; - - ret = PQprepare (plugin->dbh, name, sql, nparms, NULL); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQprepare", sql, line)) - return GNUNET_SYSERR; - PQclear (ret); - return GNUNET_OK; -} - - /** * @brief Get a database handle + * + * @param plugin global context * @return GNUNET_OK on success, GNUNET_SYSERR on error */ static int init_connection (struct Plugin *plugin) { - char *conninfo; PGresult *ret; - /* Open database and precompile statements */ - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datacache-postgres", "CONFIG", - &conninfo)) - conninfo = NULL; - plugin->dbh = PQconnectdb (conninfo == NULL ? "" : conninfo); - GNUNET_free_non_null (conninfo); + plugin->dbh = GNUNET_POSTGRES_connect (plugin->env->cfg, + "datacache-postgres"); if (NULL == plugin->dbh) - { - /* FIXME: warn about out-of-memory? */ - return GNUNET_SYSERR; - } - if (PQstatus (plugin->dbh) != CONNECTION_OK) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "datacache-postgres", - _("Unable to initialize Postgres: %s"), - PQerrorMessage (plugin->dbh)); - PQfinish (plugin->dbh); - plugin->dbh = NULL; return GNUNET_SYSERR; - } ret = PQexec (plugin->dbh, "CREATE TEMPORARY TABLE gn090dc (" @@ -164,8 +81,8 @@ init_connection (struct Plugin *plugin) (ret, PG_DIAG_SQLSTATE))))) { - (void) check_result (plugin, ret, PGRES_COMMAND_OK, "CREATE TABLE", - "gn090dc", __LINE__); + (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "CREATE TABLE", + "gn090dc"); PQfinish (plugin->dbh); plugin->dbh = NULL; return GNUNET_SYSERR; @@ -173,10 +90,9 @@ init_connection (struct Plugin *plugin) if (PQresultStatus (ret) == PGRES_COMMAND_OK) { if ((GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_key ON gn090dc (key)", __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_key ON gn090dc (key)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_dt ON gn090dc (discard_time)", - __LINE__))) + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_dt ON gn090dc (discard_time)"))) { PQclear (ret); PQfinish (plugin->dbh); @@ -185,13 +101,11 @@ init_connection (struct Plugin *plugin) } } PQclear (ret); -#if 1 ret = PQexec (plugin->dbh, "ALTER TABLE gn090dc ALTER value SET STORAGE EXTERNAL"); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090dc", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090dc")) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -200,34 +114,31 @@ init_connection (struct Plugin *plugin) PQclear (ret); ret = PQexec (plugin->dbh, "ALTER TABLE gn090dc ALTER key SET STORAGE PLAIN"); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090dc", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090dc")) { PQfinish (plugin->dbh); plugin->dbh = NULL; return GNUNET_SYSERR; } PQclear (ret); -#endif if ((GNUNET_OK != - pq_prepare (plugin, "getkt", + GNUNET_POSTGRES_prepare (plugin->dbh, "getkt", "SELECT discard_time,type,value FROM gn090dc " - "WHERE key=$1 AND type=$2 ", 2, __LINE__)) || + "WHERE key=$1 AND type=$2 ", 2)) || (GNUNET_OK != - pq_prepare (plugin, "getk", + GNUNET_POSTGRES_prepare (plugin->dbh, "getk", "SELECT discard_time,type,value FROM gn090dc " - "WHERE key=$1", 1, __LINE__)) || + "WHERE key=$1", 1)) || (GNUNET_OK != - pq_prepare (plugin, "getm", + GNUNET_POSTGRES_prepare (plugin->dbh, "getm", "SELECT length(value),oid,key FROM gn090dc " - "ORDER BY discard_time ASC LIMIT 1", 0, __LINE__)) || + "ORDER BY discard_time ASC LIMIT 1", 0)) || (GNUNET_OK != - pq_prepare (plugin, "delrow", "DELETE FROM gn090dc WHERE oid=$1", 1, - __LINE__)) || + GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090dc WHERE oid=$1", 1)) || (GNUNET_OK != - pq_prepare (plugin, "put", + GNUNET_POSTGRES_prepare (plugin->dbh, "put", "INSERT INTO gn090dc (type, discard_time, key, value) " - "VALUES ($1, $2, $3, $4)", 4, __LINE__))) + "VALUES ($1, $2, $3, $4)", 4))) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -237,35 +148,6 @@ init_connection (struct Plugin *plugin) } -/** - * Delete the row identified by the given rowid (qid - * in postgres). - * - * @return GNUNET_OK on success - */ -static int -delete_by_rowid (struct Plugin *plugin, uint32_t rowid) -{ - uint32_t brow = htonl (rowid); - const char *paramValues[] = { (const char *) &brow }; - int paramLengths[] = { sizeof (brow) }; - const int paramFormats[] = { 1 }; - PGresult *ret; - - ret = - PQexecPrepared (plugin->dbh, "delrow", 1, paramValues, paramLengths, - paramFormats, 1); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "delrow", - __LINE__)) - { - return GNUNET_SYSERR; - } - PQclear (ret); - return GNUNET_OK; -} - - /** * Store an item in the datastore. * @@ -305,8 +187,7 @@ postgres_plugin_put (void *cls, const GNUNET_HashCode * key, size_t size, PQexecPrepared (plugin->dbh, "put", 4, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put")) return GNUNET_SYSERR; PQclear (ret); return size + OVERHEAD; @@ -352,23 +233,19 @@ postgres_plugin_get (void *cls, const GNUNET_HashCode * key, (type == 0) ? 1 : 2, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != - check_result (plugin, res, PGRES_TUPLES_OK, "PQexecPrepared", - (type == 0) ? "getk" : "getkt", __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", + (type == 0) ? "getk" : "getkt")) { -#if DEBUG_POSTGRES - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", - "Ending iteration (postgres error)\n"); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Ending iteration (postgres error)\n"); return 0; } if (0 == (cnt = PQntuples (res))) { /* no result */ -#if DEBUG_POSTGRES - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", - "Ending iteration (no more results)\n"); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Ending iteration (no more results)\n"); PQclear (res); return 0; } @@ -390,19 +267,15 @@ postgres_plugin_get (void *cls, const GNUNET_HashCode * key, GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0)); type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1)); size = PQgetlength (res, i, 2); -#if DEBUG_POSTGRES - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", - "Found result of size %u bytes and type %u in database\n", - (unsigned int) size, (unsigned int) type); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found result of size %u bytes and type %u in database\n", + (unsigned int) size, (unsigned int) type); if (GNUNET_SYSERR == iter (iter_cls, expiration_time, key, size, PQgetvalue (res, i, 2), (enum GNUNET_BLOCK_Type) type)) { -#if DEBUG_POSTGRES - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", - "Ending iteration (client error)\n"); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Ending iteration (client error)\n"); PQclear (res); return cnt; } @@ -430,22 +303,17 @@ postgres_plugin_del (void *cls) res = PQexecPrepared (plugin->dbh, "getm", 0, NULL, NULL, NULL, 1); if (GNUNET_OK != - check_result (plugin, res, PGRES_TUPLES_OK, "PQexecPrepared", "getm", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "getm")) { -#if DEBUG_POSTGRES - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", - "Ending iteration (postgres error)\n"); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Ending iteration (postgres error)\n"); return 0; } if (0 == PQntuples (res)) { /* no result */ -#if DEBUG_POSTGRES - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", - "Ending iteration (no more results)\n"); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Ending iteration (no more results)\n"); PQclear (res); return GNUNET_SYSERR; } @@ -461,7 +329,7 @@ postgres_plugin_del (void *cls) oid = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1)); memcpy (&key, PQgetvalue (res, 0, 2), sizeof (GNUNET_HashCode)); PQclear (res); - if (GNUNET_OK != delete_by_rowid (plugin, oid)) + if (GNUNET_OK != GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", oid)) return GNUNET_SYSERR; plugin->env->delete_notify (plugin->env->cls, &key, size + OVERHEAD); return GNUNET_OK; @@ -495,8 +363,8 @@ libgnunet_plugin_datacache_postgres_init (void *cls) api->get = &postgres_plugin_get; api->put = &postgres_plugin_put; api->del = &postgres_plugin_del; - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "datacache-postgres", - _("Postgres datacache running\n")); + LOG (GNUNET_ERROR_TYPE_INFO, + _("Postgres datacache running\n")); return api; } diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c index f852d3b..db27de3 100644 --- a/src/datacache/plugin_datacache_sqlite.c +++ b/src/datacache/plugin_datacache_sqlite.c @@ -28,8 +28,6 @@ #include "gnunet_datacache_plugin.h" #include -#define DEBUG_DATACACHE_SQLITE GNUNET_EXTRA_LOGGING - #define LOG(kind,...) GNUNET_log_from (kind, "datacache-sqlite", __VA_ARGS__) #define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache-sqlite", op, fn) @@ -108,13 +106,11 @@ sqlite_plugin_put (void *cls, const GNUNET_HashCode * key, size_t size, sqlite3_stmt *stmt; int64_t dval; -#if DEBUG_DATACACHE_SQLITE LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' of %u bytes with key `%4s' and expiration %llums\n", "PUT", (unsigned int) size, GNUNET_h2s (key), (unsigned long long) GNUNET_TIME_absolute_get_remaining (discard_time).rel_value); -#endif dval = (int64_t) discard_time.abs_value; if (dval < 0) dval = INT64_MAX; @@ -182,10 +178,8 @@ sqlite_plugin_get (void *cls, const GNUNET_HashCode * key, int64_t ntime; now = GNUNET_TIME_absolute_get (); -#if DEBUG_DATACACHE_SQLITE LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' for key `%4s'\n", "GET", GNUNET_h2s (key)); -#endif if (sq_prepare (plugin->dbh, "SELECT count(*) FROM ds090 WHERE key=? AND type=? AND expire >= ?", @@ -214,23 +208,19 @@ sqlite_plugin_get (void *cls, const GNUNET_HashCode * key, LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite_step"); sqlite3_finalize (stmt); -#if DEBUG_DATACACHE_SQLITE LOG (GNUNET_ERROR_TYPE_DEBUG, "No content found when processing `%s' for key `%4s'\n", "GET", GNUNET_h2s (key)); -#endif return 0; } total = sqlite3_column_int (stmt, 0); sqlite3_finalize (stmt); if ((total == 0) || (iter == NULL)) { -#if DEBUG_DATACACHE_SQLITE if (0 == total) LOG (GNUNET_ERROR_TYPE_DEBUG, "No content found when processing `%s' for key `%4s'\n", "GET", GNUNET_h2s (key)); -#endif return total; } @@ -268,11 +258,9 @@ sqlite_plugin_get (void *cls, const GNUNET_HashCode * key, if (ntime == INT64_MAX) exp = GNUNET_TIME_UNIT_FOREVER_ABS; cnt++; -#if DEBUG_DATACACHE_SQLITE LOG (GNUNET_ERROR_TYPE_DEBUG, "Found %u-byte result when processing `%s' for key `%4s'\n", (unsigned int) size, "GET", GNUNET_h2s (key)); -#endif if (GNUNET_OK != iter (iter_cls, exp, key, size, dat, type)) { sqlite3_finalize (stmt); @@ -301,9 +289,7 @@ sqlite_plugin_del (void *cls) sqlite3_stmt *dstmt; GNUNET_HashCode hc; -#if DEBUG_DATACACHE_SQLITE LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s'\n", "DEL"); -#endif stmt = NULL; dstmt = NULL; if (sq_prepare @@ -458,15 +444,11 @@ libgnunet_plugin_datacache_sqlite_done (void *cls) stmt = sqlite3_next_stmt (plugin->dbh, NULL); while (stmt != NULL) { -#if DEBUG_SQLITE LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing statement %p\n", stmt); -#endif result = sqlite3_finalize (stmt); -#if DEBUG_SQLITE if (result != SQLITE_OK) - LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to close statement %p: %d\n", + LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to close statement %p: %d\n"), stmt, result); -#endif stmt = sqlite3_next_stmt (plugin->dbh, NULL); } result = sqlite3_close (plugin->dbh); diff --git a/src/datastore/Makefile.am b/src/datastore/Makefile.am index 44c5bbe..e7bccbc 100644 --- a/src/datastore/Makefile.am +++ b/src/datastore/Makefile.am @@ -100,6 +100,7 @@ libgnunet_plugin_datastore_sqlite_la_LDFLAGS = \ libgnunet_plugin_datastore_mysql_la_SOURCES = \ plugin_datastore_mysql.c libgnunet_plugin_datastore_mysql_la_LIBADD = \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lz -lmysqlclient libgnunet_plugin_datastore_mysql_la_LDFLAGS = \ @@ -111,6 +112,7 @@ libgnunet_plugin_datastore_postgres_la_SOURCES = \ plugin_datastore_postgres.c libgnunet_plugin_datastore_postgres_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq libgnunet_plugin_datastore_postgres_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) $(POSTGRES_LDFLAGS) -lpq diff --git a/src/datastore/Makefile.in b/src/datastore/Makefile.in index d85f1ea..2488d24 100644 --- a/src/datastore/Makefile.in +++ b/src/datastore/Makefile.in @@ -87,6 +87,7 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" \ LTLIBRARIES = $(lib_LTLIBRARIES) $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = libgnunet_plugin_datastore_mysql_la_DEPENDENCIES = \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) @@ -106,6 +107,7 @@ libgnunet_plugin_datastore_mysql_la_LINK = $(LIBTOOL) $(AM_V_lt) \ @HAVE_MYSQL_TRUE@ -rpath $(plugindir) libgnunet_plugin_datastore_postgres_la_DEPENDENCIES = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) am_libgnunet_plugin_datastore_postgres_la_OBJECTS = libgnunet_plugin_datastore_postgres_la-plugin_datastore_postgres.lo @@ -405,6 +407,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -438,6 +441,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -639,6 +643,7 @@ libgnunet_plugin_datastore_mysql_la_SOURCES = \ plugin_datastore_mysql.c libgnunet_plugin_datastore_mysql_la_LIBADD = \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lz -lmysqlclient @@ -653,6 +658,7 @@ libgnunet_plugin_datastore_postgres_la_SOURCES = \ libgnunet_plugin_datastore_postgres_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq libgnunet_plugin_datastore_postgres_la_LDFLAGS = \ diff --git a/src/datastore/datastore.h b/src/datastore/datastore.h index 1126027..87ceb01 100644 --- a/src/datastore/datastore.h +++ b/src/datastore/datastore.h @@ -27,7 +27,6 @@ #ifndef DATASTORE_H #define DATASTORE_H -#define DEBUG_DATASTORE GNUNET_EXTRA_LOGGING #include "gnunet_util_lib.h" @@ -130,7 +129,7 @@ struct GetMessage * Desired key (optional). Check the "size" of the * header to see if the key is actually present. */ - GNUNET_HashCode key GNUNET_PACKED; + GNUNET_HashCode key; }; @@ -253,7 +252,7 @@ struct DataMessage /** * Key under which the item can be found. */ - GNUNET_HashCode key GNUNET_PACKED; + GNUNET_HashCode key; }; GNUNET_NETWORK_STRUCT_END diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c index 4f406a2..57663e9 100644 --- a/src/datastore/datastore_api.c +++ b/src/datastore/datastore_api.c @@ -269,6 +269,22 @@ GNUNET_DATASTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) } +/** + * Task used by 'transmit_drop' to disconnect the datastore. + * + * @param cls the datastore handle + * @param tc scheduler context + */ +static void +disconnect_after_drop (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_DATASTORE_Handle *h = cls; + + GNUNET_DATASTORE_disconnect (h, GNUNET_NO); +} + + /** * Transmit DROP message to datastore service. * @@ -287,14 +303,16 @@ transmit_drop (void *cls, size_t size, void *buf) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to transmit request to drop database.\n")); - GNUNET_DATASTORE_disconnect (h, GNUNET_NO); + GNUNET_SCHEDULER_add_continuation (&disconnect_after_drop, h, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); return 0; } GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); hdr = buf; hdr->size = htons (sizeof (struct GNUNET_MessageHeader)); hdr->type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_DROP); - GNUNET_DATASTORE_disconnect (h, GNUNET_NO); + GNUNET_SCHEDULER_add_continuation (&disconnect_after_drop, h, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); return sizeof (struct GNUNET_MessageHeader); } @@ -311,9 +329,7 @@ GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, int drop) { struct GNUNET_DATASTORE_QueueEntry *qe; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Datastore disconnect\n"); -#endif if (NULL != h->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); @@ -321,7 +337,7 @@ GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, int drop) } if (h->client != NULL) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } if (h->reconnect_task != GNUNET_SCHEDULER_NO_TASK) @@ -346,7 +362,7 @@ GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, int drop) GNUNET_TIME_UNIT_MINUTES, GNUNET_YES, &transmit_drop, h)) return; - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } GNUNET_break (0); @@ -373,9 +389,7 @@ timeout_queue_entry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_NO); qe->task = GNUNET_SCHEDULER_NO_TASK; GNUNET_assert (qe->was_transmitted == GNUNET_NO); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Timeout of request in datastore queue\n"); -#endif qe->response_proc (qe->h, NULL); } @@ -455,9 +469,7 @@ make_queue_entry (struct GNUNET_DATASTORE_Handle *h, size_t msize, GNUNET_assert (pos->response_proc != NULL); /* move 'pos' element to head so that it will be * killed on 'NULL' call below */ -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Dropping request from datastore queue\n"); -#endif GNUNET_CONTAINER_DLL_remove (h->queue_head, h->queue_tail, pos); GNUNET_CONTAINER_DLL_insert (h->queue_head, h->queue_tail, pos); GNUNET_STATISTICS_update (h->stats, @@ -512,9 +524,7 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) gettext_noop ("# datastore connections (re)created"), 1, GNUNET_NO); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnected to DATASTORE\n"); -#endif process_queue (h); } @@ -530,17 +540,15 @@ do_disconnect (struct GNUNET_DATASTORE_Handle *h) { if (h->client == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "client NULL in disconnect, will not try to reconnect\n"); -#endif return; } #if 0 GNUNET_STATISTICS_update (stats, gettext_noop ("# reconnected to DATASTORE"), 1, GNUNET_NO); #endif - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->skip_next_messages = 0; h->client = NULL; h->reconnect_task = @@ -562,9 +570,7 @@ receive_cb (void *cls, const struct GNUNET_MessageHeader *msg) struct GNUNET_DATASTORE_QueueEntry *qe; h->in_receive = GNUNET_NO; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving reply from datastore\n"); -#endif if (h->skip_next_messages > 0) { h->skip_next_messages--; @@ -601,9 +607,7 @@ transmit_request (void *cls, size_t size, void *buf) return 0; /* no entry in queue */ if (buf == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to transmit request to DATASTORE.\n"); -#endif GNUNET_STATISTICS_update (h->stats, gettext_noop ("# transmission request failures"), 1, GNUNET_NO); @@ -615,10 +619,8 @@ transmit_request (void *cls, size_t size, void *buf) process_queue (h); return 0; } -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u byte request to DATASTORE\n", msize); -#endif memcpy (buf, &qe[1], msize); qe->was_transmitted = GNUNET_YES; GNUNET_SCHEDULER_cancel (qe->task); @@ -647,30 +649,22 @@ process_queue (struct GNUNET_DATASTORE_Handle *h) if (NULL == (qe = h->queue_head)) { -#if DEBUG_DATASTORE > 1 LOG (GNUNET_ERROR_TYPE_DEBUG, "Queue empty\n"); -#endif return; /* no entry in queue */ } if (qe->was_transmitted == GNUNET_YES) { -#if DEBUG_DATASTORE > 1 LOG (GNUNET_ERROR_TYPE_DEBUG, "Head request already transmitted\n"); -#endif return; /* waiting for replies */ } if (h->th != NULL) { -#if DEBUG_DATASTORE > 1 LOG (GNUNET_ERROR_TYPE_DEBUG, "Pending transmission request\n"); -#endif return; /* request pending */ } if (h->client == NULL) { -#if DEBUG_DATASTORE > 1 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not connected\n"); -#endif return; /* waiting for reconnect */ } if (GNUNET_YES == h->in_receive) @@ -678,10 +672,8 @@ process_queue (struct GNUNET_DATASTORE_Handle *h) /* wait for response to previous query */ return; } -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing %u byte request to DATASTORE\n", qe->message_size); -#endif h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, qe->message_size, GNUNET_TIME_absolute_get_remaining @@ -803,9 +795,7 @@ process_status_message (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); emsg = _("Invalid error message received from datastore service"); } -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received status %d/%s\n", (int) status, emsg); -#endif GNUNET_STATISTICS_update (h->stats, gettext_noop ("# status messages received"), 1, GNUNET_NO); @@ -861,12 +851,10 @@ GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, uint32_t rid, size_t msize; union QueueContext qc; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to put %u bytes of data under key `%s' for %llu ms\n", size, GNUNET_h2s (key), GNUNET_TIME_absolute_get_remaining (expiration).rel_value); -#endif msize = sizeof (struct DataMessage) + size; GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); qc.sc.cont = cont; @@ -875,9 +863,7 @@ GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, uint32_t rid, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for PUT\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, gettext_noop ("# PUT requests executed"), @@ -934,20 +920,16 @@ GNUNET_DATASTORE_reserve (struct GNUNET_DATASTORE_Handle *h, uint64_t amount, if (cont == NULL) cont = &drop_status_cont; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to reserve %llu bytes of data and %u entries\n", (unsigned long long) amount, (unsigned int) entries); -#endif qc.sc.cont = cont; qc.sc.cont_cls = cont_cls; qe = make_queue_entry (h, sizeof (struct ReserveMessage), queue_priority, max_queue_size, timeout, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry to reserve\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -998,9 +980,7 @@ GNUNET_DATASTORE_release_reserve (struct GNUNET_DATASTORE_Handle *h, if (cont == NULL) cont = &drop_status_cont; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to release reserve %d\n", rid); -#endif qc.sc.cont = cont; qc.sc.cont_cls = cont_cls; qe = make_queue_entry (h, sizeof (struct ReleaseReserveMessage), @@ -1008,10 +988,8 @@ GNUNET_DATASTORE_release_reserve (struct GNUNET_DATASTORE_Handle *h, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry to release reserve\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1060,20 +1038,16 @@ GNUNET_DATASTORE_update (struct GNUNET_DATASTORE_Handle *h, uint64_t uid, if (cont == NULL) cont = &drop_status_cont; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to update entry %llu raising priority by %u and expiration to %llu\n", uid, (unsigned int) priority, (unsigned long long) expiration.abs_value); -#endif qc.sc.cont = cont; qc.sc.cont_cls = cont_cls; qe = make_queue_entry (h, sizeof (struct UpdateMessage), queue_priority, max_queue_size, timeout, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for UPDATE\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1127,10 +1101,8 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h, if (cont == NULL) cont = &drop_status_cont; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to remove %u bytes under key `%s'\n", size, GNUNET_h2s (key)); -#endif qc.sc.cont = cont; qc.sc.cont_cls = cont_cls; msize = sizeof (struct DataMessage) + size; @@ -1139,9 +1111,7 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for REMOVE\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1209,10 +1179,8 @@ process_result_message (void *cls, const struct GNUNET_MessageHeader *msg) rc = qe->qc.rc; GNUNET_assert (GNUNET_YES == qe->was_transmitted); free_queue_entry (qe); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received end of result set, new queue size is %u\n", h->queue_size); -#endif h->retry_time.rel_value = 0; h->result_count = 0; process_queue (h); @@ -1253,12 +1221,10 @@ process_result_message (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_STATISTICS_update (h->stats, gettext_noop ("# Results received"), 1, GNUNET_NO); dm = (const struct DataMessage *) msg; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received result %llu with type %u and size %u with key %s\n", (unsigned long long) GNUNET_ntohll (dm->uid), ntohl (dm->type), ntohl (dm->size), GNUNET_h2s (&dm->key)); -#endif free_queue_entry (qe); h->retry_time.rel_value = 0; process_queue (h); @@ -1302,10 +1268,8 @@ GNUNET_DATASTORE_get_for_replication (struct GNUNET_DATASTORE_Handle *h, union QueueContext qc; GNUNET_assert (NULL != proc); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to get replication entry in %llu ms\n", (unsigned long long) timeout.rel_value); -#endif qc.rc.proc = proc; qc.rc.proc_cls = proc_cls; qe = make_queue_entry (h, sizeof (struct GNUNET_MessageHeader), @@ -1313,10 +1277,8 @@ GNUNET_DATASTORE_get_for_replication (struct GNUNET_DATASTORE_Handle *h, &process_result_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for GET REPLICATION\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1367,12 +1329,10 @@ GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h, GNUNET_assert (NULL != proc); GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to get %llu-th zero-anonymity entry of type %d in %llu ms\n", (unsigned long long) offset, type, (unsigned long long) timeout.rel_value); -#endif qc.rc.proc = proc; qc.rc.proc_cls = proc_cls; qe = make_queue_entry (h, sizeof (struct GetZeroAnonymityMessage), @@ -1380,10 +1340,8 @@ GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h, &process_result_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for zero-anonymity procation\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1435,21 +1393,17 @@ GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h, uint64_t offset, union QueueContext qc; GNUNET_assert (NULL != proc); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to look for data of type %u under key `%s'\n", (unsigned int) type, GNUNET_h2s (key)); -#endif qc.rc.proc = proc; qc.rc.proc_cls = proc_cls; qe = make_queue_entry (h, sizeof (struct GetMessage), queue_priority, max_queue_size, timeout, &process_result_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not queue request for `%s'\n", GNUNET_h2s (key)); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, gettext_noop ("# GET requests executed"), @@ -1486,11 +1440,9 @@ GNUNET_DATASTORE_cancel (struct GNUNET_DATASTORE_QueueEntry *qe) GNUNET_assert (GNUNET_SYSERR != qe->was_transmitted); h = qe->h; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Pending DATASTORE request %p cancelled (%d, %d)\n", qe, qe->was_transmitted, h->queue_head == qe); -#endif if (GNUNET_YES == qe->was_transmitted) { free_queue_entry (qe); diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c index 1d7e8cd..49b9db8 100644 --- a/src/datastore/gnunet-service-datastore.c +++ b/src/datastore/gnunet-service-datastore.c @@ -250,7 +250,7 @@ struct TransmitCallbackContext /** * Handle for the transmission request. */ - struct GNUNET_CONNECTION_TransmitHandle *th; + struct GNUNET_SERVER_TransmitHandle *th; /** * Client that we are transmitting to. @@ -341,12 +341,10 @@ expired_processor (void *cls, const GNUNET_HashCode * key, uint32_t size, &delete_expired, NULL); return GNUNET_SYSERR; } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting content `%s' of type %u that expired %llu ms ago\n", GNUNET_h2s (key), type, (unsigned long long) (now.abs_value - expiration.abs_value)); -#endif min_expiration = now; GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes expired"), size, GNUNET_YES); @@ -405,7 +403,6 @@ quota_processor (void *cls, const GNUNET_HashCode * key, uint32_t size, if (NULL == key) return GNUNET_SYSERR; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting %llu bytes of low-priority (%u) content `%s' of type %u at %llu ms prior to expiration (still trying to free another %llu bytes)\n", (unsigned long long) (size + GNUNET_DATASTORE_ENTRY_OVERHEAD), @@ -413,7 +410,6 @@ quota_processor (void *cls, const GNUNET_HashCode * key, uint32_t size, GNUNET_h2s (key), type, (unsigned long long) GNUNET_TIME_absolute_get_remaining (expiration).rel_value, *need); -#endif if (size + GNUNET_DATASTORE_ENTRY_OVERHEAD > *need) *need = 0; else @@ -447,10 +443,8 @@ manage_space (unsigned long long need) { unsigned long long last; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asked to free up %llu bytes of cache space\n", need); -#endif last = 0; while ((need > 0) && (last != need)) { @@ -513,10 +507,8 @@ transmit (struct GNUNET_SERVER_Client *client, struct GNUNET_MessageHeader *msg) if (GNUNET_YES == cleaning_done) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Shutdown in progress, aborting transmission.\n"); -#endif + _("Shutdown in progress, aborting transmission.\n")); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); GNUNET_free (msg); return; @@ -554,11 +546,9 @@ transmit_status (struct GNUNET_SERVER_Client *client, int code, const char *msg) struct StatusMessage *sm; size_t slen; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' message with value %d and message `%s'\n", "STATUS", code, msg != NULL ? msg : "(none)"); -#endif slen = (msg == NULL) ? 0 : strlen (msg) + 1; sm = GNUNET_malloc (sizeof (struct StatusMessage) + slen); sm->header.size = htons (sizeof (struct StatusMessage) + slen); @@ -603,10 +593,8 @@ transmit_item (void *cls, const GNUNET_HashCode * key, uint32_t size, if (key == NULL) { /* transmit 'DATA_END' */ -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' message\n", "DATA_END"); -#endif end = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader)); end->size = htons (sizeof (struct GNUNET_MessageHeader)); end->type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END); @@ -630,13 +618,11 @@ transmit_item (void *cls, const GNUNET_HashCode * key, uint32_t size, dm->uid = GNUNET_htonll (uid); dm->key = *key; memcpy (&dm[1], data, size); -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' message for `%s' of type %u with expiration %llu (now: %llu)\n", "DATA", GNUNET_h2s (key), type, (unsigned long long) expiration.abs_value, (unsigned long long) GNUNET_TIME_absolute_get ().abs_value); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# results found"), 1, GNUNET_NO); transmit (client, &dm->header); @@ -668,9 +654,7 @@ handle_reserve (void *cls, struct GNUNET_SERVER_Client *client, uint64_t amount; uint32_t entries; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "RESERVE"); -#endif amount = GNUNET_ntohll (msg->amount); entries = ntohl (msg->entries); used = payload + reserved; @@ -742,10 +726,8 @@ handle_release_reserve (void *cls, struct GNUNET_SERVER_Client *client, int rid = ntohl (msg->rid); unsigned long long rem; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "RELEASE_RESERVE"); -#endif next = reservations; prev = NULL; while (NULL != (pos = next)) @@ -764,11 +746,9 @@ handle_release_reserve (void *cls, struct GNUNET_SERVER_Client *client, reserved -= rem; GNUNET_STATISTICS_set (stats, gettext_noop ("# reserved"), reserved, GNUNET_NO); -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Returning %llu remaining reserved bytes to storage pool\n", rem); -#endif GNUNET_free (pos); transmit_status (client, GNUNET_OK, NULL); return; @@ -854,11 +834,9 @@ execute_put (struct GNUNET_SERVER_Client *client, const struct DataMessage *dm) GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes stored"), size, GNUNET_YES); GNUNET_CONTAINER_bloomfilter_add (filter, &dm->key); -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully stored %u bytes of type %u under key `%s'\n", size, ntohl (dm->type), GNUNET_h2s (&dm->key)); -#endif } transmit_status (client, ret, msg); GNUNET_free_non_null (msg); @@ -914,10 +892,8 @@ check_present (void *cls, const GNUNET_HashCode * key, uint32_t size, (0 == memcmp (&dm[1], data, size)))) { -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result already present in datastore\n"); -#endif /* FIXME: change API to allow increasing 'replication' counter */ if ((ntohl (dm->priority) > 0) || (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value > @@ -963,11 +939,9 @@ handle_put (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request for `%s' of type %u\n", "PUT", GNUNET_h2s (&dm->key), ntohl (dm->type)); -#endif rid = ntohl (dm->rid); size = ntohl (dm->size); if (rid > 0) @@ -1026,11 +1000,9 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, return; } msg = (const struct GetMessage *) message; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request for `%s' of type %u\n", "GET", GNUNET_h2s (&msg->key), ntohl (msg->type)); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# GET requests received"), 1, GNUNET_NO); GNUNET_SERVER_client_keep (client); @@ -1038,11 +1010,9 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, (GNUNET_YES != GNUNET_CONTAINER_bloomfilter_test (filter, &msg->key))) { /* don't bother database... */ -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Empty result set for `%s' request for `%s' (bloomfilter).\n", "GET", GNUNET_h2s (&msg->key)); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# requests filtered by bloomfilter"), 1, @@ -1077,10 +1047,8 @@ handle_update (void *cls, struct GNUNET_SERVER_Client *client, 1, GNUNET_NO); msg = (const struct UpdateMessage *) message; emsg = NULL; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request for %llu\n", "UPDATE", (unsigned long long) GNUNET_ntohll (msg->uid)); -#endif ret = plugin->api->update (plugin->api->cls, GNUNET_ntohll (msg->uid), (int32_t) ntohl (msg->priority), @@ -1101,10 +1069,8 @@ static void handle_get_replication (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "GET_REPLICATION"); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# GET REPLICATION requests received"), 1, @@ -1136,10 +1102,8 @@ handle_get_zero_anonymity (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "GET_ZERO_ANONYMITY"); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# GET ZERO ANONYMITY requests received"), 1, @@ -1165,19 +1129,15 @@ remove_callback (void *cls, const GNUNET_HashCode * key, uint32_t size, if (key == NULL) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No further matches for `%s' request.\n", "REMOVE"); -#endif transmit_status (client, GNUNET_NO, _("Content not found")); GNUNET_SERVER_client_drop (client); return GNUNET_OK; /* last item */ } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Item %llu matches `%s' request for key `%s' and type %u.\n", (unsigned long long) uid, "REMOVE", GNUNET_h2s (key), type); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes removed (explicit request)"), size, GNUNET_YES); @@ -1208,11 +1168,9 @@ handle_remove (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request for `%s' of type %u\n", "REMOVE", GNUNET_h2s (&dm->key), ntohl (dm->type)); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# REMOVE requests received"), 1, GNUNET_NO); GNUNET_SERVER_client_keep (client); @@ -1234,9 +1192,7 @@ static void handle_drop (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "DROP"); -#endif do_drop = GNUNET_YES; GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -1287,11 +1243,9 @@ process_stat_in (void *cls, const char *subsystem, const char *name, GNUNET_assert (stats_worked == GNUNET_NO); stats_worked = GNUNET_YES; payload += value; -#if DEBUG_SQLITE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notification from statistics about existing payload (%llu), new payload is %llu\n", - abs_value, payload); -#endif + value, payload); return GNUNET_OK; } @@ -1348,10 +1302,8 @@ load_plugin () static void unload_plugin (struct DatastorePlugin *plug) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Datastore service is unloading plugin...\n"); -#endif GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api)); GNUNET_free (plug->lib_name); GNUNET_free (plug->short_name); @@ -1409,7 +1361,7 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONTAINER_DLL_remove (tcc_head, tcc_tail, tcc); if (tcc->th != NULL) { - GNUNET_CONNECTION_notify_transmit_ready_cancel (tcc->th); + GNUNET_SERVER_notify_transmit_ready_cancel (tcc->th); GNUNET_SERVER_client_drop (tcc->client); } GNUNET_free (tcc->msg); diff --git a/src/datastore/perf_datastore_api.c b/src/datastore/perf_datastore_api.c index aae152d..cdbd6ae 100644 --- a/src/datastore/perf_datastore_api.c +++ b/src/datastore/perf_datastore_api.c @@ -285,8 +285,9 @@ run_tests (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, c if (success != GNUNET_YES) { FPRINTF (stderr, - "Test 'put' operation failed with error `%s' database likely not setup, skipping test.", + "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n", msg); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); return; } @@ -359,7 +360,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; return ok; } diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c index 76d6ad7..ed7741c 100644 --- a/src/datastore/plugin_datastore_mysql.c +++ b/src/datastore/plugin_datastore_mysql.c @@ -119,47 +119,11 @@ #include "platform.h" #include "gnunet_datastore_plugin.h" #include "gnunet_util_lib.h" -#include +#include "gnunet_mysql_lib.h" -#define DEBUG_MYSQL GNUNET_EXTRA_LOGGING #define MAX_DATUM_SIZE 65536 -/** - * Maximum number of supported parameters for a prepared - * statement. Increase if needed. - */ -#define MAX_PARAM 16 - -/** - * Die with an error message that indicates - * a failure of the command 'cmd' with the message given - * by strerror(errno). - */ -#define DIE_MYSQL(cmd, dbh) do { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); GNUNET_abort(); } while(0); - -/** - * Log an error message at log-level 'level' that indicates - * a failure of the command 'cmd' on file 'filename' - * with the message given by strerror(errno). - */ -#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } while(0); - - -struct GNUNET_MysqlStatementHandle -{ - struct GNUNET_MysqlStatementHandle *next; - - struct GNUNET_MysqlStatementHandle *prev; - - char *query; - - MYSQL_STMT *statement; - - int valid; - -}; - /** * Context for all functions in this plugin. @@ -174,64 +138,49 @@ struct Plugin /** * Handle to talk to MySQL. */ - MYSQL *dbf; - - /** - * We keep all prepared statements in a DLL. This is the head. - */ - struct GNUNET_MysqlStatementHandle *shead; - - /** - * We keep all prepared statements in a DLL. This is the tail. - */ - struct GNUNET_MysqlStatementHandle *stail; - - /** - * Filename of "my.cnf" (msyql configuration). - */ - char *cnffile; + struct GNUNET_MYSQL_Context *mc; /** * Prepared statements. */ #define INSERT_ENTRY "INSERT INTO gn090 (repl,type,prio,anonLevel,expire,rvalue,hash,vhash,value) VALUES (?,?,?,?,?,?,?,?,?)" - struct GNUNET_MysqlStatementHandle *insert_entry; + struct GNUNET_MYSQL_StatementHandle *insert_entry; #define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?" - struct GNUNET_MysqlStatementHandle *delete_entry_by_uid; + struct GNUNET_MYSQL_StatementHandle *delete_entry_by_uid; #define COUNT_ENTRY_BY_HASH "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash) WHERE hash=?" - struct GNUNET_MysqlStatementHandle *count_entry_by_hash; + struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash; #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 ?" - struct GNUNET_MysqlStatementHandle *select_entry_by_hash; + struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash; #define COUNT_ENTRY_BY_HASH_AND_VHASH "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=?" - struct GNUNET_MysqlStatementHandle *count_entry_by_hash_and_vhash; + struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_and_vhash; #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 ?" - struct GNUNET_MysqlStatementHandle *select_entry_by_hash_and_vhash; + struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_vhash; #define COUNT_ENTRY_BY_HASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_type_uid) WHERE hash=? AND type=?" - struct GNUNET_MysqlStatementHandle *count_entry_by_hash_and_type; + struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_and_type; #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 ?" - struct GNUNET_MysqlStatementHandle *select_entry_by_hash_and_type; + struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_type; #define COUNT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND type=?" - struct GNUNET_MysqlStatementHandle *count_entry_by_hash_vhash_and_type; + struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_vhash_and_type; #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 ?" - struct GNUNET_MysqlStatementHandle *select_entry_by_hash_vhash_and_type; + struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_vhash_and_type; #define UPDATE_ENTRY "UPDATE gn090 SET prio=prio+?,expire=IF(expire>=?,expire,?) WHERE uid=?" - struct GNUNET_MysqlStatementHandle *update_entry; + struct GNUNET_MYSQL_StatementHandle *update_entry; #define DEC_REPL "UPDATE gn090 SET repl=GREATEST (0, repl - 1) WHERE uid=?" - struct GNUNET_MysqlStatementHandle *dec_repl; + struct GNUNET_MYSQL_StatementHandle *dec_repl; #define SELECT_SIZE "SELECT SUM(BIT_LENGTH(value) DIV 8) FROM gn090" - struct GNUNET_MysqlStatementHandle *get_size; + struct GNUNET_MYSQL_StatementHandle *get_size; #define SELECT_IT_NON_ANONYMOUS "SELECT type,prio,anonLevel,expire,hash,value,uid "\ "FROM gn090 FORCE INDEX (idx_anonLevel_type_rvalue) "\ @@ -239,13 +188,13 @@ struct Plugin "(rvalue >= ? OR"\ " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_anonLevel_type_rvalue) WHERE anonLevel=0 AND type=? AND rvalue>=?)) "\ "ORDER BY rvalue ASC LIMIT 1" - struct GNUNET_MysqlStatementHandle *zero_iter; + struct GNUNET_MYSQL_StatementHandle *zero_iter; #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" - struct GNUNET_MysqlStatementHandle *select_expiration; + struct GNUNET_MYSQL_StatementHandle *select_expiration; #define SELECT_IT_PRIORITY "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_prio) ORDER BY prio ASC LIMIT 1" - struct GNUNET_MysqlStatementHandle *select_priority; + struct GNUNET_MYSQL_StatementHandle *select_priority; #define SELECT_IT_REPLICATION "SELECT type,prio,anonLevel,expire,hash,value,uid "\ "FROM gn090 FORCE INDEX (idx_repl_rvalue) "\ @@ -254,510 +203,15 @@ struct Plugin " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_repl_rvalue) WHERE repl=? AND rvalue>=?)) "\ "ORDER BY rvalue ASC "\ "LIMIT 1" - struct GNUNET_MysqlStatementHandle *select_replication; + struct GNUNET_MYSQL_StatementHandle *select_replication; #define SELECT_MAX_REPL "SELECT MAX(repl) FROM gn090" - struct GNUNET_MysqlStatementHandle *max_repl; - -}; - - -/** - * Obtain the location of ".my.cnf". - * - * @param cfg our configuration - * @return NULL on error - */ -static char * -get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - char *cnffile; - char *home_dir; - struct stat st; - -#ifndef WINDOWS - struct passwd *pw; -#endif - int configured; - -#ifndef WINDOWS - pw = getpwuid (getuid ()); - if (!pw) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getpwuid"); - return NULL; - } - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (cfg, "datastore-mysql", "CONFIG")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_filename (cfg, - "datastore-mysql", - "CONFIG", - &cnffile)); - configured = GNUNET_YES; - } - else - { - home_dir = GNUNET_strdup (pw->pw_dir); - GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); - GNUNET_free (home_dir); - configured = GNUNET_NO; - } -#else - home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1); - plibc_conv_to_win_path ("~/", home_dir); - GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); - GNUNET_free (home_dir); - configured = GNUNET_NO; -#endif - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Trying to use file `%s' for MySQL configuration.\n"), cnffile); - if ((0 != STAT (cnffile, &st)) || (0 != ACCESS (cnffile, R_OK)) || - (!S_ISREG (st.st_mode))) - { - if (configured == GNUNET_YES) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not access file `%s': %s\n"), cnffile, - STRERROR (errno)); - GNUNET_free (cnffile); - return NULL; - } - return cnffile; -} - - -/** - * Close database connection and all prepared statements (we got a DB - * disconnect error). - * - * @param plugin plugin context - */ -static int -iclose (struct Plugin *plugin) -{ - struct GNUNET_MysqlStatementHandle *s; - - for (s = plugin->shead; s != NULL; s = s->next) - { - if (s->valid) - { - mysql_stmt_close (s->statement); - s->valid = GNUNET_NO; - } - } - if (plugin->dbf != NULL) - { - mysql_close (plugin->dbf); - plugin->dbf = NULL; - } - return GNUNET_OK; -} - - -/** - * Open the connection with the database (and initialize - * our default options). - * - * @param plugin plugin context - * @return GNUNET_OK on success - */ -static int -iopen (struct Plugin *plugin) -{ - char *mysql_dbname; - char *mysql_server; - char *mysql_user; - char *mysql_password; - unsigned long long mysql_port; - my_bool reconnect; - unsigned int timeout; - - plugin->dbf = mysql_init (NULL); - if (plugin->dbf == NULL) - return GNUNET_SYSERR; - if (plugin->cnffile != NULL) - mysql_options (plugin->dbf, MYSQL_READ_DEFAULT_FILE, plugin->cnffile); - mysql_options (plugin->dbf, MYSQL_READ_DEFAULT_GROUP, "client"); - reconnect = 0; - mysql_options (plugin->dbf, MYSQL_OPT_RECONNECT, &reconnect); - timeout = 120; /* in seconds */ - mysql_options (plugin->dbf, MYSQL_OPT_CONNECT_TIMEOUT, - (const void *) &timeout); - mysql_options (plugin->dbf, MYSQL_SET_CHARSET_NAME, "UTF8"); - timeout = 60; /* in seconds */ - mysql_options (plugin->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout); - mysql_options (plugin->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout); - mysql_dbname = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "DATABASE")) - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-mysql", - "DATABASE", - &mysql_dbname)); - else - mysql_dbname = GNUNET_strdup ("gnunet"); - mysql_user = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "USER")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-mysql", - "USER", &mysql_user)); - } - mysql_password = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "PASSWORD")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-mysql", - "PASSWORD", - &mysql_password)); - } - mysql_server = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "HOST")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-mysql", - "HOST", - &mysql_server)); - } - mysql_port = 0; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "PORT")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, - "datastore-mysql", - "PORT", &mysql_port)); - } + struct GNUNET_MYSQL_StatementHandle *max_repl; - GNUNET_assert (mysql_dbname != NULL); - mysql_real_connect (plugin->dbf, mysql_server, mysql_user, mysql_password, - mysql_dbname, (unsigned int) mysql_port, NULL, - CLIENT_IGNORE_SIGPIPE); - GNUNET_free_non_null (mysql_server); - GNUNET_free_non_null (mysql_user); - GNUNET_free_non_null (mysql_password); - GNUNET_free (mysql_dbname); - if (mysql_error (plugin->dbf)[0]) - { - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_real_connect", plugin); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} +#define GET_ALL_KEYS "SELECT hash from gn090" + struct GNUNET_MYSQL_StatementHandle *get_all_keys; - -/** - * Run the given MySQL statement. - * - * @param plugin plugin context - * @param statement SQL statement to run - * @return GNUNET_OK on success, GNUNET_SYSERR on error - */ -static int -run_statement (struct Plugin *plugin, const char *statement) -{ - if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) - return GNUNET_SYSERR; - mysql_query (plugin->dbf, statement); - if (mysql_error (plugin->dbf)[0]) - { - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_query", plugin); - iclose (plugin); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Create a prepared statement. - * - * @param plugin plugin context - * @param statement SQL statement text to prepare - * @return NULL on error - */ -static struct GNUNET_MysqlStatementHandle * -prepared_statement_create (struct Plugin *plugin, const char *statement) -{ - struct GNUNET_MysqlStatementHandle *ret; - - ret = GNUNET_malloc (sizeof (struct GNUNET_MysqlStatementHandle)); - ret->query = GNUNET_strdup (statement); - GNUNET_CONTAINER_DLL_insert (plugin->shead, plugin->stail, ret); - return ret; -} - - -/** - * Prepare a statement for running. - * - * @param plugin plugin context - * @param ret handle to prepared statement - * @return GNUNET_OK on success - */ -static int -prepare_statement (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *ret) -{ - if (GNUNET_YES == ret->valid) - return GNUNET_OK; - if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) - return GNUNET_SYSERR; - ret->statement = mysql_stmt_init (plugin->dbf); - if (ret->statement == NULL) - { - iclose (plugin); - return GNUNET_SYSERR; - } - if (mysql_stmt_prepare (ret->statement, ret->query, strlen (ret->query))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", - _("Failed to prepare statement `%s'\n"), ret->query); - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", plugin); - mysql_stmt_close (ret->statement); - ret->statement = NULL; - iclose (plugin); - return GNUNET_SYSERR; - } - ret->valid = GNUNET_YES; - return GNUNET_OK; - -} - - -/** - * Bind the parameters for the given MySQL statement - * and run it. - * - * @param plugin plugin context - * @param s statement to bind and run - * @param ap arguments for the binding - * @return GNUNET_SYSERR on error, GNUNET_OK on success - */ -static int -init_params (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *s, - va_list ap) -{ - MYSQL_BIND qbind[MAX_PARAM]; - unsigned int pc; - unsigned int off; - enum enum_field_types ft; - - pc = mysql_stmt_param_count (s->statement); - if (pc > MAX_PARAM) - { - /* increase internal constant! */ - GNUNET_break (0); - return GNUNET_SYSERR; - } - memset (qbind, 0, sizeof (qbind)); - off = 0; - ft = 0; - while ((pc > 0) && (-1 != (int) (ft = va_arg (ap, enum enum_field_types)))) - { - qbind[off].buffer_type = ft; - switch (ft) - { - case MYSQL_TYPE_FLOAT: - qbind[off].buffer = va_arg (ap, float *); - - break; - case MYSQL_TYPE_LONGLONG: - qbind[off].buffer = va_arg (ap, unsigned long long *); - qbind[off].is_unsigned = va_arg (ap, int); - - break; - case MYSQL_TYPE_LONG: - qbind[off].buffer = va_arg (ap, unsigned int *); - qbind[off].is_unsigned = va_arg (ap, int); - - break; - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_BLOB: - qbind[off].buffer = va_arg (ap, void *); - qbind[off].buffer_length = va_arg (ap, unsigned long); - qbind[off].length = va_arg (ap, unsigned long *); - - break; - default: - /* unsupported type */ - GNUNET_break (0); - return GNUNET_SYSERR; - } - pc--; - off++; - } - if (!((pc == 0) && (-1 != (int) ft) && (va_arg (ap, int) == -1))) - { - GNUNET_assert (0); - return GNUNET_SYSERR; - } - if (mysql_stmt_bind_param (s->statement, qbind)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_param", __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - if (mysql_stmt_execute (s->statement)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' for `%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_execute", s->query, __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Run a prepared SELECT statement. - * - * @param plugin plugin context - * @param s statement to run - * @param result_size number of elements in results array - * @param results pointer to already initialized MYSQL_BIND - * array (of sufficient size) for passing results - * @param ap pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective - * values (size + buffer-reference for pointers); terminated - * with "-1" - * @return GNUNET_SYSERR on error, otherwise GNUNET_OK or GNUNET_NO (no result) - */ -static int -prepared_statement_run_select_va (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s, - unsigned int result_size, - MYSQL_BIND * results, va_list ap) -{ - int ret; - unsigned int rsize; - - if (GNUNET_OK != prepare_statement (plugin, s)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != init_params (plugin, s, ap)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - rsize = mysql_stmt_field_count (s->statement); - if (rsize > result_size) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (mysql_stmt_bind_result (s->statement, results)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_result", __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - ret = mysql_stmt_fetch (s->statement); - if (ret == MYSQL_NO_DATA) - return GNUNET_NO; - if (ret != 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_fetch", - __FILE__, __LINE__, mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - mysql_stmt_reset (s->statement); - return GNUNET_OK; -} - - -/** - * Run a prepared SELECT statement. - * - * @param plugin plugin context - * @param s statement to run - * @param result_size number of elements in results array - * @param results pointer to already initialized MYSQL_BIND - * array (of sufficient size) for passing results - * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective - * values (size + buffer-reference for pointers); terminated - * with "-1" - * @return GNUNET_SYSERR on error, otherwise - * the number of successfully affected (or queried) rows - */ -static int -prepared_statement_run_select (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s, - unsigned int result_size, MYSQL_BIND * results, - ...) -{ - va_list ap; - int ret; - - va_start (ap, results); - ret = prepared_statement_run_select_va (plugin, s, result_size, results, ap); - va_end (ap); - return ret; -} - - -/** - * Run a prepared statement that does NOT produce results. - * - * @param plugin plugin context - * @param s statement to run - * @param insert_id NULL or address where to store the row ID of whatever - * was inserted (only for INSERT statements!) - * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective - * values (size + buffer-reference for pointers); terminated - * with "-1" - * @return GNUNET_SYSERR on error, otherwise - * the number of successfully affected rows - */ -static int -prepared_statement_run (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s, - unsigned long long *insert_id, ...) -{ - va_list ap; - int affected; - - if (GNUNET_OK != prepare_statement (plugin, s)) - return GNUNET_SYSERR; - va_start (ap, insert_id); - if (GNUNET_OK != init_params (plugin, s, ap)) - { - va_end (ap); - return GNUNET_SYSERR; - } - va_end (ap); - affected = mysql_stmt_affected_rows (s->statement); - if (NULL != insert_id) - *insert_id = (unsigned long long) mysql_stmt_insert_id (s->statement); - mysql_stmt_reset (s->statement); - return affected; -} +}; /** @@ -772,13 +226,11 @@ do_delete_entry (struct Plugin *plugin, unsigned long long uid) { int ret; -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting value %llu from gn090 table\n", uid); -#endif - ret = - prepared_statement_run (plugin, plugin->delete_entry_by_uid, NULL, - MYSQL_TYPE_LONGLONG, &uid, GNUNET_YES, -1); + ret = GNUNET_MYSQL_statement_run_prepared (plugin->mc, + plugin->delete_entry_by_uid, NULL, + MYSQL_TYPE_LONGLONG, &uid, GNUNET_YES, -1); if (ret >= 0) return GNUNET_OK; GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -807,7 +259,7 @@ mysql_plugin_estimate_size (void *cls) cbind[0].buffer = &total; cbind[0].is_unsigned = GNUNET_NO; if (GNUNET_OK != - prepared_statement_run_select (plugin, plugin->get_size, 1, cbind, -1)) + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->get_size, 1, cbind, NULL, NULL, -1)) return 0; return total; } @@ -857,7 +309,7 @@ mysql_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, lsize = size; GNUNET_CRYPTO_hash (data, size, &vhash); if (GNUNET_OK != - prepared_statement_run (plugin, plugin->insert_entry, NULL, + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->insert_entry, NULL, MYSQL_TYPE_LONG, &irepl, GNUNET_YES, MYSQL_TYPE_LONG, &type, GNUNET_YES, MYSQL_TYPE_LONG, &ipriority, GNUNET_YES, @@ -868,11 +320,9 @@ mysql_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, MYSQL_TYPE_BLOB, &vhash, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, data, lsize, &lsize, -1)) return GNUNET_SYSERR; -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Inserted value `%s' with size %u into gn090 table\n", GNUNET_h2s (key), (unsigned int) size); -#endif if (size > 0) plugin->env->duc (plugin->env->cls, size); return GNUNET_OK; @@ -911,14 +361,12 @@ mysql_plugin_update (void *cls, uint64_t uid, int delta, unsigned long long lexpire = expire.abs_value; int ret; -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating value %llu adding %d to priority and maxing exp at %llu\n", vkey, delta, lexpire); -#endif ret = - prepared_statement_run (plugin, plugin->update_entry, NULL, - MYSQL_TYPE_LONG, &delta, GNUNET_NO, + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->update_entry, NULL, + MYSQL_TYPE_LONG, &delta, GNUNET_NO, MYSQL_TYPE_LONGLONG, &lexpire, GNUNET_YES, MYSQL_TYPE_LONGLONG, &lexpire, GNUNET_YES, MYSQL_TYPE_LONGLONG, &vkey, GNUNET_YES, -1); @@ -942,7 +390,7 @@ mysql_plugin_update (void *cls, uint64_t uid, int delta, * @param ... arguments to initialize stmt */ static void -execute_select (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *stmt, +execute_select (struct Plugin *plugin, struct GNUNET_MYSQL_StatementHandle *stmt, PluginDatumProcessor proc, void *proc_cls, ...) { va_list ap; @@ -986,7 +434,7 @@ execute_select (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *stmt, rbind[6].is_unsigned = 1; va_start (ap, proc_cls); - ret = prepared_statement_run_select_va (plugin, stmt, 7, rbind, ap); + ret = GNUNET_MYSQL_statement_run_prepared_select_va (plugin->mc, stmt, 7, rbind, NULL, NULL, ap); va_end (ap); if (ret <= 0) { @@ -1001,11 +449,9 @@ execute_select (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *stmt, proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u-byte value under key `%s' with prio %u, anon %u, expire %llu selecting from gn090 table\n", (unsigned int) size, GNUNET_h2s (&key), priority, anonymity, exp); -#endif GNUNET_assert (size < MAX_DATUM_SIZE); expiration.abs_value = exp; ret = @@ -1067,10 +513,10 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, if (vhash != NULL) { ret = - prepared_statement_run_select (plugin, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin-> count_entry_by_hash_vhash_and_type, 1, - cbind, MYSQL_TYPE_BLOB, key, hashSize, + cbind, NULL, NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, vhash, hashSize2, &hashSize2, MYSQL_TYPE_LONG, &type, GNUNET_YES, -1); @@ -1078,9 +524,9 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, else { ret = - prepared_statement_run_select (plugin, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_entry_by_hash_and_type, - 1, cbind, MYSQL_TYPE_BLOB, key, + 1, cbind, NULL, NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_LONG, &type, GNUNET_YES, -1); } @@ -1090,9 +536,9 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, if (vhash != NULL) { ret = - prepared_statement_run_select (plugin, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_entry_by_hash_and_vhash, - 1, cbind, MYSQL_TYPE_BLOB, key, + 1, cbind, NULL, NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, vhash, hashSize2, &hashSize2, -1); @@ -1100,8 +546,8 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, else { ret = - prepared_statement_run_select (plugin, plugin->count_entry_by_hash, 1, - cbind, MYSQL_TYPE_BLOB, key, hashSize, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_entry_by_hash, 1, + cbind, NULL, NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, -1); } } @@ -1112,12 +558,9 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, } offset = offset % total; off = (unsigned long long) offset; -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Obtaining %llu/%lld result for GET `%s'\n", off, total, GNUNET_h2s (key)); -#endif - if (type != GNUNET_BLOCK_TYPE_ANY) { if (NULL != vhash) @@ -1244,8 +687,8 @@ repl_proc (void *cls, const GNUNET_HashCode * key, uint32_t size, { oid = (unsigned long long) uid; iret = - prepared_statement_run (plugin, plugin->dec_repl, NULL, - MYSQL_TYPE_LONGLONG, &oid, GNUNET_YES, -1); + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->dec_repl, NULL, + MYSQL_TYPE_LONGLONG, &oid, GNUNET_YES, -1); if (iret == GNUNET_SYSERR) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -1287,7 +730,7 @@ mysql_plugin_get_replication (void *cls, PluginDatumProcessor proc, results.is_unsigned = GNUNET_YES; if (1 != - prepared_statement_run_select (plugin, plugin->max_repl, 1, &results, -1)) + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->max_repl, 1, &results, NULL, NULL, -1)) { proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; @@ -1324,19 +767,18 @@ mysql_plugin_get_keys (void *cls, MYSQL_BIND cbind[1]; unsigned long length; - statement = mysql_stmt_init (plugin->dbf); + statement = GNUNET_MYSQL_statement_get_stmt (plugin->mc, + plugin->get_all_keys); if (statement == NULL) { - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } if (mysql_stmt_prepare (statement, query, strlen (query))) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", _("Failed to prepare statement `%s'\n"), query); - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", plugin); - mysql_stmt_close (statement); - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } GNUNET_assert (proc != NULL); @@ -1346,8 +788,7 @@ mysql_plugin_get_keys (void *cls, _("`%s' for `%s' failed at %s:%d with error: %s\n"), "mysql_stmt_execute", query, __FILE__, __LINE__, mysql_stmt_error (statement)); - mysql_stmt_close (statement); - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } memset (cbind, 0, sizeof (cbind)); @@ -1362,7 +803,7 @@ mysql_plugin_get_keys (void *cls, _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_bind_result", __FILE__, __LINE__, mysql_stmt_error (statement)); - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } while (0 == (ret = mysql_stmt_fetch (statement))) @@ -1376,11 +817,10 @@ mysql_plugin_get_keys (void *cls, _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_fetch", __FILE__, __LINE__, mysql_stmt_error (statement)); - mysql_stmt_close (statement); - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } - mysql_stmt_close (statement); + mysql_stmt_reset (statement); } @@ -1484,7 +924,7 @@ mysql_plugin_drop (void *cls) { struct Plugin *plugin = cls; - if (GNUNET_OK != run_statement (plugin, "DROP TABLE gn090")) + if (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, "DROP TABLE gn090")) return; /* error */ plugin->env->duc (plugin->env->cls, 0); } @@ -1505,16 +945,14 @@ libgnunet_plugin_datastore_mysql_init (void *cls) plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->env = env; - plugin->cnffile = get_my_cnf_path (env->cfg); - if (GNUNET_OK != iopen (plugin)) + plugin->mc = GNUNET_MYSQL_context_create (env->cfg, "datastore-mysql"); + if (NULL == plugin->mc) { - iclose (plugin); - GNUNET_free_non_null (plugin->cnffile); GNUNET_free (plugin); return NULL; } -#define MRUNS(a) (GNUNET_OK != run_statement (plugin, a) ) -#define PINIT(a,b) (NULL == (a = prepared_statement_create(plugin, b))) +#define MRUNS(a) (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, a) ) +#define PINIT(a,b) (NULL == (a = GNUNET_MYSQL_statement_prepare (plugin->mc, b))) if (MRUNS ("CREATE TABLE IF NOT EXISTS gn090 (" " repl INT(11) UNSIGNED NOT NULL DEFAULT 0," @@ -1556,10 +994,10 @@ libgnunet_plugin_datastore_mysql_init (void *cls) PINIT (plugin->select_expiration, SELECT_IT_EXPIRATION) || PINIT (plugin->select_priority, SELECT_IT_PRIORITY) || PINIT (plugin->max_repl, SELECT_MAX_REPL) || + PINIT (plugin->get_all_keys, GET_ALL_KEYS) || PINIT (plugin->select_replication, SELECT_IT_REPLICATION)) { - iclose (plugin); - GNUNET_free_non_null (plugin->cnffile); + GNUNET_MYSQL_context_destroy (plugin->mc); GNUNET_free (plugin); return NULL; } @@ -1593,19 +1031,10 @@ libgnunet_plugin_datastore_mysql_done (void *cls) { struct GNUNET_DATASTORE_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; - struct GNUNET_MysqlStatementHandle *s; - iclose (plugin); - while (NULL != (s = plugin->shead)) - { - GNUNET_CONTAINER_DLL_remove (plugin->shead, plugin->stail, s); - GNUNET_free (s->query); - GNUNET_free (s); - } - GNUNET_free_non_null (plugin->cnffile); + GNUNET_MYSQL_context_destroy (plugin->mc); GNUNET_free (plugin); GNUNET_free (api); - mysql_library_end (); return NULL; } diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c index 16393c2..6dec314 100644 --- a/src/datastore/plugin_datastore_postgres.c +++ b/src/datastore/plugin_datastore_postgres.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -26,9 +26,9 @@ #include "platform.h" #include "gnunet_datastore_plugin.h" +#include "gnunet_postgres_lib.h" #include -#define DEBUG_POSTGRES GNUNET_EXTRA_LOGGING /** * After how many ms "busy" should a DB operation fail for good? @@ -61,87 +61,6 @@ struct Plugin }; -/** - * Check if the result obtained from Postgres has - * the desired status code. If not, log an error, clear the - * result and return GNUNET_SYSERR. - * - * @param plugin global context - * @param ret result to check - * @param expected_status expected return value - * @param command name of SQL command that was run - * @param args arguments to SQL command - * @param line line number for error reporting - * @return GNUNET_OK if the result is acceptable - */ -static int -check_result (struct Plugin *plugin, PGresult * ret, int expected_status, - const char *command, const char *args, int line) -{ - if (ret == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "datastore-postgres", - "Postgres failed to allocate result for `%s:%s' at %d\n", - command, args, line); - return GNUNET_SYSERR; - } - if (PQresultStatus (ret) != expected_status) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "datastore-postgres", - _("`%s:%s' failed at %s:%d with error: %s"), command, args, - __FILE__, line, PQerrorMessage (plugin->dbh)); - PQclear (ret); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - -/** - * Run simple SQL statement (without results). - * - * @param plugin global context - * @param sql statement to run - * @param line code line for error reporting - */ -static int -pq_exec (struct Plugin *plugin, const char *sql, int line) -{ - PGresult *ret; - - ret = PQexec (plugin->dbh, sql); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexec", sql, line)) - return GNUNET_SYSERR; - PQclear (ret); - return GNUNET_OK; -} - -/** - * Prepare SQL statement. - * - * @param plugin global context - * @param name name for the prepared SQL statement - * @param sql SQL code to prepare - * @param nparams number of parameters in sql - * @param line code line for error reporting - * @return GNUNET_OK on success - */ -static int -pq_prepare (struct Plugin *plugin, const char *name, const char *sql, - int nparams, int line) -{ - PGresult *ret; - - ret = PQprepare (plugin->dbh, name, sql, nparams, NULL); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQprepare", sql, line)) - return GNUNET_SYSERR; - PQclear (ret); - return GNUNET_OK; -} - /** * @brief Get a database handle * @@ -151,33 +70,11 @@ pq_prepare (struct Plugin *plugin, const char *name, const char *sql, static int init_connection (struct Plugin *plugin) { - char *conninfo; PGresult *ret; - /* Open database and precompile statements */ - conninfo = NULL; - (void) GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-postgres", "CONFIG", - &conninfo); - plugin->dbh = PQconnectdb (conninfo == NULL ? "" : conninfo); + plugin->dbh = GNUNET_POSTGRES_connect (plugin->env->cfg, "datastore-postgres"); if (NULL == plugin->dbh) - { - /* FIXME: warn about out-of-memory? */ - GNUNET_free_non_null (conninfo); - return GNUNET_SYSERR; - } - if (PQstatus (plugin->dbh) != CONNECTION_OK) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "datastore-postgres", - _ - ("Unable to initialize Postgres with configuration `%s': %s"), - conninfo, PQerrorMessage (plugin->dbh)); - PQfinish (plugin->dbh); - plugin->dbh = NULL; - GNUNET_free_non_null (conninfo); return GNUNET_SYSERR; - } - GNUNET_free_non_null (conninfo); ret = PQexec (plugin->dbh, "CREATE TABLE gn090 (" " repl INTEGER NOT NULL DEFAULT 0," @@ -194,8 +91,7 @@ init_connection (struct Plugin *plugin) (ret, PG_DIAG_SQLSTATE))))) { - (void) check_result (plugin, ret, PGRES_COMMAND_OK, "CREATE TABLE", "gn090", - __LINE__); + (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "CREATE TABLE", "gn090"); PQfinish (plugin->dbh); plugin->dbh = NULL; return GNUNET_SYSERR; @@ -203,29 +99,23 @@ init_connection (struct Plugin *plugin) if (PQresultStatus (ret) == PGRES_COMMAND_OK) { if ((GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_hash ON gn090 (hash)", __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_hash ON gn090 (hash)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_hash_vhash ON gn090 (hash,vhash)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_hash_vhash ON gn090 (hash,vhash)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_prio ON gn090 (prio)", __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_prio ON gn090 (prio)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_expire ON gn090 (expire)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_expire ON gn090 (expire)")) || (GNUNET_OK != - pq_exec (plugin, - "CREATE INDEX idx_prio_anon ON gn090 (prio,anonLevel)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, + "CREATE INDEX idx_prio_anon ON gn090 (prio,anonLevel)")) || (GNUNET_OK != - pq_exec (plugin, - "CREATE INDEX idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, + "CREATE INDEX idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_repl_rvalue ON gn090 (repl,rvalue)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_repl_rvalue ON gn090 (repl,rvalue)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_expire_hash ON gn090 (expire,hash)", - __LINE__))) + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_expire_hash ON gn090 (expire,hash)"))) { PQclear (ret); PQfinish (plugin->dbh); @@ -238,8 +128,7 @@ init_connection (struct Plugin *plugin) PQexec (plugin->dbh, "ALTER TABLE gn090 ALTER value SET STORAGE EXTERNAL"); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -248,8 +137,7 @@ init_connection (struct Plugin *plugin) PQclear (ret); ret = PQexec (plugin->dbh, "ALTER TABLE gn090 ALTER hash SET STORAGE PLAIN"); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -258,8 +146,7 @@ init_connection (struct Plugin *plugin) PQclear (ret); ret = PQexec (plugin->dbh, "ALTER TABLE gn090 ALTER vhash SET STORAGE PLAIN"); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -267,60 +154,56 @@ init_connection (struct Plugin *plugin) } PQclear (ret); if ((GNUNET_OK != - pq_prepare (plugin, "getvt", + GNUNET_POSTGRES_prepare (plugin->dbh, "getvt", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE hash=$1 AND vhash=$2 AND type=$3 " - "ORDER BY oid ASC LIMIT 1 OFFSET $4", 4, __LINE__)) || + "ORDER BY oid ASC LIMIT 1 OFFSET $4", 4)) || (GNUNET_OK != - pq_prepare (plugin, "gett", + GNUNET_POSTGRES_prepare (plugin->dbh, "gett", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE hash=$1 AND type=$2 " - "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3, __LINE__)) || + "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3)) || (GNUNET_OK != - pq_prepare (plugin, "getv", + GNUNET_POSTGRES_prepare (plugin->dbh, "getv", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE hash=$1 AND vhash=$2 " - "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3, __LINE__)) || + "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3)) || (GNUNET_OK != - pq_prepare (plugin, "get", + GNUNET_POSTGRES_prepare (plugin->dbh, "get", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " - "WHERE hash=$1 " "ORDER BY oid ASC LIMIT 1 OFFSET $2", 2, - __LINE__)) || + "WHERE hash=$1 " "ORDER BY oid ASC LIMIT 1 OFFSET $2", 2)) || (GNUNET_OK != - pq_prepare (plugin, "put", + GNUNET_POSTGRES_prepare (plugin->dbh, "put", "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) " - "VALUES ($1, $2, $3, $4, $5, RANDOM(), $6, $7, $8)", 9, - __LINE__)) || + "VALUES ($1, $2, $3, $4, $5, RANDOM(), $6, $7, $8)", 9)) || (GNUNET_OK != - pq_prepare (plugin, "update", + GNUNET_POSTGRES_prepare (plugin->dbh, "update", "UPDATE gn090 SET prio = prio + $1, expire = CASE WHEN expire < $2 THEN $2 ELSE expire END " - "WHERE oid = $3", 3, __LINE__)) || + "WHERE oid = $3", 3)) || (GNUNET_OK != - pq_prepare (plugin, "decrepl", + GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl", "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) " - "WHERE oid = $1", 1, __LINE__)) || + "WHERE oid = $1", 1)) || (GNUNET_OK != - pq_prepare (plugin, "select_non_anonymous", + GNUNET_POSTGRES_prepare (plugin->dbh, "select_non_anonymous", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE anonLevel = 0 AND type = $1 ORDER BY oid DESC LIMIT 1 OFFSET $2", - 1, __LINE__)) || + 1)) || (GNUNET_OK != - pq_prepare (plugin, "select_expiration_order", + GNUNET_POSTGRES_prepare (plugin->dbh, "select_expiration_order", "(SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) " "UNION " "(SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "ORDER BY prio ASC LIMIT 1) " "ORDER BY expire ASC LIMIT 1", - 1, __LINE__)) || + 1)) || (GNUNET_OK != - pq_prepare (plugin, "select_replication_order", + GNUNET_POSTGRES_prepare (plugin->dbh, "select_replication_order", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " - "ORDER BY repl DESC,RANDOM() LIMIT 1", 0, __LINE__)) || + "ORDER BY repl DESC,RANDOM() LIMIT 1", 0)) || (GNUNET_OK != - pq_prepare (plugin, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1, - __LINE__)) || + GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1)) || (GNUNET_OK != - pq_prepare (plugin, "get_keys", "SELECT hash FROM gn090", 0, - __LINE__))) + GNUNET_POSTGRES_prepare (plugin->dbh, "get_keys", "SELECT hash FROM gn090", 0))) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -330,38 +213,6 @@ init_connection (struct Plugin *plugin) } -/** - * Delete the row identified by the given rowid (qid - * in postgres). - * - * @param plugin global context - * @param rowid which row to delete - * @return GNUNET_OK on success - */ -static int -delete_by_rowid (struct Plugin *plugin, unsigned int rowid) -{ - uint32_t browid; - const char *paramValues[] = { (const char *) &browid }; - int paramLengths[] = { sizeof (browid) }; - const int paramFormats[] = { 1 }; - PGresult *ret; - - browid = htonl (rowid); - ret = - PQexecPrepared (plugin->dbh, "delrow", 1, paramValues, paramLengths, - paramFormats, 1); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "delrow", - __LINE__)) - { - return GNUNET_SYSERR; - } - PQclear (ret); - return GNUNET_OK; -} - - /** * Get an estimate of how much space the database is * currently using. @@ -381,18 +232,22 @@ postgres_plugin_estimate_size (void *cls) "SELECT SUM(LENGTH(value))+256*COUNT(*) FROM gn090", 0, NULL, NULL, NULL, NULL, 1); if (GNUNET_OK != - check_result (plugin, ret, PGRES_TUPLES_OK, "PQexecParams", "get_size", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_TUPLES_OK, "PQexecParams", "get_size")) { return 0; } - if ((PQntuples (ret) != 1) || (PQnfields (ret) != 1) || - (PQgetlength (ret, 0, 0) != sizeof (unsigned long long))) + if ((PQntuples (ret) != 1) || (PQnfields (ret) != 1) ) { GNUNET_break (0); PQclear (ret); return 0; } + if (PQgetlength (ret, 0, 0) != sizeof (unsigned long long)) + { + GNUNET_break (0 == PQgetlength (ret, 0, 0)); + PQclear (ret); + return 0; + } total = GNUNET_ntohll (*(const unsigned long long *) PQgetvalue (ret, 0, 0)); PQclear (ret); return total; @@ -402,7 +257,7 @@ postgres_plugin_estimate_size (void *cls) /** * Store an item in the datastore. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param key key for the item * @param size number of bytes in data * @param data content stored @@ -457,15 +312,12 @@ postgres_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, PQexecPrepared (plugin->dbh, "put", 8, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put")) return GNUNET_SYSERR; PQclear (ret); plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD); -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Stored %u bytes in database\n", (unsigned int) size); -#endif return GNUNET_OK; } @@ -478,11 +330,13 @@ postgres_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, * @param proc function to call the value (once only). * @param proc_cls closure for proc * @param res result from exec + * @param filename filename for error messages * @param line line number for error messages */ static void process_result (struct Plugin *plugin, PluginDatumProcessor proc, - void *proc_cls, PGresult * res, int line) + void *proc_cls, PGresult * res, + const char *filename, int line) { int iret; enum GNUNET_BLOCK_Type type; @@ -494,13 +348,11 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, GNUNET_HashCode key; if (GNUNET_OK != - check_result (plugin, res, PGRES_TUPLES_OK, "PQexecPrepared", "select", - line)) + GNUNET_POSTGRES_check_result_ (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "select", + filename, line)) { -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Ending iteration (postgres error)\n"); -#endif proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } @@ -508,10 +360,8 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, if (0 == PQntuples (res)) { /* no result */ -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Ending iteration (no more results)\n"); -#endif proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); PQclear (res); return; @@ -534,7 +384,7 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, { GNUNET_break (0); PQclear (res); - delete_by_rowid (plugin, rowid); + GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", rowid); proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } @@ -546,11 +396,9 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, 0, 3)); memcpy (&key, PQgetvalue (res, 0, 4), sizeof (GNUNET_HashCode)); size = PQgetlength (res, 0, 5); -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Found result of size %u bytes and type %u in database\n", (unsigned int) size, (unsigned int) type); -#endif iret = proc (proc_cls, &key, size, PQgetvalue (res, 0, 5), (enum GNUNET_BLOCK_Type) type, priority, anonymity, expiration_time, @@ -558,23 +406,17 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, PQclear (res); if (iret == GNUNET_NO) { -#if DEBUG_POSTGRES GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processor asked for item %u to be removed.\n", rowid); -#endif - if (GNUNET_OK == delete_by_rowid (plugin, rowid)) + if (GNUNET_OK == GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", rowid)) { -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Deleting %u bytes from database\n", (unsigned int) size); -#endif plugin->env->duc (plugin->env->cls, -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD)); -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Deleted %u bytes from database\n", (unsigned int) size); -#endif } } } @@ -584,7 +426,7 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, * Iterate over the results for a particular key * in the datastore. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param offset offset of the result (modulo num-results); * specific ordering does not matter for the offset * @param key maybe NULL (to match all entries) @@ -679,8 +521,7 @@ postgres_plugin_get_key (void *cls, uint64_t offset, } } if (GNUNET_OK != - check_result (plugin, ret, PGRES_TUPLES_OK, "PQexecParams", pname, - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_TUPLES_OK, "PQexecParams", pname)) { proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; @@ -704,7 +545,7 @@ postgres_plugin_get_key (void *cls, uint64_t offset, ret = PQexecPrepared (plugin->dbh, pname, nparams, paramValues, paramLengths, paramFormats, 1); - process_result (plugin, proc, proc_cls, ret, __LINE__); + process_result (plugin, proc, proc_cls, ret, __FILE__, __LINE__); } @@ -739,7 +580,7 @@ postgres_plugin_get_zero_anonymity (void *cls, uint64_t offset, ret = PQexecPrepared (plugin->dbh, "select_non_anonymous", 2, paramValues, paramLengths, paramFormats, 1); - process_result (plugin, proc, proc_cls, ret, __LINE__); + process_result (plugin, proc, proc_cls, ret, __FILE__, __LINE__); } @@ -771,7 +612,7 @@ struct ReplCtx * Decrements the replication counter and calls the original * iterator. * - * @param cls closure + * @param cls closure with the 'struct ReplCtx*' * @param key key for the content * @param size number of bytes in data * @param data content stored @@ -815,8 +656,8 @@ repl_proc (void *cls, const GNUNET_HashCode * key, uint32_t size, PQexecPrepared (plugin->dbh, "decrepl", 1, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != - check_result (plugin, qret, PGRES_COMMAND_OK, "PQexecPrepared", - "decrepl", __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, qret, PGRES_COMMAND_OK, "PQexecPrepared", + "decrepl")) return GNUNET_SYSERR; PQclear (qret); } @@ -830,7 +671,7 @@ repl_proc (void *cls, const GNUNET_HashCode * key, uint32_t size, * replication counter is decremented by one IF it was positive before. * Call 'proc' with all values ZERO or NULL if the datastore is empty. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param proc function to call the value (once only). * @param proc_cls closure for proc */ @@ -848,7 +689,7 @@ postgres_plugin_get_replication (void *cls, PluginDatumProcessor proc, ret = PQexecPrepared (plugin->dbh, "select_replication_order", 0, NULL, NULL, NULL, 1); - process_result (plugin, &repl_proc, &rc, ret, __LINE__); + process_result (plugin, &repl_proc, &rc, ret, __FILE__, __LINE__); } @@ -856,7 +697,7 @@ postgres_plugin_get_replication (void *cls, PluginDatumProcessor proc, * Get a random item for expiration. * Call 'proc' with all values ZERO or NULL if the datastore is empty. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param proc function to call the value (once only). * @param proc_cls closure for proc */ @@ -875,7 +716,7 @@ postgres_plugin_get_expiration (void *cls, PluginDatumProcessor proc, ret = PQexecPrepared (plugin->dbh, "select_expiration_order", 1, paramValues, paramLengths, paramFormats, 1); - process_result (plugin, proc, proc_cls, ret, __LINE__); + process_result (plugin, proc, proc_cls, ret, __FILE__, __LINE__); } @@ -928,8 +769,7 @@ postgres_plugin_update (void *cls, uint64_t uid, int delta, PQexecPrepared (plugin->dbh, "update", 3, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "update", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "update")) return GNUNET_SYSERR; PQclear (ret); return GNUNET_OK; @@ -940,7 +780,7 @@ postgres_plugin_update (void *cls, uint64_t uid, int delta, /** * Get all of the keys in the datastore. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param proc function to call on each key * @param proc_cls closure for proc */ @@ -972,13 +812,16 @@ postgres_plugin_get_keys (void *cls, /** * Drop database. + * + * @param cls closure with the 'struct Plugin' */ static void postgres_plugin_drop (void *cls) { struct Plugin *plugin = cls; - - pq_exec (plugin, "DROP TABLE gn090", __LINE__); + + if (GNUNET_OK != GNUNET_POSTGRES_exec (plugin->dbh, "DROP TABLE gn090")) + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "postgres", _("Failed to drop table from database.\n")); } diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c index cd5ae39..00195fb 100644 --- a/src/datastore/plugin_datastore_sqlite.c +++ b/src/datastore/plugin_datastore_sqlite.c @@ -28,10 +28,6 @@ #include "gnunet_datastore_plugin.h" #include -/** - * Enable or disable logging debug messages. - */ -#define DEBUG_SQLITE GNUNET_EXTRA_LOGGING /** * We allocate items on the stack at times. To prevent a stack @@ -147,10 +143,8 @@ sq_prepare (sqlite3 * dbh, const char *zSql, sqlite3_stmt ** ppStmt) result = sqlite3_prepare_v2 (dbh, zSql, strlen (zSql), ppStmt, (const char **) &dummy); -#if DEBUG_SQLITE && 0 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Prepared `%s' / %p: %d\n", zSql, *ppStmt, result); -#endif return result; } @@ -415,10 +409,8 @@ database_shutdown (struct Plugin *plugin) stmt = sqlite3_next_stmt (plugin->dbh, NULL); while (stmt != NULL) { -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Closing statement %p\n", stmt); -#endif result = sqlite3_finalize (stmt); if (result != SQLITE_OK) GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite", @@ -502,14 +494,12 @@ sqlite_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, if (size > MAX_ITEM_SIZE) return GNUNET_SYSERR; -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Storing in database block with type %u/key `%s'/priority %u/expiration in %llu ms (%lld).\n", type, GNUNET_h2s (key), priority, (unsigned long long) GNUNET_TIME_absolute_get_remaining (expiration).rel_value, (long long) expiration.abs_value); -#endif GNUNET_CRYPTO_hash (data, size, &vhash); stmt = plugin->insertContent; rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); @@ -540,11 +530,9 @@ sqlite_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, { case SQLITE_DONE: plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD); -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Stored new entry (%u bytes)\n", size + GNUNET_DATASTORE_ENTRY_OVERHEAD); -#endif ret = GNUNET_OK; break; case SQLITE_BUSY: @@ -621,9 +609,7 @@ sqlite_plugin_update (void *cls, uint64_t uid, int delta, switch (n) { case SQLITE_DONE: -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Block updated\n"); -#endif return GNUNET_OK; case SQLITE_BUSY: LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, @@ -677,11 +663,9 @@ execute_get (struct Plugin *plugin, sqlite3_stmt * stmt, break; } expiration.abs_value = sqlite3_column_int64 (stmt, 3); -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Found reply in database with expiration %llu\n", (unsigned long long) expiration.abs_value); -#endif ret = proc (proc_cls, sqlite3_column_blob (stmt, 4) /* key */ , size, sqlite3_column_blob (stmt, 5) /* data */ , sqlite3_column_int (stmt, 0) /* type */ , @@ -972,10 +956,8 @@ sqlite_plugin_get_replication (void *cls, PluginDatumProcessor proc, uint32_t repl; sqlite3_stmt *stmt; -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Getting random block based on replication order.\n"); -#endif rc.have_uid = GNUNET_NO; rc.proc = proc; rc.proc_cls = proc_cls; @@ -1061,10 +1043,8 @@ sqlite_plugin_get_expiration (void *cls, PluginDatumProcessor proc, sqlite3_stmt *stmt; struct GNUNET_TIME_Absolute now; -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Getting random block based on expiration and priority order.\n"); -#endif now = GNUNET_TIME_absolute_get (); stmt = plugin->selExpi; if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, now.abs_value)) @@ -1233,18 +1213,13 @@ libgnunet_plugin_datastore_sqlite_done (void *cls) struct GNUNET_DATASTORE_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "sqlite plugin is done\n"); -#endif - fn = NULL; if (plugin->drop_on_shutdown) fn = GNUNET_strdup (plugin->fn); -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Shutting down database\n"); -#endif database_shutdown (plugin); plugin->env = NULL; GNUNET_free (api); @@ -1254,10 +1229,8 @@ libgnunet_plugin_datastore_sqlite_done (void *cls) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); GNUNET_free (fn); } -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "sqlite plugin is finished\n"); -#endif return NULL; } diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c index 25836ca..4c07366 100644 --- a/src/datastore/test_datastore_api.c +++ b/src/datastore/test_datastore_api.c @@ -462,12 +462,14 @@ run_tests (void *cls, int32_t success, struct GNUNET_TIME_Absolute min_expiratio return; case GNUNET_NO: FPRINTF (stderr, "%s", "Test 'put' operation failed, key already exists (!?)\n"); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); return; case GNUNET_SYSERR: FPRINTF (stderr, "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n", msg); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); return; default: @@ -544,7 +546,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; #endif if (ok != 0) diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c index 4015c2c..bb3898e 100644 --- a/src/datastore/test_datastore_api_management.c +++ b/src/datastore/test_datastore_api_management.c @@ -253,8 +253,9 @@ run_tests (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, c if (success != GNUNET_YES) { FPRINTF (stderr, - "Test 'put' operation failed with error `%s' database likely not setup, skipping test.", + "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n", msg); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); return; } @@ -328,7 +329,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; if (ok != 0) FPRINTF (stderr, "Missed some testcases: %u\n", ok); diff --git a/src/datastore/test_defaults.conf b/src/datastore/test_defaults.conf index 113d6bb..ce27c01 100644 --- a/src/datastore/test_defaults.conf +++ b/src/datastore/test_defaults.conf @@ -28,3 +28,6 @@ AUTOSTART = NO [dv] AUTOSTART = NO + +[namestore] +AUTOSTART = NO diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index 93880c2..b2d18d2 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am @@ -50,6 +50,7 @@ libgnunet_plugin_block_dht_la_DEPENDENCIES = \ bin_PROGRAMS = \ gnunet-service-dht \ + gnunet-dht-monitor \ gnunet-dht-get \ gnunet-dht-put @@ -92,6 +93,16 @@ gnunet_dht_put_LDADD = \ gnunet_dht_put_DEPENDENCIES = \ libgnunetdht.la +gnunet_dht_monitor_SOURCES = \ + gnunet-dht-monitor.c +gnunet_dht_monitor_LDADD = \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/util/libgnunetutil.la +gnunet_dht_monitor_DEPENDENCIES = \ + libgnunetdht.la + + check_PROGRAMS = \ test_dht_api \ test_dht_twopeer \ diff --git a/src/dht/Makefile.in b/src/dht/Makefile.in index 97e9c59..12ce558 100644 --- a/src/dht/Makefile.in +++ b/src/dht/Makefile.in @@ -37,8 +37,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -bin_PROGRAMS = gnunet-service-dht$(EXEEXT) gnunet-dht-get$(EXEEXT) \ - gnunet-dht-put$(EXEEXT) +bin_PROGRAMS = gnunet-service-dht$(EXEEXT) gnunet-dht-monitor$(EXEEXT) \ + gnunet-dht-get$(EXEEXT) gnunet-dht-put$(EXEEXT) check_PROGRAMS = test_dht_api$(EXEEXT) test_dht_twopeer$(EXEEXT) \ test_dht_twopeer_put_get$(EXEEXT) \ test_dht_twopeer_get_put$(EXEEXT) \ @@ -123,6 +123,8 @@ libgnunetdht_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ PROGRAMS = $(bin_PROGRAMS) am_gnunet_dht_get_OBJECTS = gnunet-dht-get.$(OBJEXT) gnunet_dht_get_OBJECTS = $(am_gnunet_dht_get_OBJECTS) +am_gnunet_dht_monitor_OBJECTS = gnunet-dht-monitor.$(OBJEXT) +gnunet_dht_monitor_OBJECTS = $(am_gnunet_dht_monitor_OBJECTS) am_gnunet_dht_put_OBJECTS = gnunet-dht-put.$(OBJEXT) gnunet_dht_put_OBJECTS = $(am_gnunet_dht_put_OBJECTS) am_gnunet_service_dht_OBJECTS = gnunet-service-dht.$(OBJEXT) \ @@ -208,19 +210,21 @@ am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgnunet_plugin_block_dht_la_SOURCES) \ $(libgnunetdht_la_SOURCES) $(gnunet_dht_get_SOURCES) \ - $(gnunet_dht_put_SOURCES) $(gnunet_service_dht_SOURCES) \ - $(test_dht_2dtorus_SOURCES) $(test_dht_api_SOURCES) \ - $(test_dht_line_SOURCES) $(test_dht_monitor_SOURCES) \ - $(test_dht_multipeer_SOURCES) $(test_dht_twopeer_SOURCES) \ + $(gnunet_dht_monitor_SOURCES) $(gnunet_dht_put_SOURCES) \ + $(gnunet_service_dht_SOURCES) $(test_dht_2dtorus_SOURCES) \ + $(test_dht_api_SOURCES) $(test_dht_line_SOURCES) \ + $(test_dht_monitor_SOURCES) $(test_dht_multipeer_SOURCES) \ + $(test_dht_twopeer_SOURCES) \ $(test_dht_twopeer_get_put_SOURCES) \ $(test_dht_twopeer_path_tracking_SOURCES) \ $(test_dht_twopeer_put_get_SOURCES) DIST_SOURCES = $(libgnunet_plugin_block_dht_la_SOURCES) \ $(libgnunetdht_la_SOURCES) $(gnunet_dht_get_SOURCES) \ - $(gnunet_dht_put_SOURCES) $(gnunet_service_dht_SOURCES) \ - $(test_dht_2dtorus_SOURCES) $(test_dht_api_SOURCES) \ - $(test_dht_line_SOURCES) $(test_dht_monitor_SOURCES) \ - $(test_dht_multipeer_SOURCES) $(test_dht_twopeer_SOURCES) \ + $(gnunet_dht_monitor_SOURCES) $(gnunet_dht_put_SOURCES) \ + $(gnunet_service_dht_SOURCES) $(test_dht_2dtorus_SOURCES) \ + $(test_dht_api_SOURCES) $(test_dht_line_SOURCES) \ + $(test_dht_monitor_SOURCES) $(test_dht_multipeer_SOURCES) \ + $(test_dht_twopeer_SOURCES) \ $(test_dht_twopeer_get_put_SOURCES) \ $(test_dht_twopeer_path_tracking_SOURCES) \ $(test_dht_twopeer_put_get_SOURCES) @@ -285,6 +289,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -318,6 +323,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -519,6 +525,17 @@ gnunet_dht_put_LDADD = \ gnunet_dht_put_DEPENDENCIES = \ libgnunetdht.la +gnunet_dht_monitor_SOURCES = \ + gnunet-dht-monitor.c + +gnunet_dht_monitor_LDADD = \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/util/libgnunetutil.la + +gnunet_dht_monitor_DEPENDENCIES = \ + libgnunetdht.la + test_dht_api_SOURCES = \ test_dht_api.c @@ -778,6 +795,9 @@ clean-checkPROGRAMS: gnunet-dht-get$(EXEEXT): $(gnunet_dht_get_OBJECTS) $(gnunet_dht_get_DEPENDENCIES) @rm -f gnunet-dht-get$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_dht_get_OBJECTS) $(gnunet_dht_get_LDADD) $(LIBS) +gnunet-dht-monitor$(EXEEXT): $(gnunet_dht_monitor_OBJECTS) $(gnunet_dht_monitor_DEPENDENCIES) + @rm -f gnunet-dht-monitor$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_dht_monitor_OBJECTS) $(gnunet_dht_monitor_LDADD) $(LIBS) gnunet-dht-put$(EXEEXT): $(gnunet_dht_put_OBJECTS) $(gnunet_dht_put_DEPENDENCIES) @rm -f gnunet-dht-put$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_dht_put_OBJECTS) $(gnunet_dht_put_LDADD) $(LIBS) @@ -820,6 +840,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht_api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-dht-get.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-dht-monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-dht-put.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-dht.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-dht_clients.Po@am__quote@ diff --git a/src/dht/dht.conf.in b/src/dht/dht.conf.in index 17c13e9..59581dc 100644 --- a/src/dht/dht.conf.in +++ b/src/dht/dht.conf.in @@ -1,6 +1,6 @@ [dht] AUTOSTART = YES -@UNIXONLY@ PORT = 2095 +@JAVAPORT@PORT = 2095 HOSTNAME = localhost HOME = $SERVICEHOME CONFIG = $DEFAULTCONFIG diff --git a/src/dht/dht.h b/src/dht/dht.h index 9894be8..8adf49f 100644 --- a/src/dht/dht.h +++ b/src/dht/dht.h @@ -180,6 +180,11 @@ struct GNUNET_DHT_ClientPutMessage */ uint32_t desired_replication_level GNUNET_PACKED; + /** + * Unique ID for the PUT message. + */ + uint64_t unique_id GNUNET_PACKED; + /** * How long should this data persist? */ @@ -196,26 +201,54 @@ struct GNUNET_DHT_ClientPutMessage /** - * Message to monitor requests going through peer, clients <--> DHT service. + * Message to confirming receipt of PUT, sent from DHT service to clients. */ -struct GNUNET_DHT_MonitorMessage +struct GNUNET_DHT_ClientPutConfirmationMessage { /** - * Type: GNUNET_MESSAGE_TYPE_DHT_MONITOR_{GET, PUT, GET_RESP, PUT_RESP*} - * (*) not yet implemented, necessary for key randomization + * Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK */ struct GNUNET_MessageHeader header; /** - * The type of data in the request. + * Always zero. */ - uint32_t type GNUNET_PACKED; + uint32_t reserved GNUNET_PACKED; + + /** + * Unique ID from the PUT message that is being confirmed. + */ + uint64_t unique_id GNUNET_PACKED; + +}; + + + +/** + * Message to monitor put requests going through peer, DHT service -> clients. + */ +struct GNUNET_DHT_MonitorPutMessage +{ + /** + * Type: GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT + */ + struct GNUNET_MessageHeader header; /** * Message options, actually an 'enum GNUNET_DHT_RouteOption' value. */ uint32_t options GNUNET_PACKED; + /** + * The type of data in the request. + */ + uint32_t type GNUNET_PACKED; + + /** + * Hop count so far. + */ + uint32_t hop_count GNUNET_PACKED; + /** * Replication level for this message */ @@ -223,31 +256,149 @@ struct GNUNET_DHT_MonitorMessage /** * Number of peers recorded in the outgoing path from source to the - * storgage location of this message. + * storage location of this message. */ uint32_t put_path_length GNUNET_PACKED; /** - * The number of peer identities recorded from the storage location - * to this peer. + * How long should this data persist? */ - uint32_t get_path_length GNUNET_PACKED; + struct GNUNET_TIME_AbsoluteNBO expiration_time; /** - * Unique ID for GET / GET responses. + * The key to store the value under. */ - uint64_t unique_id GNUNET_PACKED; + GNUNET_HashCode key; + + /* put path (if tracked) */ + + /* Payload */ +}; + + +/** + * Message to request monitoring messages, clients -> DHT service. + */ +struct GNUNET_DHT_MonitorStartStopMessage +{ /** - * How long should this data persist? + * Type: GNUNET_MESSAGE_TYPE_DHT_MONITOR_(START|STOP) */ - struct GNUNET_TIME_AbsoluteNBO expiration; + struct GNUNET_MessageHeader header; + + /** + * The type of data desired, GNUNET_BLOCK_TYPE_ANY for all. + */ + uint32_t type GNUNET_PACKED; + + /** + * Flag whether to notify about GET messages. + */ + int16_t get GNUNET_PACKED; + + /** + * Flag whether to notify about GET_REPONSE messages. + */ + int16_t get_resp GNUNET_PACKED; + + /** + * Flag whether to notify about PUT messages. + */ + int16_t put GNUNET_PACKED; + + /** + * Flag whether to use the provided key to filter messages. + */ + int16_t filter_key GNUNET_PACKED; + + /** + * The key to filter messages by. + */ + GNUNET_HashCode key; +}; + + +/** + * Message to monitor get requests going through peer, DHT service -> clients. + */ +struct GNUNET_DHT_MonitorGetMessage +{ + /** + * Type: GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT + */ + struct GNUNET_MessageHeader header; + + /** + * Message options, actually an 'enum GNUNET_DHT_RouteOption' value. + */ + uint32_t options GNUNET_PACKED; + + /** + * The type of data in the request. + */ + uint32_t type GNUNET_PACKED; + + /** + * Hop count + */ + uint32_t hop_count GNUNET_PACKED; + + /** + * Replication level for this message + */ + uint32_t desired_replication_level GNUNET_PACKED; + + /** + * Number of peers recorded in the outgoing path from source to the + * storage location of this message. + */ + uint32_t get_path_length GNUNET_PACKED; /** * The key to store the value under. */ GNUNET_HashCode key; + /* get path (if tracked) */ + +}; + +/** + * Message to monitor get results going through peer, DHT service -> clients. + */ +struct GNUNET_DHT_MonitorGetRespMessage +{ + /** + * Type: GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT + */ + struct GNUNET_MessageHeader header; + + /** + * Content type. + */ + uint32_t type GNUNET_PACKED; + + /** + * Length of the PUT path that follows (if tracked). + */ + uint32_t put_path_length GNUNET_PACKED; + + /** + * Length of the GET path that follows (if tracked). + */ + uint32_t get_path_length GNUNET_PACKED; + + /** + * When does the content expire? + */ + struct GNUNET_TIME_AbsoluteNBO expiration_time; + + /** + * The key of the corresponding GET request. + */ + GNUNET_HashCode key; + /* put path (if tracked) */ /* get path (if tracked) */ diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 3cb13b4..420eacb 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -73,11 +73,6 @@ struct PendingMessage */ void *cont_cls; - /** - * Timeout task for this message - */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; - /** * Unique ID for this request */ @@ -99,6 +94,56 @@ struct PendingMessage }; +/** + * Handle to a PUT request. + */ +struct GNUNET_DHT_PutHandle +{ + /** + * Kept in a DLL. + */ + struct GNUNET_DHT_PutHandle *next; + + /** + * Kept in a DLL. + */ + struct GNUNET_DHT_PutHandle *prev; + + /** + * Continuation to call when done. + */ + GNUNET_DHT_PutContinuation cont; + + /** + * Pending message associated with this PUT operation, + * NULL after the message has been transmitted to the service. + */ + struct PendingMessage *pending; + + /** + * Main handle to this DHT api + */ + struct GNUNET_DHT_Handle *dht_handle; + + /** + * Closure for 'cont'. + */ + void *cont_cls; + + /** + * Timeout task for this operation. + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + + /** + * Unique ID for the PUT operation. + */ + uint64_t unique_id; + +}; + + + /** * Handle to a GET request */ @@ -171,9 +216,19 @@ struct GNUNET_DHT_MonitorHandle GNUNET_HashCode *key; /** - * Callback for each received message of interest. + * Callback for each received message of type get. + */ + GNUNET_DHT_MonitorGetCB get_cb; + + /** + * Callback for each received message of type get response. + */ + GNUNET_DHT_MonitorGetRespCB get_resp_cb; + + /** + * Callback for each received message of type put. */ - GNUNET_DHT_MonitorCB cb; + GNUNET_DHT_MonitorPutCB put_cb; /** * Closure for cb. @@ -225,8 +280,18 @@ struct GNUNET_DHT_Handle struct GNUNET_DHT_MonitorHandle *monitor_tail; /** - * Hash map containing the current outstanding unique requests - * (values are of type 'struct GNUNET_DHT_RouteHandle'). + * Head of active PUT requests. + */ + struct GNUNET_DHT_PutHandle *put_head; + + /** + * Tail of active PUT requests. + */ + struct GNUNET_DHT_PutHandle *put_tail; + + /** + * Hash map containing the current outstanding unique GET requests + * (values are of type 'struct GNUNET_DHT_GetHandle'). */ struct GNUNET_CONTAINER_MultiHashMap *active_requests; @@ -257,6 +322,8 @@ struct GNUNET_DHT_Handle * Handler for messages received from the DHT service * a demultiplexer which handles numerous message types * + * @param cls the 'struct GNUNET_DHT_Handle' + * @param msg the incoming message */ static void service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg); @@ -265,16 +332,17 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg); /** * Try to (re)connect to the DHT service. * + * @param handle DHT handle to reconnect * @return GNUNET_YES on success, GNUNET_NO on failure. */ static int try_connect (struct GNUNET_DHT_Handle *handle) { - if (handle->client != NULL) + if (NULL != handle->client) return GNUNET_OK; handle->in_receive = GNUNET_NO; handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg); - if (handle->client == NULL) + if (NULL == handle->client) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to connect to the DHT service!\n")); @@ -314,6 +382,7 @@ add_request_to_pending (void *cls, const GNUNET_HashCode * key, void *value) /** * Try to send messages from list of messages to send + * * @param handle DHT_Handle */ static void @@ -359,17 +428,34 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void do_disconnect (struct GNUNET_DHT_Handle *handle) { - if (handle->client == NULL) + struct GNUNET_DHT_PutHandle *ph; + struct GNUNET_DHT_PutHandle *next; + + if (NULL == handle->client) return; - GNUNET_assert (handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == handle->reconnect_task); if (NULL != handle->th) GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); handle->th = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from DHT service, will try to reconnect in %llu ms\n", (unsigned long long) handle->retry_time.rel_value); - GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (handle->client); handle->client = NULL; + + /* signal disconnect to all PUT requests that were transmitted but waiting + for the put confirmation */ + next = handle->put_head; + while (NULL != (ph = next)) + { + next = ph->next; + if (NULL == ph->pending) + { + if (NULL != ph->cont) + ph->cont (ph->cont_cls, GNUNET_SYSERR); + GNUNET_DHT_put_cancel (ph); + } + } handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->retry_time, &try_reconnect, handle); } @@ -377,6 +463,11 @@ do_disconnect (struct GNUNET_DHT_Handle *handle) /** * Transmit the next pending message, called by notify_transmit_ready + * + * @param cls the DHT handle + * @param size number of bytes available in 'buf' for transmission + * @param buf where to copy messages for the service + * @return number of bytes written to 'buf' */ static size_t transmit_pending (void *cls, size_t size, void *buf); @@ -384,20 +475,22 @@ transmit_pending (void *cls, size_t size, void *buf); /** * Try to send messages from list of messages to send + * + * @param handle handle to DHT */ static void process_pending_messages (struct GNUNET_DHT_Handle *handle) { struct PendingMessage *head; - if (handle->client == NULL) + if (NULL == handle->client) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "process_pending_messages called, but client is null, reconnecting\n"); + "process_pending_messages called, but client is NULL, reconnecting\n"); do_disconnect (handle); return; } - if (handle->th != NULL) + if (NULL != handle->th) return; if (NULL == (head = handle->pending_head)) return; @@ -417,6 +510,11 @@ process_pending_messages (struct GNUNET_DHT_Handle *handle) /** * Transmit the next pending message, called by notify_transmit_ready + * + * @param cls the DHT handle + * @param size number of bytes available in 'buf' for transmission + * @param buf where to copy messages for the service + * @return number of bytes written to 'buf' */ static size_t transmit_pending (void *cls, size_t size, void *buf) @@ -426,7 +524,7 @@ transmit_pending (void *cls, size_t size, void *buf) size_t tsize; handle->th = NULL; - if (buf == NULL) + if (NULL == buf) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission to DHT service failed! Reconnecting!\n"); @@ -446,11 +544,6 @@ transmit_pending (void *cls, size_t size, void *buf) GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, head); head->in_pending_queue = GNUNET_NO; - if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (head->timeout_task); - head->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } if (NULL != head->cont) { head->cont (head->cont_cls, NULL); @@ -533,63 +626,178 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value) return GNUNET_YES; } - /** - * Process a monitoring message from the service. + * Process a get monitor message from the service. * * @param handle The DHT handle. - * @param msg Message from the service. + * @param msg Monitor get message from the service. * * @return GNUNET_OK if everything went fine, * GNUNET_SYSERR if the message is malformed. */ static int -process_monitor_message (struct GNUNET_DHT_Handle *handle, - const struct GNUNET_MessageHeader *msg) +process_monitor_get_message (struct GNUNET_DHT_Handle *handle, + const struct GNUNET_DHT_MonitorGetMessage *msg) { - struct GNUNET_DHT_MonitorMessage *m; struct GNUNET_DHT_MonitorHandle *h; + + for (h = handle->monitor_head; NULL != h; h = h->next) + { + int type_ok; + int key_ok; + + type_ok = (GNUNET_BLOCK_TYPE_ANY == h->type) || (h->type == ntohl(msg->type)); + key_ok = (NULL == h->key) || (0 == memcmp (h->key, &msg->key, + sizeof (GNUNET_HashCode))); + if (type_ok && key_ok && (NULL != h->get_cb)) + h->get_cb (h->cb_cls, + ntohl (msg->options), + (enum GNUNET_BLOCK_Type) ntohl(msg->type), + ntohl (msg->hop_count), + ntohl (msg->desired_replication_level), + ntohl (msg->get_path_length), + (struct GNUNET_PeerIdentity *) &msg[1], + &msg->key); + } + return GNUNET_OK; +} + + +/** + * Process a get response monitor message from the service. + * + * @param handle The DHT handle. + * @param msg monitor get response message from the service + * @return GNUNET_OK if everything went fine, + * GNUNET_SYSERR if the message is malformed. + */ +static int +process_monitor_get_resp_message (struct GNUNET_DHT_Handle *handle, + const struct GNUNET_DHT_MonitorGetRespMessage + *msg) +{ + struct GNUNET_DHT_MonitorHandle *h; + struct GNUNET_PeerIdentity *path; + uint32_t getl; + uint32_t putl; size_t msize; - if (ntohs (msg->type) < GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET || - ntohs (msg->type) > GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT) - return GNUNET_SYSERR; - msize = ntohs (msg->size); - if (msize < sizeof (struct GNUNET_DHT_MonitorMessage)) + msize = ntohs (msg->header.size); + path = (struct GNUNET_PeerIdentity *) &msg[1]; + getl = ntohl (msg->get_path_length); + putl = ntohl (msg->put_path_length); + if ( (getl + putl < getl) || + ( ((msize - sizeof (struct GNUNET_DHT_MonitorGetRespMessage)) / sizeof (struct GNUNET_PeerIdentity)) < getl + putl) ) + { + GNUNET_break (0); return GNUNET_SYSERR; + } + for (h = handle->monitor_head; NULL != h; h = h->next) + { + int type_ok; + int key_ok; + + type_ok = (GNUNET_BLOCK_TYPE_ANY == h->type) || (h->type == ntohl(msg->type)); + key_ok = (NULL == h->key) || (0 == memcmp (h->key, &msg->key, + sizeof (GNUNET_HashCode))); + if (type_ok && key_ok && (NULL != h->get_resp_cb)) + h->get_resp_cb (h->cb_cls, + (enum GNUNET_BLOCK_Type) ntohl(msg->type), + path, getl, + &path[getl], putl, + GNUNET_TIME_absolute_ntoh(msg->expiration_time), + &msg->key, + (void *) &path[getl + putl], + msize - + sizeof (struct GNUNET_DHT_MonitorGetRespMessage) - + sizeof (struct GNUNET_PeerIdentity) * (putl + getl)); + } + return GNUNET_OK; +} - m = (struct GNUNET_DHT_MonitorMessage *) msg; - h = handle->monitor_head; - while (NULL != h) + +/** + * Process a put monitor message from the service. + * + * @param handle The DHT handle. + * @param msg Monitor put message from the service. + * + * @return GNUNET_OK if everything went fine, + * GNUNET_SYSERR if the message is malformed. + */ +static int +process_monitor_put_message (struct GNUNET_DHT_Handle *handle, + const struct GNUNET_DHT_MonitorPutMessage *msg) +{ + struct GNUNET_DHT_MonitorHandle *h; + size_t msize; + struct GNUNET_PeerIdentity *path; + uint32_t putl; + + msize = ntohs (msg->header.size); + path = (struct GNUNET_PeerIdentity *) &msg[1]; + putl = ntohl (msg->put_path_length); + if (((msize - sizeof (struct GNUNET_DHT_MonitorGetRespMessage)) / sizeof (struct GNUNET_PeerIdentity)) < putl) { - if (h->type == ntohl(m->type) && - (NULL == h->key || - memcmp (h->key, &m->key, sizeof (GNUNET_HashCode)) == 0)) - { - struct GNUNET_PeerIdentity *path; - uint32_t getl; - uint32_t putl; - - path = (struct GNUNET_PeerIdentity *) &m[1]; - getl = ntohl (m->get_path_length); - putl = ntohl (m->put_path_length); - h->cb (h->cb_cls, ntohs(msg->type), - GNUNET_TIME_absolute_ntoh(m->expiration), - &m->key, - &path[getl], putl, path, getl, - ntohl (m->desired_replication_level), - ntohl (m->options), ntohl (m->type), - (void *) &path[getl + putl], - ntohs (msg->size) - - sizeof (struct GNUNET_DHT_MonitorMessage) - - sizeof (struct GNUNET_PeerIdentity) * (putl + getl)); - } - h = h->next; + GNUNET_break (0); + return GNUNET_SYSERR; + } + for (h = handle->monitor_head; NULL != h; h = h->next) + { + int type_ok; + int key_ok; + + type_ok = (GNUNET_BLOCK_TYPE_ANY == h->type) || (h->type == ntohl(msg->type)); + key_ok = (NULL == h->key) || (0 == memcmp (h->key, &msg->key, + sizeof (GNUNET_HashCode))); + if (type_ok && key_ok && (NULL != h->put_cb)) + h->put_cb (h->cb_cls, + ntohl (msg->options), + (enum GNUNET_BLOCK_Type) ntohl(msg->type), + ntohl (msg->hop_count), + ntohl (msg->desired_replication_level), + putl, path, + GNUNET_TIME_absolute_ntoh(msg->expiration_time), + &msg->key, + (void *) &path[putl], + msize - + sizeof (struct GNUNET_DHT_MonitorPutMessage) - + sizeof (struct GNUNET_PeerIdentity) * putl); } + return GNUNET_OK; +} + + +/** + * Process a put confirmation message from the service. + * + * @param handle The DHT handle. + * @param msg confirmation message from the service. + * @return GNUNET_OK if everything went fine, + * GNUNET_SYSERR if the message is malformed. + */ +static int +process_put_confirmation_message (struct GNUNET_DHT_Handle *handle, + const struct GNUNET_DHT_ClientPutConfirmationMessage *msg) +{ + struct GNUNET_DHT_PutHandle *ph; + GNUNET_DHT_PutContinuation cont; + void *cont_cls; + for (ph = handle->put_head; NULL != ph; ph = ph->next) + if (ph->unique_id == msg->unique_id) + break; + if (NULL == ph) + return GNUNET_OK; + cont = ph->cont; + cont_cls = ph->cont_cls; + GNUNET_DHT_put_cancel (ph); + if (NULL != cont) + cont (cont_cls, GNUNET_OK); return GNUNET_OK; } + /** * Handler for messages received from the DHT service * a demultiplexer which handles numerous message types @@ -602,38 +810,84 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_DHT_Handle *handle = cls; const struct GNUNET_DHT_ClientResultMessage *dht_msg; + uint16_t msize; + int ret; - if (msg == NULL) + if (NULL == msg) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Error receiving data from DHT service, reconnecting\n"); do_disconnect (handle); return; } - if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT) + ret = GNUNET_SYSERR; + msize = ntohs (msg->size); + switch (ntohs (msg->type)) { - if (process_monitor_message (handle, msg) == GNUNET_OK) + case GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET: + if (msize < sizeof (struct GNUNET_DHT_MonitorGetMessage)) { - GNUNET_CLIENT_receive (handle->client, &service_message_handler, handle, - GNUNET_TIME_UNIT_FOREVER_REL); - return; + GNUNET_break (0); + break; } - GNUNET_break (0); - do_disconnect (handle); - return; + ret = process_monitor_get_message(handle, + (const struct GNUNET_DHT_MonitorGetMessage *) msg); + break; + case GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP: + if (msize < sizeof (struct GNUNET_DHT_MonitorGetRespMessage)) + { + GNUNET_break (0); + break; + } + ret = process_monitor_get_resp_message(handle, + (const struct GNUNET_DHT_MonitorGetRespMessage *) msg); + break; + case GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT: + if (msize < sizeof (struct GNUNET_DHT_MonitorPutMessage)) + { + GNUNET_break (0); + break; + } + ret = process_monitor_put_message(handle, + (const struct GNUNET_DHT_MonitorPutMessage *) msg); + break; + case GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT_RESP: + /* Not implemented yet */ + GNUNET_break(0); + break; + case GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT: + if (ntohs (msg->size) < sizeof (struct GNUNET_DHT_ClientResultMessage)) + { + GNUNET_break (0); + break; + } + ret = GNUNET_OK; + dht_msg = (const struct GNUNET_DHT_ClientResultMessage *) msg; + LOG (GNUNET_ERROR_TYPE_DEBUG, "Received reply for `%s' from DHT service %p\n", + GNUNET_h2s (&dht_msg->key), handle); + GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests, + &dht_msg->key, &process_reply, + (void *) dht_msg); + break; + case GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK: + if (ntohs (msg->size) != sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)) + { + GNUNET_break (0); + break; + } + ret = process_put_confirmation_message (handle, + (const struct GNUNET_DHT_ClientPutConfirmationMessage*) msg); + break; + default: + GNUNET_break(0); + break; } - if (ntohs (msg->size) < sizeof (struct GNUNET_DHT_ClientResultMessage)) + if (GNUNET_OK != ret) { GNUNET_break (0); do_disconnect (handle); return; } - dht_msg = (const struct GNUNET_DHT_ClientResultMessage *) msg; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Received reply for `%s' from DHT service %p\n", - GNUNET_h2s (&dht_msg->key), handle); - GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests, - &dht_msg->key, &process_reply, - (void *) dht_msg); GNUNET_CLIENT_receive (handle->client, &service_message_handler, handle, GNUNET_TIME_UNIT_FOREVER_REL); } @@ -677,11 +931,12 @@ void GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle) { struct PendingMessage *pm; + struct GNUNET_DHT_PutHandle *ph; - GNUNET_assert (handle != NULL); + GNUNET_assert (NULL != handle); GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (handle->active_requests)); - if (handle->th != NULL) + if (NULL != handle->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); handle->th = NULL; @@ -693,18 +948,24 @@ GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle) pm); pm->in_pending_queue = GNUNET_NO; GNUNET_assert (GNUNET_YES == pm->free_on_send); - if (GNUNET_SCHEDULER_NO_TASK != pm->timeout_task) - GNUNET_SCHEDULER_cancel (pm->timeout_task); if (NULL != pm->cont) pm->cont (pm->cont_cls, NULL); GNUNET_free (pm); } - if (handle->client != NULL) + while (NULL != (ph = handle->put_head)) { - GNUNET_CLIENT_disconnect (handle->client, GNUNET_YES); + GNUNET_break (NULL == ph->pending); + if (NULL != ph->cont) + ph->cont (ph->cont_cls, GNUNET_SYSERR); + GNUNET_DHT_put_cancel (ph); + } + + if (NULL != handle->client) + { + GNUNET_CLIENT_disconnect (handle->client); handle->client = NULL; } - if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task) GNUNET_SCHEDULER_cancel (handle->reconnect_task); GNUNET_CONTAINER_multihashmap_destroy (handle->active_requests); GNUNET_free (handle); @@ -720,22 +981,49 @@ GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle) static void timeout_put_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct PendingMessage *pending = cls; - struct GNUNET_DHT_Handle *handle; + struct GNUNET_DHT_PutHandle *ph = cls; + struct GNUNET_DHT_Handle *handle = ph->dht_handle; - handle = pending->handle; - GNUNET_assert (GNUNET_YES == pending->in_pending_queue); - GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, - pending); - pending->in_pending_queue = GNUNET_NO; - if (pending->cont != NULL) - pending->cont (pending->cont_cls, tc); - GNUNET_free (pending); + ph->timeout_task = GNUNET_SCHEDULER_NO_TASK; + if (NULL != ph->pending) + { + GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, + ph->pending); + ph->pending->in_pending_queue = GNUNET_NO; + GNUNET_free (ph->pending); + } + if (NULL != ph->cont) + ph->cont (ph->cont_cls, GNUNET_NO); + GNUNET_CONTAINER_DLL_remove (handle->put_head, + handle->put_tail, + ph); + GNUNET_free (ph); +} + + +/** + * Function called whenever the PUT message leaves the queue. Sets + * the message pointer in the put handle to NULL. + * + * @param cls the 'struct GNUNET_DHT_PutHandle' + * @param tc unused + */ +static void +mark_put_message_gone (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_DHT_PutHandle *ph = cls; + + ph->pending = NULL; } /** - * Perform a PUT operation storing data in the DHT. + * Perform a PUT operation storing data in the DHT. FIXME: we should + * change the protocol to get a confirmation for the PUT from the DHT + * and call 'cont' only after getting the confirmation; otherwise, the + * client has no good way of telling if the 'PUT' message actually got + * to the DHT service! * * @param handle handle to DHT service * @param key the key to store under @@ -748,51 +1036,97 @@ timeout_put_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param exp desired expiration time for the value * @param timeout how long to wait for transmission of this request * @param cont continuation to call when done (transmitting request to service) + * You must not call GNUNET_DHT_DISCONNECT in this continuation * @param cont_cls closure for cont */ -void +struct GNUNET_DHT_PutHandle * GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const GNUNET_HashCode * key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const char *data, struct GNUNET_TIME_Absolute exp, - struct GNUNET_TIME_Relative timeout, GNUNET_SCHEDULER_Task cont, + struct GNUNET_TIME_Relative timeout, GNUNET_DHT_PutContinuation cont, void *cont_cls) { struct GNUNET_DHT_ClientPutMessage *put_msg; size_t msize; struct PendingMessage *pending; + struct GNUNET_DHT_PutHandle *ph; msize = sizeof (struct GNUNET_DHT_ClientPutMessage) + size; if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) { GNUNET_break (0); - if (NULL != cont) - cont (cont_cls, NULL); - return; + return NULL; } + ph = GNUNET_malloc (sizeof (struct GNUNET_DHT_PutHandle)); + ph->dht_handle = handle; + ph->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, &timeout_put_request, ph); + ph->cont = cont; + ph->cont_cls = cont_cls; + ph->unique_id = ++handle->uid_gen; pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); + ph->pending = pending; put_msg = (struct GNUNET_DHT_ClientPutMessage *) &pending[1]; pending->msg = &put_msg->header; pending->handle = handle; - pending->cont = cont; - pending->cont_cls = cont_cls; + pending->cont = &mark_put_message_gone; + pending->cont_cls = ph; pending->free_on_send = GNUNET_YES; - pending->timeout_task = - GNUNET_SCHEDULER_add_delayed (timeout, &timeout_put_request, pending); put_msg->header.size = htons (msize); put_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT); put_msg->type = htonl (type); put_msg->options = htonl ((uint32_t) options); put_msg->desired_replication_level = htonl (desired_replication_level); + put_msg->unique_id = ph->unique_id; put_msg->expiration = GNUNET_TIME_absolute_hton (exp); put_msg->key = *key; memcpy (&put_msg[1], data, size); GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, pending); pending->in_pending_queue = GNUNET_YES; + GNUNET_CONTAINER_DLL_insert_tail (handle->put_head, + handle->put_tail, + ph); process_pending_messages (handle); + return ph; +} + + +/** + * Cancels a DHT PUT operation. Note that the PUT request may still + * go out over the network (we can't stop that); However, if the PUT + * has not yet been sent to the service, cancelling the PUT will stop + * this from happening (but there is no way for the user of this API + * to tell if that is the case). The only use for this API is to + * prevent a later call to 'cont' from "GNUNET_DHT_put" (i.e. because + * the system is shutting down). + * + * @param ph put operation to cancel ('cont' will no longer be called) + */ +void +GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph) +{ + struct GNUNET_DHT_Handle *handle = ph->dht_handle; + + if (NULL != ph->pending) + { + GNUNET_CONTAINER_DLL_remove (handle->pending_head, + handle->pending_tail, + ph->pending); + GNUNET_free (ph->pending); + ph->pending = NULL; + } + if (ph->timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (ph->timeout_task); + ph->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_CONTAINER_DLL_remove (handle->put_head, + handle->put_tail, + ph); + GNUNET_free (ph); } @@ -801,7 +1135,6 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const GNUNET_HashCode * key, * also "GNUNET_BLOCK_evaluate". * * @param handle handle to the DHT service - * @param timeout how long to wait for transmission of this request to the service * @param type expected type of the response object * @param key the key to look up * @param desired_replication_level estimate of how many @@ -815,7 +1148,6 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const GNUNET_HashCode * key, */ struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, - struct GNUNET_TIME_Relative timeout, enum GNUNET_BLOCK_Type type, const GNUNET_HashCode * key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, @@ -847,8 +1179,7 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, get_msg->desired_replication_level = htonl (desired_replication_level); get_msg->type = htonl (type); get_msg->key = *key; - handle->uid_gen++; - get_msg->unique_id = handle->uid_gen; + get_msg->unique_id = ++handle->uid_gen; memcpy (&get_msg[1], xquery, xquery_size); GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, pending); @@ -925,7 +1256,9 @@ GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle) * @param handle Handle to the DHT service. * @param type Type of blocks that are of interest. * @param key Key of data of interest, NULL for all. - * @param cb Callback to process all monitored data. + * @param get_cb Callback to process monitored get messages. + * @param get_resp_cb Callback to process monitored get response messages. + * @param put_cb Callback to process monitored put messages. * @param cb_cls Closure for cb. * * @return Handle to stop monitoring. @@ -934,18 +1267,21 @@ struct GNUNET_DHT_MonitorHandle * GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const GNUNET_HashCode *key, - GNUNET_DHT_MonitorCB cb, + GNUNET_DHT_MonitorGetCB get_cb, + GNUNET_DHT_MonitorGetRespCB get_resp_cb, + GNUNET_DHT_MonitorPutCB put_cb, void *cb_cls) { struct GNUNET_DHT_MonitorHandle *h; - struct GNUNET_DHT_MonitorMessage *m; + struct GNUNET_DHT_MonitorStartStopMessage *m; struct PendingMessage *pending; h = GNUNET_malloc (sizeof (struct GNUNET_DHT_MonitorHandle)); GNUNET_CONTAINER_DLL_insert(handle->monitor_head, handle->monitor_tail, h); - GNUNET_assert (NULL != cb); - h->cb = cb; + h->get_cb = get_cb; + h->get_resp_cb = get_resp_cb; + h->put_cb = put_cb; h->cb_cls = cb_cls; h->type = type; h->dht_handle = handle; @@ -955,17 +1291,22 @@ GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle, memcpy (h->key, key, sizeof(GNUNET_HashCode)); } - pending = GNUNET_malloc (sizeof (struct GNUNET_DHT_MonitorMessage) + + pending = GNUNET_malloc (sizeof (struct GNUNET_DHT_MonitorStartStopMessage) + sizeof (struct PendingMessage)); - m = (struct GNUNET_DHT_MonitorMessage *) &pending[1]; + m = (struct GNUNET_DHT_MonitorStartStopMessage *) &pending[1]; pending->msg = &m->header; pending->handle = handle; pending->free_on_send = GNUNET_YES; - m->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET); - m->header.size = htons (sizeof (struct GNUNET_DHT_MonitorMessage)); + m->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_START); + m->header.size = htons (sizeof (struct GNUNET_DHT_MonitorStartStopMessage)); m->type = htonl(type); - if (NULL != key) + m->get = htons(NULL != get_cb); + m->get_resp = htons(NULL != get_resp_cb); + m->put = htons(NULL != put_cb); + if (NULL != key) { + m->filter_key = htons(1); memcpy (&m->key, key, sizeof(GNUNET_HashCode)); + } GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, pending); pending->in_pending_queue = GNUNET_YES; @@ -985,10 +1326,36 @@ GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle, void GNUNET_DHT_monitor_stop (struct GNUNET_DHT_MonitorHandle *handle) { - GNUNET_free_non_null (handle->key); + struct GNUNET_DHT_MonitorStartStopMessage *m; + struct PendingMessage *pending; + GNUNET_CONTAINER_DLL_remove (handle->dht_handle->monitor_head, handle->dht_handle->monitor_tail, handle); + + pending = GNUNET_malloc (sizeof (struct GNUNET_DHT_MonitorStartStopMessage) + + sizeof (struct PendingMessage)); + m = (struct GNUNET_DHT_MonitorStartStopMessage *) &pending[1]; + pending->msg = &m->header; + pending->handle = handle->dht_handle; + pending->free_on_send = GNUNET_YES; + m->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP); + m->header.size = htons (sizeof (struct GNUNET_DHT_MonitorStartStopMessage)); + m->type = htonl(handle->type); + m->get = htons(NULL != handle->get_cb); + m->get_resp = htons(NULL != handle->get_resp_cb); + m->put = htons(NULL != handle->put_cb); + if (NULL != handle->key) { + m->filter_key = htons(1); + memcpy (&m->key, handle->key, sizeof(GNUNET_HashCode)); + } + GNUNET_CONTAINER_DLL_insert (handle->dht_handle->pending_head, + handle->dht_handle->pending_tail, + pending); + pending->in_pending_queue = GNUNET_YES; + process_pending_messages (handle->dht_handle); + + GNUNET_free_non_null (handle->key); GNUNET_free (handle); } diff --git a/src/dht/gnunet-dht-get.c b/src/dht/gnunet-dht-get.c index 6ad4b30..fb185c4 100644 --- a/src/dht/gnunet-dht-get.c +++ b/src/dht/gnunet-dht-get.c @@ -186,7 +186,7 @@ run (void *cls, char *const *args, const char *cfgfile, GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (absolute_timeout), &cleanup_task, NULL); get_handle = - GNUNET_DHT_get_start (dht_handle, timeout, query_type, &key, replication, + GNUNET_DHT_get_start (dht_handle, query_type, &key, replication, GNUNET_DHT_RO_NONE, NULL, 0, &get_result_iterator, NULL); diff --git a/src/dht/gnunet-dht-monitor.c b/src/dht/gnunet-dht-monitor.c new file mode 100644 index 0000000..8ca3beb --- /dev/null +++ b/src/dht/gnunet-dht-monitor.c @@ -0,0 +1,325 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file dht/gnunet-dht-monitor.c + * @brief search for data in DHT + * @author Christian Grothoff + * @author Bartlomiej Polot + */ +#include "platform.h" +#include "gnunet_dht_service.h" + +/** + * The type of the query + */ +static unsigned int block_type; + +/** + * The key to be monitored + */ +static char *query_key; + +/** + * User supplied timeout value (in seconds) + */ +static unsigned long long timeout_request = 5; + +/** + * Be verbose + */ +static int verbose; + +/** +* Handle to the DHT + */ +static struct GNUNET_DHT_Handle *dht_handle; + +/** + * Global handle of the configuration + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Handle for the get request + */ +static struct GNUNET_DHT_MonitorHandle *monitor_handle; + +/** + * Count of messages received + */ +static unsigned int result_count; + +/** + * Global status value + */ +static int ret; + + +/** + * Function called on shutdown, disconnects from DHT if necessary. + * + * @param cls closure (unused) + * @param tc Task Context + */ +static void +shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (verbose) + FPRINTF (stderr, "%s", "Shutting down!\n"); + if (dht_handle != NULL) + { + GNUNET_DHT_disconnect (dht_handle); + dht_handle = NULL; + } +} + + +/** + * Stop monitoring request and start shutdown + * + * @param cls closure (unused) + * @param tc Task Context + */ +static void +cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (verbose) + FPRINTF (stderr, "%s", "Cleaning up!\n"); + if (monitor_handle != NULL) + { + GNUNET_DHT_monitor_stop (monitor_handle); + monitor_handle = NULL; + } + GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); +} + + +/** + * Callback called on each GET request going through the DHT. + * + * @param cls Closure. + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the GET path (or NULL if not recorded). + * @param desired_replication_level Desired replication level. + * @param key Key of the requested data. + */ +void +get_callback (void *cls, + enum GNUNET_DHT_RouteOption options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + const GNUNET_HashCode * key) +{ + FPRINTF (stdout, "Result %d, operation: %s, type %d\n Key: %s", + result_count, + "GET", + type, + GNUNET_h2s_full(key)); + result_count++; +} + +/** + * Callback called on each GET reply going through the DHT. + * + * @param cls Closure. + * @param type The type of data in the result. + * @param get_path Peers on GET path (or NULL if not recorded). + * @param get_path_length number of entries in get_path. + * @param put_path peers on the PUT path (or NULL if not recorded). + * @param put_path_length number of entries in get_path. + * @param exp Expiration time of the data. + * @param key Key of the data. + * @param data Pointer to the result data. + * @param size Number of bytes in data. + */ +void +get_resp_callback (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size) +{ + FPRINTF (stdout, "Result %d, operation: %s, type %d:\n Key: %s\n %.*s\n", + result_count, + "GET_RESP", + type, + GNUNET_h2s_full(key), + (unsigned int) size, + (char *) data); + result_count++; +} + +/** + * Callback called on each PUT request going through the DHT. + * + * @param cls Closure. + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the PUT path (or NULL if not recorded). + * @param desired_replication_level Desired replication level. + * @param exp Expiration time of the data. + * @param key Key under which data is to be stored. + * @param data Pointer to the data carried. + * @param size Number of bytes in data. + */ +void +put_callback (void *cls, + enum GNUNET_DHT_RouteOption options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size) +{ + FPRINTF (stdout, "Result %d, operation: %s, type %d:\n Key: %s\n %.*s\n", + result_count, + "PUT", + type, + GNUNET_h2s_full(key), + (unsigned int) size, + (char *) data); + result_count++; +} + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param c configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + struct GNUNET_TIME_Relative timeout; + GNUNET_HashCode *key; + + cfg = c; + + dht_handle = GNUNET_DHT_connect (cfg, 1); + + if (dht_handle == NULL) + { + if (verbose) + FPRINTF (stderr, "%s", "Couldn't connect to DHT service!\n"); + ret = 1; + return; + } + else if (verbose) + FPRINTF (stderr, "%s", "Connected to DHT service!\n"); + + if (block_type == GNUNET_BLOCK_TYPE_ANY) /* Type of data not set */ + block_type = GNUNET_BLOCK_TYPE_TEST; + + if (query_key != NULL) { + key = GNUNET_malloc (sizeof(GNUNET_HashCode)); + GNUNET_CRYPTO_hash (query_key, strlen (query_key), key); + } + else + key = NULL; + + if (0 != timeout_request) + { + timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, + timeout_request); + if (verbose) + FPRINTF (stderr, "Monitoring for %llus\n", timeout_request); + } + else + { + timeout = GNUNET_TIME_UNIT_FOREVER_REL; + if (verbose) + FPRINTF (stderr, "%s", "Monitoring indefinitely (close with Ctrl+C)\n"); + } + + GNUNET_SCHEDULER_add_delayed (timeout, &cleanup_task, NULL); + if (verbose) + FPRINTF (stderr, "Issuing MONITOR request for %s!\n", query_key); + monitor_handle = GNUNET_DHT_monitor_start (dht_handle, + block_type, + key, + &get_callback, + &get_resp_callback, + &put_callback, + NULL); + if (verbose) + FPRINTF (stderr, "%s", "MONITOR started!\n"); + GNUNET_free_non_null (key); + +} + + +/** + * gnunet-dht-get command line options + */ +static struct GNUNET_GETOPT_CommandLineOption options[] = { + {'k', "key", "KEY", + gettext_noop ("the query key"), + 1, &GNUNET_GETOPT_set_string, &query_key}, + {'t', "type", "TYPE", + gettext_noop ("the type of data to look for"), + 1, &GNUNET_GETOPT_set_uint, &block_type}, + {'T', "timeout", "TIMEOUT", + gettext_noop ("how long to execute? 0 = forever"), + 1, &GNUNET_GETOPT_set_ulong, &timeout_request}, + {'V', "verbose", NULL, + gettext_noop ("be verbose (print progress information)"), + 0, &GNUNET_GETOPT_set_one, &verbose}, + GNUNET_GETOPT_OPTION_END +}; + + +/** + * Entry point for gnunet-dht-monitor + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + return (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-dht-get", + gettext_noop + ("Prints all packets that go through the DHT."), + options, &run, NULL)) ? ret : 1; +} + +/* end of gnunet-dht-monitor.c */ diff --git a/src/dht/gnunet-dht-put.c b/src/dht/gnunet-dht-put.c index ef5ae5e..59acc79 100644 --- a/src/dht/gnunet-dht-put.c +++ b/src/dht/gnunet-dht-put.c @@ -80,7 +80,7 @@ static char *data; static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - if (dht_handle != NULL) + if (NULL != dht_handle) { GNUNET_DHT_disconnect (dht_handle); dht_handle = NULL; @@ -91,13 +91,33 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * Signature of the main function of a task. * * @param cls closure - * @param tc context information (why was this task triggered now) + * @param success GNUNET_OK if the PUT was transmitted, + * GNUNET_NO on timeout, + * GNUNET_SYSERR on disconnect from service + * after the PUT message was transmitted + * (so we don't know if it was received or not) */ -void -message_sent_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +static void +message_sent_cont (void *cls, int success) { if (verbose) - FPRINTF (stderr, "%s", _("PUT request sent!\n")); + { + switch (success) + { + case GNUNET_OK: + FPRINTF (stderr, "%s", _("PUT request sent!\n")); + break; + case GNUNET_NO: + FPRINTF (stderr, "%s", _("Timeout sending PUT request!\n")); + break; + case GNUNET_SYSERR: + FPRINTF (stderr, "%s", _("PUT request not confirmed!\n")); + break; + default: + GNUNET_break (0); + break; + } + } GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); } diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index 96fcd34..d897d1f 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c @@ -87,7 +87,7 @@ struct ClientList * Handle to the current transmission request, NULL * if none pending. */ - struct GNUNET_CONNECTION_TransmitHandle *transmit_handle; + struct GNUNET_SERVER_TransmitHandle *transmit_handle; /** * Linked list of pending messages for this client @@ -203,6 +203,21 @@ struct ClientMonitorRecord */ GNUNET_HashCode *key; + /** + * Flag whether to notify about GET messages. + */ + int16_t get; + + /** + * Flag whether to notify about GET_REPONSE messages. + */ + int16_t get_resp; + + /** + * Flag whether to notify about PUT messages. + */ + uint16_t put; + /** * Client to notify of these requests. */ @@ -246,6 +261,31 @@ static struct GNUNET_CONTAINER_Heap *retry_heap; static GNUNET_SCHEDULER_TaskIdentifier retry_task; +/** + * Task run to check for messages that need to be sent to a client. + * + * @param client a ClientList, containing the client and any messages to be sent to it + */ +static void +process_pending_messages (struct ClientList *client); + + +/** + * Add a PendingMessage to the clients list of messages to be sent + * + * @param client the active client to send the message to + * @param pending_message the actual message to send + */ +static void +add_pending_message (struct ClientList *client, + struct PendingMessage *pending_message) +{ + GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail, + pending_message); + process_pending_messages (client); +} + + /** * Find a client if it exists, add it otherwise. * @@ -289,11 +329,9 @@ remove_client_records (void *cls, const GNUNET_HashCode * key, void *value) if (record->client != client) return GNUNET_YES; -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing client %p's record for key %s\n", client, GNUNET_h2s (key)); -#endif GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (forward_map, key, record)); @@ -320,13 +358,11 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) struct PendingMessage *reply; struct ClientMonitorRecord *monitor; -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Local client %p disconnects\n", client); -#endif pos = find_active_client (client); GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos); if (pos->transmit_handle != NULL) - GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->transmit_handle); + GNUNET_SERVER_notify_transmit_ready_cancel (pos->transmit_handle); while (NULL != (reply = pos->pending_head)) { GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply); @@ -449,6 +485,8 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_DHT_ClientPutMessage *dht_msg; struct GNUNET_CONTAINER_BloomFilter *peer_bf; uint16_t size; + struct PendingMessage *pm; + struct GNUNET_DHT_ClientPutConfirmationMessage *conf; size = ntohs (message->size); if (size < sizeof (struct GNUNET_DHT_ClientPutMessage)) @@ -463,12 +501,10 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_NO); dht_msg = (const struct GNUNET_DHT_ClientPutMessage *) message; /* give to local clients */ -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Handling local PUT of %u-bytes for query %s\n", size - sizeof (struct GNUNET_DHT_ClientPutMessage), GNUNET_h2s (&dht_msg->key)); -#endif GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), &dht_msg->key, 0, NULL, 0, NULL, ntohl (dht_msg->type), @@ -490,7 +526,26 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, peer_bf, &dht_msg->key, 0, NULL, &dht_msg[1], size - sizeof (struct GNUNET_DHT_ClientPutMessage)); + GDS_CLIENTS_process_put (ntohl (dht_msg->options), + ntohl (dht_msg->type), + 0, + ntohl (dht_msg->desired_replication_level), + 1, + GDS_NEIGHBOURS_get_id(), + GNUNET_TIME_absolute_ntoh (dht_msg->expiration), + &dht_msg->key, + &dht_msg[1], + size - sizeof (struct GNUNET_DHT_ClientPutMessage)); GNUNET_CONTAINER_bloomfilter_free (peer_bf); + pm = GNUNET_malloc (sizeof (struct PendingMessage) + + sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); + conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1]; + conf->header.size = htons (sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); + conf->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK); + conf->reserved = htonl (0); + conf->unique_id = dht_msg->unique_id; + pm->msg = &conf->header; + add_pending_message (find_active_client (client), pm); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -528,11 +583,9 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, gettext_noop ("# GET requests received from clients"), 1, GNUNET_NO); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received request for %s from local client %p\n", GNUNET_h2s (&get->key), client); -#endif cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size); cqr->key = get->key; cqr->client = find_active_client (client); @@ -548,6 +601,13 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, cqr->type = ntohl (get->type); GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GDS_CLIENTS_process_get (ntohl (get->options), + ntohl (get->type), + 0, + ntohl (get->desired_replication_level), + 1, + GDS_NEIGHBOURS_get_id(), + &get->key); /* start remote requests */ if (GNUNET_SCHEDULER_NO_TASK != retry_task) GNUNET_SCHEDULER_cancel (retry_task); @@ -593,11 +653,9 @@ remove_by_unique_id (void *cls, const GNUNET_HashCode * key, void *value) if (record->unique_id != ctx->unique_id) return GNUNET_YES; -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing client %p's record for key %s (by unique id)\n", ctx->client->client_handle, GNUNET_h2s (key)); -#endif return remove_client_records (ctx->client, key, record); } @@ -623,10 +681,8 @@ handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client, gettext_noop ("# GET STOP requests received from clients"), 1, GNUNET_NO); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p stopped request for key %s\n", client, GNUNET_h2s (&dht_stop_msg->key)); -#endif ctx.client = find_active_client (client); ctx.unique_id = dht_stop_msg->unique_id; GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, &dht_stop_msg->key, @@ -636,7 +692,7 @@ handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client, /** - * Handler for monitor messages + * Handler for monitor start messages * * @param cls closure for the service * @param client the client we received this message from @@ -648,37 +704,74 @@ handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { struct ClientMonitorRecord *r; - const struct GNUNET_DHT_MonitorMessage *msg; - unsigned int i; - char *c; + const struct GNUNET_DHT_MonitorStartStopMessage *msg; - msg = (struct GNUNET_DHT_MonitorMessage *) message; + msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message; r = GNUNET_malloc (sizeof(struct ClientMonitorRecord)); r->client = find_active_client(client); r->type = ntohl(msg->type); - c = (char *) &msg->key; - for (i = 0; i < sizeof (GNUNET_HashCode) && c[i] == 0; i++); - if (sizeof (GNUNET_HashCode) == i) - r->key = NULL; + r->get = ntohs(msg->get); + r->get_resp = ntohs(msg->get_resp); + r->put = ntohs(msg->put); + if (0 == ntohs(msg->filter_key)) + r->key = NULL; else { r->key = GNUNET_malloc (sizeof (GNUNET_HashCode)); memcpy (r->key, &msg->key, sizeof (GNUNET_HashCode)); } GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, r); - // FIXME add remove somewhere GNUNET_SERVER_receive_done (client, GNUNET_OK); } - /** - * Task run to check for messages that need to be sent to a client. + * Handler for monitor stop messages + * + * @param cls closure for the service + * @param client the client we received this message from + * @param message the actual message received * - * @param client a ClientList, containing the client and any messages to be sent to it */ static void -process_pending_messages (struct ClientList *client); +handle_dht_local_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + struct ClientMonitorRecord *r; + const struct GNUNET_DHT_MonitorStartStopMessage *msg; + int keys_match; + + msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message; + r = monitor_head; + + while (NULL != r) + { + if (NULL == r->key) + keys_match = (0 == ntohs(msg->filter_key)); + else + { + keys_match = (0 != ntohs(msg->filter_key) + && !memcmp(r->key, &msg->key, sizeof(GNUNET_HashCode))); + } + if (find_active_client(client) == r->client + && ntohl(msg->type) == r->type + && r->get == msg->get + && r->get_resp == msg->get_resp + && r->put == msg->put + && keys_match + ) + { + GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, r); + GNUNET_free_non_null (r->key); + GNUNET_free (r); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; /* Delete only ONE entry */ + } + r = r->next; + } + + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} /** @@ -706,11 +799,9 @@ send_reply_to_client (void *cls, size_t size, void *buf) if (buf == NULL) { /* client disconnected */ -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected, pending messages will be discarded\n", client->client_handle); -#endif return 0; } off = 0; @@ -721,17 +812,13 @@ send_reply_to_client (void *cls, size_t size, void *buf) reply); memcpy (&cbuf[off], reply->msg, msize); GNUNET_free (reply); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u bytes to client %p\n", msize, client->client_handle); -#endif off += msize; } process_pending_messages (client); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitted %u/%u bytes to client %p\n", (unsigned int) off, (unsigned int) size, client->client_handle); -#endif return off; } @@ -746,20 +833,16 @@ process_pending_messages (struct ClientList *client) { if ((client->pending_head == NULL) || (client->transmit_handle != NULL)) { -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not asking for transmission to %p now: %s\n", client->client_handle, client->pending_head == NULL ? "no more messages" : "request already pending"); -#endif return; } -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking for transmission of %u bytes to client %p\n", ntohs (client->pending_head->msg->size), client->client_handle); -#endif client->transmit_handle = GNUNET_SERVER_notify_transmit_ready (client->client_handle, ntohs (client->pending_head-> @@ -769,22 +852,6 @@ process_pending_messages (struct ClientList *client) } -/** - * Add a PendingMessage to the clients list of messages to be sent - * - * @param client the active client to send the message to - * @param pending_message the actual message to send - */ -static void -add_pending_message (struct ClientList *client, - struct PendingMessage *pending_message) -{ - GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail, - pending_message); - process_pending_messages (client); -} - - /** * Closure for 'forward_reply' */ @@ -844,11 +911,9 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type)) { -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record type missmatch, not passing request for key %s to local client\n", GNUNET_h2s (key)); -#endif GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# Key match, type mismatches in REPLY to CLIENT"), @@ -859,11 +924,9 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) for (i = 0; i < record->seen_replies_count; i++) if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (GNUNET_HashCode))) { -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Duplicate reply, not passing request for key %s to local client\n", GNUNET_h2s (key)); -#endif GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# Duplicate REPLIES to CLIENT request dropped"), @@ -874,11 +937,9 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_BLOCK_evaluate (GDS_block_context, record->type, key, NULL, 0, record->xquery, record->xquery_size, frc->data, frc->data_size); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Evaluation result is %d for key %s for local client's query\n", (int) eval, GNUNET_h2s (key)); -#endif switch (eval) { case GNUNET_BLOCK_EVALUATION_OK_LAST: @@ -929,11 +990,9 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_NO); reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; reply->unique_id = record->unique_id; -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing reply to query %s for client %p\n", GNUNET_h2s (key), record->client->client_handle); -#endif add_pending_message (record->client, pm); if (GNUNET_YES == do_free) remove_client_records (record->client, key, record); @@ -1027,33 +1086,101 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, /** - * Check if some client is monitoring messages of this type and notify - * him in that case. + * Check if some client is monitoring GET messages and notify + * them in that case. * - * @param mtype Type of the DHT message. - * @param exp When will this value expire. - * @param key Key of the result/request. - * @param putl number of entries in get_path. - * @param put_path peers on the PUT path (or NULL if not recorded). - * @param getl number of entries in get_path. - * @param get_path Peers on reply path (or NULL if not recorded). + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the GET path (or NULL if not recorded). * @param desired_replication_level Desired replication level. - * @param type Type of the result/request. + * @param key Key of the requested data. + */ +void +GDS_CLIENTS_process_get (uint32_t options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + const GNUNET_HashCode * key) +{ + struct ClientMonitorRecord *m; + struct ClientList **cl; + unsigned int cl_size; + + cl = NULL; + cl_size = 0; + for (m = monitor_head; NULL != m; m = m->next) + { + if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && + (NULL == m->key || + memcmp (key, m->key, sizeof(GNUNET_HashCode)) == 0)) + { + struct PendingMessage *pm; + struct GNUNET_DHT_MonitorGetMessage *mmsg; + struct GNUNET_PeerIdentity *msg_path; + size_t msize; + unsigned int i; + + /* Don't send duplicates */ + for (i = 0; i < cl_size; i++) + if (cl[i] == m->client) + break; + if (i < cl_size) + continue; + GNUNET_array_append (cl, cl_size, m->client); + + msize = path_length * sizeof (struct GNUNET_PeerIdentity); + msize += sizeof (struct GNUNET_DHT_MonitorGetMessage); + msize += sizeof (struct PendingMessage); + pm = (struct PendingMessage *) GNUNET_malloc (msize); + mmsg = (struct GNUNET_DHT_MonitorGetMessage *) &pm[1]; + pm->msg = &mmsg->header; + mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); + mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET); + mmsg->options = htonl(options); + mmsg->type = htonl(type); + mmsg->hop_count = htonl(hop_count); + mmsg->desired_replication_level = htonl(desired_replication_level); + mmsg->get_path_length = htonl(path_length); + memcpy (&mmsg->key, key, sizeof (GNUNET_HashCode)); + msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; + if (path_length > 0) + memcpy (msg_path, path, + path_length * sizeof (struct GNUNET_PeerIdentity)); + add_pending_message (m->client, pm); + } + } + GNUNET_free_non_null (cl); +} + + +/** + * Check if some client is monitoring GET RESP messages and notify + * them in that case. + * + * @param type The type of data in the result. + * @param get_path Peers on GET path (or NULL if not recorded). + * @param get_path_length number of entries in get_path. + * @param put_path peers on the PUT path (or NULL if not recorded). + * @param put_path_length number of entries in get_path. + * @param exp Expiration time of the data. + * @param key Key of the data. * @param data Pointer to the result data. * @param size Number of bytes in data. */ void -GDS_CLIENTS_process_monitor (uint16_t mtype, - const struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode *key, - uint32_t putl, - const struct GNUNET_PeerIdentity *put_path, - uint32_t getl, - const struct GNUNET_PeerIdentity *get_path, - uint32_t desired_replication_level, - enum GNUNET_BLOCK_Type type, - const struct GNUNET_MessageHeader *data, - uint16_t size) +GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size) { struct ClientMonitorRecord *m; struct ClientList **cl; @@ -1068,7 +1195,7 @@ GDS_CLIENTS_process_monitor (uint16_t mtype, memcmp (key, m->key, sizeof(GNUNET_HashCode)) == 0)) { struct PendingMessage *pm; - struct GNUNET_DHT_MonitorMessage *mmsg; + struct GNUNET_DHT_MonitorGetRespMessage *mmsg; struct GNUNET_PeerIdentity *path; size_t msize; unsigned int i; @@ -1082,29 +1209,116 @@ GDS_CLIENTS_process_monitor (uint16_t mtype, GNUNET_array_append (cl, cl_size, m->client); msize = size; - msize += (getl + putl) * sizeof (struct GNUNET_PeerIdentity); - msize += sizeof (struct GNUNET_DHT_MonitorMessage); + msize += (get_path_length + put_path_length) + * sizeof (struct GNUNET_PeerIdentity); + msize += sizeof (struct GNUNET_DHT_MonitorGetRespMessage); msize += sizeof (struct PendingMessage); pm = (struct PendingMessage *) GNUNET_malloc (msize); - mmsg = (struct GNUNET_DHT_MonitorMessage *) &pm[1]; + mmsg = (struct GNUNET_DHT_MonitorGetRespMessage *) &pm[1]; pm->msg = (struct GNUNET_MessageHeader *) mmsg; mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); - mmsg->header.type = htons (mtype); - mmsg->expiration = GNUNET_TIME_absolute_hton(exp); - memcpy (&mmsg->key, key, sizeof (GNUNET_HashCode)); - mmsg->put_path_length = htonl(putl); - mmsg->get_path_length = htonl(getl); - mmsg->desired_replication_level = htonl (desired_replication_level); + mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP); + mmsg->type = htonl(type); + mmsg->put_path_length = htonl(put_path_length); + mmsg->get_path_length = htonl(get_path_length); path = (struct GNUNET_PeerIdentity *) &mmsg[1]; - if (putl > 0) + if (put_path_length > 0) + { + memcpy (path, put_path, + put_path_length * sizeof (struct GNUNET_PeerIdentity)); + path = &path[put_path_length]; + } + if (get_path_length > 0) + memcpy (path, get_path, + get_path_length * sizeof (struct GNUNET_PeerIdentity)); + mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp); + memcpy (&mmsg->key, key, sizeof (GNUNET_HashCode)); + if (size > 0) + memcpy (&path[get_path_length], data, size); + add_pending_message (m->client, pm); + } + } + GNUNET_free_non_null (cl); +} + + +/** + * Check if some client is monitoring PUT messages and notify + * them in that case. + * + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the PUT path (or NULL if not recorded). + * @param desired_replication_level Desired replication level. + * @param exp Expiration time of the data. + * @param key Key under which data is to be stored. + * @param data Pointer to the data carried. + * @param size Number of bytes in data. + */ +void +GDS_CLIENTS_process_put (uint32_t options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size) +{ + struct ClientMonitorRecord *m; + struct ClientList **cl; + unsigned int cl_size; + + cl = NULL; + cl_size = 0; + for (m = monitor_head; NULL != m; m = m->next) + { + if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && + (NULL == m->key || + memcmp (key, m->key, sizeof(GNUNET_HashCode)) == 0)) + { + struct PendingMessage *pm; + struct GNUNET_DHT_MonitorPutMessage *mmsg; + struct GNUNET_PeerIdentity *msg_path; + size_t msize; + unsigned int i; + + /* Don't send duplicates */ + for (i = 0; i < cl_size; i++) + if (cl[i] == m->client) + break; + if (i < cl_size) + continue; + GNUNET_array_append (cl, cl_size, m->client); + + msize = size; + msize += path_length * sizeof (struct GNUNET_PeerIdentity); + msize += sizeof (struct GNUNET_DHT_MonitorPutMessage); + msize += sizeof (struct PendingMessage); + pm = (struct PendingMessage *) GNUNET_malloc (msize); + mmsg = (struct GNUNET_DHT_MonitorPutMessage *) &pm[1]; + pm->msg = (struct GNUNET_MessageHeader *) mmsg; + mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); + mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); + mmsg->options = htonl(options); + mmsg->type = htonl(type); + mmsg->hop_count = htonl(hop_count); + mmsg->desired_replication_level = htonl(desired_replication_level); + mmsg->put_path_length = htonl(path_length); + msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; + if (path_length > 0) { - memcpy (path, put_path, putl * sizeof (struct GNUNET_PeerIdentity)); - path = &path[putl]; + memcpy (msg_path, path, + path_length * sizeof (struct GNUNET_PeerIdentity)); } - if (getl > 0) - memcpy (path, get_path, getl * sizeof (struct GNUNET_PeerIdentity)); + mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp); + memcpy (&mmsg->key, key, sizeof (GNUNET_HashCode)); if (size > 0) - memcpy (&path[getl], data, size); + memcpy (&msg_path[path_length], data, size); add_pending_message (m->client, pm); } } @@ -1129,8 +1343,11 @@ GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server) GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, sizeof (struct GNUNET_DHT_ClientGetStopMessage)}, {&handle_dht_local_monitor, NULL, - GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET, - sizeof (struct GNUNET_DHT_MonitorMessage)}, + GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, + sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, + {&handle_dht_local_monitor_stop, NULL, + GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, + sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, {NULL, NULL, 0, 0} }; forward_map = GNUNET_CONTAINER_multihashmap_create (1024); @@ -1153,12 +1370,18 @@ GDS_CLIENTS_done () GNUNET_SCHEDULER_cancel (retry_task); retry_task = GNUNET_SCHEDULER_NO_TASK; } - GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap)); - GNUNET_CONTAINER_heap_destroy (retry_heap); - retry_heap = NULL; - GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (forward_map)); - GNUNET_CONTAINER_multihashmap_destroy (forward_map); - forward_map = NULL; + if (NULL != retry_heap) + { + GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap)); + GNUNET_CONTAINER_heap_destroy (retry_heap); + retry_heap = NULL; + } + if (NULL != forward_map) + { + GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (forward_map)); + GNUNET_CONTAINER_multihashmap_destroy (forward_map); + forward_map = NULL; + } } /* end of gnunet-service-dht_clients.c */ diff --git a/src/dht/gnunet-service-dht_clients.h b/src/dht/gnunet-service-dht_clients.h index a477456..9f3d2dd 100644 --- a/src/dht/gnunet-service-dht_clients.h +++ b/src/dht/gnunet-service-dht_clients.h @@ -57,33 +57,77 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, /** - * Check if some client is monitoring messages of this type and notify - * him in that case. + * Check if some client is monitoring GET messages and notify + * them in that case. * - * @param mtype Type of the DHT message. - * @param exp When will this value expire. - * @param key Key of the result/request. - * @param putl number of entries in get_path. - * @param put_path peers on the PUT path (or NULL if not recorded). - * @param getl number of entries in get_path. - * @param get_path Peers on reply path (or NULL if not recorded). + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the GET path (or NULL if not recorded). * @param desired_replication_level Desired replication level. - * @param type Type of the result/request. + * @param key Key of the requested data. + */ +void +GDS_CLIENTS_process_get (uint32_t options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + const GNUNET_HashCode * key); + +/** + * Check if some client is monitoring GET RESP messages and notify + * them in that case. + * + * @param type The type of data in the result. + * @param get_path Peers on GET path (or NULL if not recorded). + * @param get_path_length number of entries in get_path. + * @param put_path peers on the PUT path (or NULL if not recorded). + * @param put_path_length number of entries in get_path. + * @param exp Expiration time of the data. + * @param key Key of the data. * @param data Pointer to the result data. * @param size Number of bytes in data. */ void -GDS_CLIENTS_process_monitor (uint16_t mtype, - const struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode *key, - uint32_t putl, - const struct GNUNET_PeerIdentity *put_path, - uint32_t getl, - const struct GNUNET_PeerIdentity *get_path, - uint32_t desired_replication_level, - enum GNUNET_BLOCK_Type type, - const struct GNUNET_MessageHeader *data, - uint16_t size); +GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size); + +/** + * Check if some client is monitoring PUT messages and notify + * them in that case. + * + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the PUT path (or NULL if not recorded). + * @param desired_replication_level Desired replication level. + * @param exp Expiration time of the data. + * @param key Key under which data is to be stored. + * @param data Pointer to the data carried. + * @param size Number of bytes in data. + */ +void +GDS_CLIENTS_process_put (uint32_t options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size); /** * Initialize client subsystem. diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index 82cd067..4d1dd6f 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c @@ -193,11 +193,9 @@ datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, GNUNET_BLOCK_evaluate (GDS_block_context, type, key, ctx->reply_bf, ctx->reply_bf_mutator, ctx->xquery, ctx->xquery_size, rdata, rdata_size); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found reply for query %s in datacache, evaluation result is %d\n", GNUNET_h2s (key), (int) eval); -#endif ctx->eval = eval; switch (eval) { diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 4ea5dd6..083b499 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c @@ -524,11 +524,9 @@ add_known_to_bloom (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_HashCode mh; GNUNET_BLOCK_mingle_hash (key, ctx->bf_mutator, &mh); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding known peer (%s) to bloomfilter for FIND PEER with mutation %u\n", GNUNET_h2s (key), ctx->bf_mutator); -#endif GNUNET_CONTAINER_bloomfilter_add (ctx->bloom, &mh); return GNUNET_YES; } @@ -615,10 +613,8 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, /* Check for connect to self message */ if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) return; -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected %s to %s\n", GNUNET_i2s (&my_identity), GNUNET_h2s (&peer->hashPubKey)); -#endif if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (all_known_peers, &peer->hashPubKey)) @@ -626,7 +622,7 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_break (0); return; } - GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# Peers connected"), 1, + GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1, GNUNET_NO); peer_bucket = find_bucket (&peer->hashPubKey); GNUNET_assert ((peer_bucket >= 0) && (peer_bucket < MAX_BUCKETS)); @@ -675,10 +671,8 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) /* Check for disconnect from self message */ if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) return; -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnected %s from %s\n", GNUNET_i2s (&my_identity), GNUNET_h2s (&peer->hashPubKey)); -#endif to_remove = GNUNET_CONTAINER_multihashmap_get (all_known_peers, &peer->hashPubKey); if (NULL == to_remove) @@ -686,7 +680,7 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) GNUNET_break (0); return; } - GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# Peers connected"), -1, + GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), -1, GNUNET_NO); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (all_known_peers, @@ -1030,11 +1024,9 @@ select_peer (const GNUNET_HashCode * key, } else { -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Excluded peer `%s' due to BF match in greedy routing for %s\n", GNUNET_i2s (&pos->id), GNUNET_h2s (key)); -#endif GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# Peers excluded from routing due to Bloomfilter"), @@ -1067,11 +1059,9 @@ select_peer (const GNUNET_HashCode * key, gettext_noop ("# Peers excluded from routing due to Bloomfilter"), 1, GNUNET_NO); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Excluded peer `%s' due to BF match in random routing for %s\n", GNUNET_i2s (&pos->id), GNUNET_h2s (key)); -#endif pos = pos->next; continue; /* Ignore bloomfiltered peers */ } @@ -1154,12 +1144,10 @@ get_target_peers (const GNUNET_HashCode * key, &nxt->id.hashPubKey)); GNUNET_CONTAINER_bloomfilter_add (bloom, &rtargets[off]->id.hashPubKey); } -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Selected %u/%u peers at hop %u for %s (target was %u)\n", off, GNUNET_CONTAINER_multihashmap_size (all_known_peers), (unsigned int) hop_count, GNUNET_h2s (key), ret); -#endif if (0 == off) { GNUNET_free (rtargets); @@ -1212,11 +1200,9 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, struct GNUNET_PeerIdentity *pp; GNUNET_assert (NULL != bf); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding myself (%s) to PUT bloomfilter for %s\n", GNUNET_i2s (&my_identity), GNUNET_h2s (key)); -#endif GNUNET_CONTAINER_bloomfilter_add (bf, &my_identity.hashPubKey); GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# PUT requests routed"), 1, GNUNET_NO); @@ -1225,12 +1211,10 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, &targets); if (0 == target_count) { -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing PUT for %s terminates after %u hops at %s\n", GNUNET_h2s (key), (unsigned int) hop_count, GNUNET_i2s (&my_identity)); -#endif return; } msize = @@ -1254,11 +1238,9 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, for (i = 0; i < target_count; i++) { target = targets[i]; -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing PUT for %s after %u hops to %s\n", GNUNET_h2s (key), (unsigned int) hop_count, GNUNET_i2s (&target->id)); -#endif pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); pending->importance = 0; /* FIXME */ pending->timeout = expiration_time; @@ -1335,20 +1317,16 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, target_count = get_target_peers (key, peer_bf, hop_count, desired_replication_level, &targets); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding myself (%s) to GET bloomfilter for %s\n", GNUNET_i2s (&my_identity), GNUNET_h2s (key)); -#endif GNUNET_CONTAINER_bloomfilter_add (peer_bf, &my_identity.hashPubKey); if (0 == target_count) { -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing GET for %s terminates after %u hops at %s\n", GNUNET_h2s (key), (unsigned int) hop_count, GNUNET_i2s (&my_identity)); -#endif return; } reply_bf_size = GNUNET_CONTAINER_bloomfilter_get_size (reply_bf); @@ -1367,11 +1345,9 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, for (i = 0; i < target_count; i++) { target = targets[i]; -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing GET for %s after %u hops to %s\n", GNUNET_h2s (key), (unsigned int) hop_count, GNUNET_i2s (&target->id)); -#endif pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); pending->importance = 0; /* FIXME */ pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT); @@ -1578,10 +1554,8 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, /* cannot verify, good luck */ break; } -#if DEBUG_DHT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PUT for %s at %s\n", - GNUNET_h2s (&put->key), GNUNET_i2s (&my_identity)); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PUT for `%s' from %s\n", + GNUNET_h2s (&put->key), GNUNET_i2s (peer)); bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter, DHT_BLOOM_SIZE, GNUNET_CONSTANTS_BLOOMFILTER_K); GNUNET_break_op (GNUNET_YES == @@ -1617,10 +1591,15 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, pp, payload, payload_size); } GNUNET_CONTAINER_bloomfilter_free (bf); - GDS_CLIENTS_process_monitor (GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT, - GNUNET_TIME_absolute_ntoh (put->expiration_time), &put->key, - putlen, put_path, 0, NULL, ntohl(put->desired_replication_level), - ntohl (put->type), payload, payload_size); + GDS_CLIENTS_process_put (options, + ntohl (put->type), + ntohl (put->hop_count), + ntohl (put->desired_replication_level), + putlen, put_path, + GNUNET_TIME_absolute_ntoh (put->expiration_time), + &put->key, + payload, + payload_size); return GNUNET_YES; } @@ -1795,11 +1774,9 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer, /* remember request for routing replies */ GDS_ROUTING_add (peer, type, options, &get->key, xquery, xquery_size, reply_bf, get->bf_mutator); -#if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GET for %s at %s after %u hops\n", GNUNET_h2s (&get->key), GNUNET_i2s (&my_identity), (unsigned int) ntohl (get->hop_count)); -#endif /* local lookup (this may update the reply_bf) */ if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || (am_closest_peer (&get->key, peer_bf))) @@ -1826,9 +1803,13 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer, 1, GNUNET_NO); } - GDS_CLIENTS_process_monitor (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET, - GNUNET_TIME_UNIT_FOREVER_ABS, &get->key, 0, NULL, 0, NULL, - ntohl (get->desired_replication_level), type, NULL, 0); + /* FIXME Path */ + GDS_CLIENTS_process_get (options, + type, + ntohl(get->hop_count), + ntohl(get->desired_replication_level), + 0, NULL, + &get->key); /* P2P forwarding */ if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) @@ -1962,10 +1943,16 @@ handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer, xget_path, data, data_size); } - GDS_CLIENTS_process_monitor (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP, - GNUNET_TIME_absolute_ntoh (prm->expiration_time), &prm->key, - put_path_length, put_path, get_path_length, get_path, - 0, type, data, data_size); + GDS_CLIENTS_process_get_resp (type, + get_path, + get_path_length, + put_path, + put_path_length, + GNUNET_TIME_absolute_ntoh ( + prm->expiration_time), + &prm->key, + data, + data_size); return GNUNET_YES; } @@ -2025,5 +2012,16 @@ GDS_NEIGHBOURS_done () } } +/** + * Get the ID of the local node. + * + * @return identity of the local node + */ +struct GNUNET_PeerIdentity * +GDS_NEIGHBOURS_get_id () +{ + return &my_identity; +} + /* end of gnunet-service-dht_neighbours.c */ diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index b6e0f0e..3297638 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h @@ -135,4 +135,13 @@ void GDS_NEIGHBOURS_done (void); +/** + * Get the ID of the local node. + * + * @return identity of the local node + */ +struct GNUNET_PeerIdentity * +GDS_NEIGHBOURS_get_id (); + + #endif diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index a880bf7..013d856 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c @@ -227,6 +227,8 @@ process (void *cls, const GNUNET_HashCode * key, void *value) 1, GNUNET_NO); return GNUNET_SYSERR; case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: + GNUNET_break (0); + return GNUNET_OK; case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: GNUNET_break (0); return GNUNET_OK; @@ -280,10 +282,47 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, pc.get_path = get_path; pc.data = data; pc.data_size = data_size; + if (NULL == data) + { + /* Some apps might have an 'empty' reply as a valid reply; however, + 'process' will call GNUNET_BLOCK_evaluate' which treats a 'NULL' + reply as request-validation (but we need response-validation). + So we set 'data' to a 0-byte non-NULL value just to be sure */ + GNUNET_break (0 == data_size); + data_size = 0; + pc.data = ""; /* something not null */ + } GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, key, &process, &pc); } +/** + * Remove the oldest entry from the DHT routing table. Must only + * be called if it is known that there is at least one entry + * in the heap and hashmap. + */ +static void +expire_oldest_entry () +{ + struct RecentRequest *recent_req; + + GNUNET_STATISTICS_update (GDS_stats, + gettext_noop + ("# Entries removed from routing table"), 1, + GNUNET_NO); + recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); + GNUNET_assert (recent_req != NULL); + GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node); + GNUNET_CONTAINER_bloomfilter_free (recent_req->reply_bf); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (recent_map, + &recent_req->key, + recent_req)); + GNUNET_free (recent_req); +} + + + /** * Add a new entry to our routing table. * @@ -308,18 +347,7 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, struct RecentRequest *recent_req; while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT) - { - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Entries removed from routing table"), 1, - GNUNET_NO); - recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); - GNUNET_assert (recent_req != NULL); - GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node); - GNUNET_CONTAINER_bloomfilter_free (recent_req->reply_bf); - GNUNET_free (recent_req); - } - + expire_oldest_entry (); GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# Entries added to routing table"), 1, GNUNET_NO); @@ -359,23 +387,12 @@ GDS_ROUTING_init () void GDS_ROUTING_done () { - struct RecentRequest *recent_req; - while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) - { - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Entries removed from routing table"), 1, - GNUNET_NO); - recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); - GNUNET_assert (recent_req != NULL); - GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node); - GNUNET_CONTAINER_bloomfilter_free (recent_req->reply_bf); - GNUNET_free (recent_req); - } + expire_oldest_entry (); GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (recent_heap)); GNUNET_CONTAINER_heap_destroy (recent_heap); recent_heap = NULL; + GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (recent_map)); GNUNET_CONTAINER_multihashmap_destroy (recent_map); recent_map = NULL; } diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c index 19467b9..3c016ae 100644 --- a/src/dht/plugin_block_dht.c +++ b/src/dht/plugin_block_dht.c @@ -65,17 +65,29 @@ block_plugin_dht_evaluate (void *cls, enum GNUNET_BLOCK_Type type, if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; if (xquery_size != 0) + { + GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; - if (reply_block_size == 0) + } + if (NULL == reply_block) return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; if (reply_block_size < sizeof (struct GNUNET_MessageHeader)) + { + GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } msg = reply_block; if (reply_block_size != ntohs (msg->size)) + { + GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } hello = reply_block; if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid)) + { + GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } if (NULL != bf) { GNUNET_BLOCK_mingle_hash (&pid.hashPubKey, bf_mutator, &mhash); diff --git a/src/dht/test_dht_2dtorus.conf b/src/dht/test_dht_2dtorus.conf index d420b29..d7a3d8a 100644 --- a/src/dht/test_dht_2dtorus.conf +++ b/src/dht/test_dht_2dtorus.conf @@ -65,7 +65,7 @@ CONNECT_TIMEOUT = 60 s CONNECT_ATTEMPTS = 3 DEBUG = YES HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat -MAX_CONCURRENT_SSH = 10 +MAX_CONCURRENT_SSH = 20 USE_PROGRESSBARS = YES PEERGROUP_TIMEOUT = 2400 s TOPOLOGY_OUTPUT_FILE = 2dtorus_topo_initial @@ -77,7 +77,7 @@ MAX_OUTSTANDING_CONNECTIONS = 75 DELETE_FILES = YES [test_dht_topo] -CONNECTION_LIMIT = 16 +CONNECTION_LIMIT = 20 #DATA_OUTPUT_FILE=data_output diff --git a/src/dht/test_dht_api.c b/src/dht/test_dht_api.c index 182856a..000ad33 100644 --- a/src/dht/test_dht_api.c +++ b/src/dht/test_dht_api.c @@ -121,7 +121,7 @@ stop_arm (struct PeerContext *p) if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (p->arm_proc); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); @@ -195,10 +195,10 @@ test_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, * Signature of the main function of a task. * * @param cls closure - * @param tc context information (why was this task triggered now) + * @param success result of PUT */ static void -test_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +test_get (void *cls, int success) { struct PeerContext *peer = cls; GNUNET_HashCode hash; @@ -212,7 +212,7 @@ test_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) retry_context.next_timeout = BASE_TIMEOUT; peer->get_handle = - GNUNET_DHT_get_start (peer->dht_handle, TOTAL_TIMEOUT, + GNUNET_DHT_get_start (peer->dht_handle, GNUNET_BLOCK_TYPE_TEST, &hash, 1, GNUNET_DHT_RO_NONE, NULL, 0, &test_get_iterator, NULL); diff --git a/src/dht/test_dht_api_data.conf b/src/dht/test_dht_api_data.conf index 0e34eb7..032416c 100644 --- a/src/dht/test_dht_api_data.conf +++ b/src/dht/test_dht_api_data.conf @@ -77,7 +77,8 @@ EXTERNAL_ADDRESS = 127.0.0.1 [dns] AUTOSTART = NO - +[namestore] +AUTOSTART = NO [nse] AUTOSTART = NO diff --git a/src/dht/test_dht_api_peer1.conf b/src/dht/test_dht_api_peer1.conf index cacc4da..d9db7c4 100644 --- a/src/dht/test_dht_api_peer1.conf +++ b/src/dht/test_dht_api_peer1.conf @@ -10,7 +10,7 @@ AUTOSTART = YES ACCEPT_FROM6 = ::1; ACCEPT_FROM = 127.0.0.1; HOSTNAME = localhost -PORT = 2100 +PORT = 12100 BINARY = gnunet-service-dht [block] diff --git a/src/dht/test_dht_line.conf b/src/dht/test_dht_line.conf index 8bcb12c..6be3559 100644 --- a/src/dht/test_dht_line.conf +++ b/src/dht/test_dht_line.conf @@ -80,6 +80,8 @@ DELETE_FILES = YES CONNECTION_LIMIT = 5 #DATA_OUTPUT_FILE=data_output +[namestore] +AUTOSTART = NO [nse] WORKDELAY = 500 ms diff --git a/src/dht/test_dht_monitor.c b/src/dht/test_dht_monitor.c index 63af7e9..ca6704a 100644 --- a/src/dht/test_dht_monitor.c +++ b/src/dht/test_dht_monitor.c @@ -31,8 +31,6 @@ #include "gnunet_testing_lib.h" #include "gnunet_dht_service.h" -#define VERBOSE GNUNET_YES - #define REMOVE_DIR GNUNET_YES @@ -137,17 +135,14 @@ shutdown_callback (void *cls, const char *emsg) { if (emsg != NULL) { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Shutdown of peers failed!\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: Shutdown of peers failed: %s\n", + emsg); ok++; } else { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: All peers successfully shut down!\n"); -#endif } GNUNET_CONFIGURATION_destroy (testing_cfg); } @@ -156,16 +151,12 @@ shutdown_callback (void *cls, const char *emsg) static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Ending test.\n"); -#endif - if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (disconnect_task); disconnect_task = GNUNET_SCHEDULER_NO_TASK; } - if (data_file != NULL) GNUNET_DISK_file_close (data_file); GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); @@ -184,6 +175,7 @@ disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_DHT_get_stop (get_h_far); for (i = 0; i < num_peers; i++) { + GNUNET_DHT_monitor_stop(mhs[i]); GNUNET_DHT_disconnect (hs[i]); } GNUNET_SCHEDULER_cancel (shutdown_handle); @@ -258,7 +250,7 @@ do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_h2s_full (&d_far->id.hashPubKey)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: from %s\n", GNUNET_h2s_full (&o->id.hashPubKey)); - get_h_far = GNUNET_DHT_get_start (hs[0], GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */ + get_h_far = GNUNET_DHT_get_start (hs[0], GNUNET_BLOCK_TYPE_TEST, /* type */ &d_far->id.hashPubKey, /*key to search */ 4U, /* replication level */ @@ -302,65 +294,123 @@ put_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } /** - * Callback called on each request going through the DHT. + * Callback called on each GET request going through the DHT. + * Prints the info about the intercepted packet and increments a counter. + * + * @param cls Closure. + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the GET path (or NULL if not recorded). + * @param desired_replication_level Desired replication level. + * @param key Key of the requested data. + */ +void +monitor_get_cb (void *cls, + enum GNUNET_DHT_RouteOption options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + const GNUNET_HashCode * key) +{ + const char *s_key; + unsigned int i; + + i = (unsigned int) (long) cls; + s_key = GNUNET_h2s(key); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "%u got a GET message for key %s\n", + i, s_key); + + if (strncmp (s_key, id_far, 4) == 0 && in_test == GNUNET_YES) + monitor_counter++; +} + + +/** + * Callback called on each PUT request going through the DHT. + * Prints the info about the intercepted packet and increments a counter. + * + * @param cls Closure. + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the PUT path (or NULL if not recorded). + * @param desired_replication_level Desired replication level. + * @param exp Expiration time of the data. + * @param key Key under which data is to be stored. + * @param data Pointer to the data carried. + * @param size Number of bytes in data. + */ +void +monitor_put_cb (void *cls, + enum GNUNET_DHT_RouteOption options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size) +{ + const char *s_key; + unsigned int i; + + i = (unsigned int) (long) cls; + s_key = GNUNET_h2s(key); + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "%u got a PUT message for key %s with %u bytes\n", + i, s_key, size); + + if (strncmp (s_key, id_far, 4) == 0 && in_test == GNUNET_YES) + monitor_counter++; +} + + +/** + * Callback called on each GET reply going through the DHT. * Prints the info about the intercepted packet and increments a counter. * - * @param cls Closure (long) # of daemon that got the monitor event. - * @param mtype Type of the DHT message monitored. - * @param exp When will this value expire. - * @param key Key of the result/request. - * @param get_path Peers on reply path (or NULL if not recorded). + * @param cls Closure. + * @param type The type of data in the result. + * @param get_path Peers on GET path (or NULL if not recorded). * @param get_path_length number of entries in get_path. * @param put_path peers on the PUT path (or NULL if not recorded). * @param put_path_length number of entries in get_path. - * @param desired_replication_level Desired replication level. - * @param type Type of the result/request. + * @param exp Expiration time of the data. + * @param key Key of the data. * @param data Pointer to the result data. * @param size Number of bytes in data. */ void -monitor_dht_cb (void *cls, - uint16_t mtype, - struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity * get_path, +monitor_res_cb (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, - const struct GNUNET_PeerIdentity * put_path, + const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, - uint32_t desired_replication_level, - enum GNUNET_DHT_RouteOption options, - enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, const void *data, size_t size) { const char *s_key; - const char *mtype_s; unsigned int i; i = (unsigned int) (long) cls; s_key = GNUNET_h2s(key); - switch (mtype) - { - case 149: - mtype_s = "GET "; - break; - case 150: - mtype_s = "RESULT"; - break; - case 151: - mtype_s = "PUT "; - break; - default: - GNUNET_break (0); - mtype_s = "UNKNOWN!!!"; - } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "%u got a message of type %s for key %s\n", - i, mtype_s, s_key); + "%u got a REPLY message for key %s with %u bytes\n", + i, s_key, size); - if ((mtype == GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET || - mtype == GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT) && - strncmp (s_key, id_far, 4) == 0 && in_test == GNUNET_YES) + if (strncmp (s_key, id_far, 4) == 0 && in_test == GNUNET_YES) monitor_counter++; } @@ -389,15 +439,9 @@ peergroup_ready (void *cls, const char *emsg) GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); return; } -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "************************************************************\n"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: Peer Group started successfully!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Have %u connections\n", + "test: Peer Group started successfully with %u connections\n", total_connections); -#endif - if (data_file != NULL) { buf = NULL; @@ -419,8 +463,13 @@ peergroup_ready (void *cls, const char *emsg) { d = GNUNET_TESTING_daemon_get (pg, i); hs[i] = GNUNET_DHT_connect (d->cfg, 32); - mhs[i] = GNUNET_DHT_monitor_start(hs[i], GNUNET_BLOCK_TYPE_ANY, NULL, - &monitor_dht_cb, (void *)(long)i); + mhs[i] = GNUNET_DHT_monitor_start(hs[i], + GNUNET_BLOCK_TYPE_ANY, + NULL, + &monitor_get_cb, + &monitor_res_cb, + &monitor_put_cb, + (void *)(long)i); } if ((NULL == o) || (NULL == d_far)) @@ -500,19 +549,12 @@ run (void *cls, char *const *args, const char *cfgfile, testing_cfg = GNUNET_CONFIGURATION_dup (cfg); GNUNET_log_setup ("test_dht_monitor", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Starting daemons.\n"); GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", "use_progressbars", "YES"); -#endif - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing", "num_peers", &num_peers)) @@ -600,9 +642,6 @@ main (int xargc, char *xargv[]) char *const argv[] = { "test-dht-monitor", "-c", "test_dht_line.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; diff --git a/src/dht/test_dht_multipeer.c b/src/dht/test_dht_multipeer.c index 94e39d2..ab7d90e 100644 --- a/src/dht/test_dht_multipeer.c +++ b/src/dht/test_dht_multipeer.c @@ -27,9 +27,6 @@ #include "gnunet_core_service.h" #include "gnunet_dht_service.h" -/* DEFINES */ -#define VERBOSE GNUNET_NO - /* Timeout for entire testcase */ #define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 30) @@ -279,7 +276,7 @@ static struct StatValues stats[] = { {"core", "# bytes encrypted", 0}, {"core", "# type maps received", 0}, {"core", "# session keys confirmed via PONG", 0}, - {"core", "# entries in session map", 0}, + {"core", "# peers connected", 0}, {"core", "# key exchanges initiated", 0}, {"core", "# send requests dropped (disconnected)", 0}, {"core", "# transmissions delayed due to corking", 0}, @@ -624,7 +621,7 @@ do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (test_get->dht_handle != NULL); outstanding_gets++; test_get->get_handle = - GNUNET_DHT_get_start (test_get->dht_handle, GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_DHT_get_start (test_get->dht_handle, GNUNET_BLOCK_TYPE_TEST, &key, 1, route_option, NULL, 0, &get_result_iterator, test_get); test_get->task = @@ -658,10 +655,9 @@ start_gets (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) unsigned long long j; struct TestGetContext *test_get; -#if VERBOSE - FPRINTF (stderr, "Issuing %llu GETs\n", - (unsigned long long) (num_peers * num_peers)); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Issuing %llu GETs\n", + (unsigned long long) (num_peers * num_peers)); for (i = 0; i < num_peers; i++) for (j = 0; j < num_peers; j++) { @@ -678,7 +674,7 @@ start_gets (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * Called when the PUT request has been transmitted to the DHT service. */ static void -put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +put_finished (void *cls, int success) { struct TestPutContext *test_put = cls; @@ -719,10 +715,9 @@ do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) test_put->dht_handle = GNUNET_DHT_connect (test_put->daemon->cfg, 10); GNUNET_assert (test_put->dht_handle != NULL); outstanding_puts++; -#if VERBOSE > 2 - FPRINTF (stderr, "PUT %u at `%s'\n", test_put->uid, - GNUNET_i2s (&test_put->daemon->id)); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "PUT %u at `%s'\n", test_put->uid, + GNUNET_i2s (&test_put->daemon->id)); GNUNET_DHT_put (test_put->dht_handle, &key, 1, route_option, GNUNET_BLOCK_TYPE_TEST, sizeof (data), data, GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_FOREVER_REL, @@ -822,9 +817,6 @@ check () char *const argv[] = { "test-dht-multipeer", /* Name to give running binary */ "-c", "test_dht_multipeer_data.conf", /* Config file to use */ -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -848,13 +840,8 @@ main (int argc, char *argv[]) { int ret; - GNUNET_log_setup ("test-dht-multipeer", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); /** diff --git a/src/dht/test_dht_multipeer_data.conf b/src/dht/test_dht_multipeer_data.conf index ff87698..f181594 100644 --- a/src/dht/test_dht_multipeer_data.conf +++ b/src/dht/test_dht_multipeer_data.conf @@ -16,7 +16,7 @@ ACCEPT_FROM = 127.0.0.1; CONFIG = $DEFAULTCONFIG HOME = $SERVICEHOME HOSTNAME = localhost -PORT = 2100 +PORT = 12100 STOP_FOUND = YES USE_MAX_HOPS = YES MAX_HOPS = 16 @@ -115,12 +115,13 @@ BEHIND_NAT = NO ALLOW_NAT = NO INTERNAL_ADDRESS = 127.0.0.1 EXTERNAL_ADDRESS = 127.0.0.1 -USE_LOCALADDR = NO +USE_LOCALADDR = YES [dns] AUTOSTART = NO - +[namestore] +AUTOSTART = NO [nse] AUTOSTART = NO diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c index 81dc7cb..f51f3a6 100644 --- a/src/dht/test_dht_topo.c +++ b/src/dht/test_dht_topo.c @@ -30,8 +30,6 @@ #include "gnunet_testing_lib.h" #include "gnunet_dht_service.h" -#define VERBOSE GNUNET_NO - #define REMOVE_DIR GNUNET_YES /** @@ -54,11 +52,6 @@ */ static int ok; -/** - * Be verbose - */ -static int verbose; - /** * Total number of peers in the test. */ @@ -116,27 +109,26 @@ static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle; static char *topology_file; -struct GNUNET_TESTING_Daemon *d1; +static struct GNUNET_DHT_Handle **hs; -struct GNUNET_TESTING_Daemon *d2; +static struct GNUNET_DHT_GetHandle *get_h; -struct GNUNET_DHT_Handle **hs; +static struct GNUNET_DHT_GetHandle *get_h_2; -struct GNUNET_DHT_GetHandle *get_h; +static struct GNUNET_DHT_GetHandle *get_h_far; -struct GNUNET_DHT_GetHandle *get_h_2; +static int found_1; -struct GNUNET_DHT_GetHandle *get_h_far; +static int found_2; -int found_1; -int found_2; -int found_far; +static int found_far; /** * Which topology are we to run */ static int test_topology; + /** * Check whether peers successfully shut down. */ @@ -145,17 +137,12 @@ shutdown_callback (void *cls, const char *emsg) { if (emsg != NULL) { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Shutdown of peers failed!\n"); ok++; } else { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All peers successfully shut down!\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All peers successfully shut down!\n"); } GNUNET_CONFIGURATION_destroy (testing_cfg); } @@ -164,9 +151,7 @@ shutdown_callback (void *cls, const char *emsg) static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Ending test.\n"); if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) { @@ -185,7 +170,7 @@ disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { unsigned int i; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "disconnecting peers\n"); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "disconnecting peers\n"); disconnect_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_SCHEDULER_cancel (put_task); if (NULL != get_h) @@ -202,6 +187,7 @@ disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); } + static void dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, const GNUNET_HashCode * key, @@ -255,14 +241,15 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, default: GNUNET_break(0); } - if (TORUS == test_topology && - (found_1 == 0 || found_2 == 0 || found_far == 0)) + if ( (TORUS == test_topology) && + ( (found_1 == 0) || (found_2 == 0) || (found_far == 0)) ) return; ok = 0; GNUNET_SCHEDULER_cancel (disconnect_task); disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); } + static void do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -313,11 +300,11 @@ do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_assert (0); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\ntest: from %s\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\nfrom %s\n", GNUNET_h2s_full (&o->id.hashPubKey)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", GNUNET_h2s_full (&d->id.hashPubKey)); - get_h = GNUNET_DHT_get_start (hs[0], GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */ + get_h = GNUNET_DHT_get_start (hs[0], GNUNET_BLOCK_TYPE_TEST, /* type */ &d->id.hashPubKey, /*key to search */ 4U, /* replication level */ @@ -328,7 +315,7 @@ do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", GNUNET_h2s_full (&d2->id.hashPubKey)); - get_h_2 = GNUNET_DHT_get_start (hs[0], GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */ + get_h_2 = GNUNET_DHT_get_start (hs[0], GNUNET_BLOCK_TYPE_TEST, /* type */ &d2->id.hashPubKey, /*key to search */ 4U, /* replication level */ @@ -337,7 +324,7 @@ do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) &dht_get_id_handler, (void *)2); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", GNUNET_h2s_full (&d_far->id.hashPubKey)); - get_h_far = GNUNET_DHT_get_start (hs[0], GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */ + get_h_far = GNUNET_DHT_get_start (hs[0], GNUNET_BLOCK_TYPE_TEST, /* type */ &d_far->id.hashPubKey, /*key to search */ 4U, /* replication level */ @@ -402,21 +389,16 @@ peergroup_ready (void *cls, const char *emsg) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peergroup callback called with error, aborting test!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error from testing: `%s'\n", + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error from testing: `%s'\n", emsg); ok++; GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); return; } -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "************************************************************\n"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer Group started successfully!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have %u connections\n", + "Peer Group started successfully with %u connections\n", total_connections); -#endif - if (data_file != NULL) { buf = NULL; @@ -465,7 +447,6 @@ connect_cb (void *cls, const struct GNUNET_PeerIdentity *first, struct GNUNET_TESTING_Daemon *first_daemon, struct GNUNET_TESTING_Daemon *second_daemon, const char *emsg) { - if (emsg == NULL) { total_connections++; @@ -474,10 +455,9 @@ connect_cb (void *cls, const struct GNUNET_PeerIdentity *first, } else { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Problem with new connection (%s)\n", emsg); } - } @@ -500,19 +480,11 @@ run (void *cls, char *const *args, const char *cfgfile, testing_cfg = GNUNET_CONFIGURATION_dup (cfg); GNUNET_log_setup ("test_dht_topo", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); - -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", "use_progressbars", "YES"); -#endif - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing", "num_peers", &num_peers)) @@ -579,38 +551,23 @@ run (void *cls, char *const *args, const char *cfgfile, } - -/** - * test_dht_2d command line options - */ -static struct GNUNET_GETOPT_CommandLineOption options[] = { - {'V', "verbose", NULL, - gettext_noop ("be verbose (print progress information)"), - 0, &GNUNET_GETOPT_set_one, &verbose}, - GNUNET_GETOPT_OPTION_END -}; - - /** * Main: start test */ int main (int xargc, char *xargv[]) { - char *const argv_torus[] = { "test-dht-2dtorus", + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + static char *const argv_torus[] = { "test-dht-2dtorus", "-c", "test_dht_2dtorus.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; - char *const argv_line[] = { "test-dht-line", + static char *const argv_line[] = { "test-dht-line", "-c", "test_dht_line.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; char *const *argv; @@ -641,17 +598,17 @@ main (int xargc, char *xargv[]) #if REMOVE_DIR GNUNET_DISK_directory_remove ("/tmp/test_dht_topo"); #endif - if (found_1 == 0) + if (0 == found_1) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID 1 not found!\n"); } if (TORUS == test_topology) { - if (found_2 == 0) + if (0 == found_2) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID 2 not found!\n"); } - if (found_far == 0) + if (0 == found_far) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID far not found!\n"); } diff --git a/src/dht/test_dht_twopeer.c b/src/dht/test_dht_twopeer.c index a3b6e4a..f0ac05b 100644 --- a/src/dht/test_dht_twopeer.c +++ b/src/dht/test_dht_twopeer.c @@ -28,8 +28,6 @@ #include "gnunet_dht_service.h" /* DEFINES */ -#define VERBOSE GNUNET_NO - #define MAX_GET_ATTEMPTS 10 #define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) @@ -250,8 +248,6 @@ get_stop_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) &stop_retry_get, get_context); get_context->get_handle = GNUNET_DHT_get_start (get_context->dht_handle, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), GNUNET_BLOCK_TYPE_DHT_HELLO, &get_context->peer->hashPubKey, 1, GNUNET_DHT_RO_NONE, NULL, 0, &get_result_iterator, @@ -285,8 +281,6 @@ do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) &stop_retry_get, get_context); get_context->get_handle = GNUNET_DHT_get_start (get_context->dht_handle, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), GNUNET_BLOCK_TYPE_DHT_HELLO, &get_context->peer->hashPubKey, 1, GNUNET_DHT_RO_FIND_PEER, NULL, 0, @@ -306,7 +300,6 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, if (emsg == NULL) { total_connections++; -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s, distance %u\n", first_daemon->shortname, second_daemon->shortname, distance); @@ -314,19 +307,16 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, else { failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to connect peer %s to peer %s with error :\n%s\n", first_daemon->shortname, second_daemon->shortname, emsg); -#endif } if (total_connections == expected_connections) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created %d total connections, which is our target number! Starting next phase of testing.\n", total_connections); -#endif GNUNET_SCHEDULER_cancel (die_task); die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, @@ -409,10 +399,8 @@ peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, if (peers_left == 0) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All %d daemons started, now connecting peers!\n", num_peers); -#endif GNUNET_SCHEDULER_cancel (die_task); /* Set up task in case topology creation doesn't finish * within a reasonable amount of time */ @@ -466,9 +454,6 @@ check () char *const argv[] = { "test-dht-twopeer", "-c", "test_dht_twopeer_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -491,11 +476,7 @@ main (int argc, char *argv[]) int ret; GNUNET_log_setup ("test-dht-twopeer", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); /** diff --git a/src/dht/test_dht_twopeer_data.conf b/src/dht/test_dht_twopeer_data.conf index ba1e22b..2889a41 100644 --- a/src/dht/test_dht_twopeer_data.conf +++ b/src/dht/test_dht_twopeer_data.conf @@ -9,7 +9,7 @@ AUTOSTART = YES DEBUG = NO AUTOSTART = YES #PREFIX = xterm -T dht -e gdb --args -PORT = 2100 +PORT = 12100 BINARY = gnunet-service-dht [block] @@ -34,7 +34,7 @@ HOSTNAME = localhost PORT = 12092 [arm] -DEFAULTSERVICES = core +DEFAULTSERVICES = core dht PORT = 12366 DEBUG = NO @@ -58,7 +58,7 @@ BEHIND_NAT = NO ALLOW_NAT = NO INTERNAL_ADDRESS = 127.0.0.1 EXTERNAL_ADDRESS = 127.0.0.1 -USE_LOCALADDR = NO +USE_LOCALADDR = YES [dns] AUTOSTART = NO @@ -72,3 +72,5 @@ AUTOSTART = NO [fs] AUTOSTART = NO +[namestore] +AUTOSTART = NO diff --git a/src/dht/test_dht_twopeer_get_put.c b/src/dht/test_dht_twopeer_get_put.c index 0bb9fac..3271d04 100644 --- a/src/dht/test_dht_twopeer_get_put.c +++ b/src/dht/test_dht_twopeer_get_put.c @@ -272,7 +272,7 @@ do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to the same thing as when data was inserted */ #endif global_get_handle = - GNUNET_DHT_get_start (peer2dht, GNUNET_TIME_relative_get_forever (), + GNUNET_DHT_get_start (peer2dht, #if DNS GNUNET_BLOCK_TYPE_DNS, #else @@ -289,7 +289,7 @@ do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * Schedule the GET request for some time in the future. */ static void -put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +put_finished (void *cls, int success) { GNUNET_SCHEDULER_cancel (die_task); die_task = @@ -391,29 +391,23 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, if (emsg == NULL) { total_connections++; -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s, distance %u\n", first_daemon->shortname, second_daemon->shortname, distance); -#endif } -#if VERBOSE else { failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to connect peer %s to peer %s with error :\n%s\n", first_daemon->shortname, second_daemon->shortname, emsg); } -#endif if (total_connections == expected_connections) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created %d total connections, which is our target number! Starting next phase of testing.\n", total_connections); -#endif GNUNET_SCHEDULER_cancel (die_task); die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from test gets"); @@ -482,10 +476,8 @@ peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, if (peers_left == 0) /* Indicates all peers started */ { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All %d daemons started, now connecting peers!\n", num_peers); -#endif expected_connections = -1; if ((pg != NULL)) /* Sanity check */ { @@ -556,9 +548,6 @@ check () char *const argv[] = { "test-dht-twopeer-get-put", /* Name to give running binary */ "-c", "test_dht_twopeer_data.conf", /* Config file to use */ -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -583,11 +572,7 @@ main (int argc, char *argv[]) int ret; GNUNET_log_setup ("test-dht-twopeer", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); /** diff --git a/src/dht/test_dht_twopeer_path_tracking.c b/src/dht/test_dht_twopeer_path_tracking.c index 6e764a3..6ecf6a3 100644 --- a/src/dht/test_dht_twopeer_path_tracking.c +++ b/src/dht/test_dht_twopeer_path_tracking.c @@ -249,7 +249,7 @@ get_result_iterator (void *cls, struct GNUNET_TIME_Absolute exp, * Schedule the GET request for some time in the future. */ static void -put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +put_finished (void *cls, int success) { GNUNET_HashCode key; /* Key for data lookup */ @@ -259,7 +259,7 @@ put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) "waiting for get response (data not found)"); memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to the same thing as when data was inserted */ global_get_handle = - GNUNET_DHT_get_start (peer2dht, GNUNET_TIME_relative_get_forever (), + GNUNET_DHT_get_start (peer2dht, GNUNET_BLOCK_TYPE_TEST, &key, 1, GNUNET_DHT_RO_RECORD_ROUTE, NULL, 0, &get_result_iterator, NULL); diff --git a/src/dht/test_dht_twopeer_put_get.c b/src/dht/test_dht_twopeer_put_get.c index 48bf9f8..44150e3 100644 --- a/src/dht/test_dht_twopeer_put_get.c +++ b/src/dht/test_dht_twopeer_put_get.c @@ -128,10 +128,16 @@ static struct GNUNET_DHT_Handle *peer1dht; */ static struct GNUNET_DHT_Handle *peer2dht; +/** + * Handle for our PUT operation. + */ +static struct GNUNET_DHT_PutHandle *put_op; + + /** * Check whether peers successfully shut down. */ -void +static void shutdown_callback (void *cls, const char *emsg) { if (emsg != NULL) @@ -164,6 +170,11 @@ finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + if (NULL != put_op) + { + GNUNET_DHT_put_cancel (put_op); + put_op = NULL; + } if (peer1dht != NULL) GNUNET_DHT_disconnect (peer1dht); @@ -174,6 +185,7 @@ end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); } + /** * Check if the get_handle is being used, if so stop the request. Either * way, schedule the end_badly_cont function which actually shuts down the @@ -242,10 +254,11 @@ get_result_iterator (void *cls, struct GNUNET_TIME_Absolute exp, * Schedule the GET request for some time in the future. */ static void -put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +put_finished (void *cls, int success) { GNUNET_HashCode key; /* Key for data lookup */ + put_op = NULL; GNUNET_SCHEDULER_cancel (die_task); die_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &end_badly, @@ -253,7 +266,7 @@ put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to the same thing as when data was inserted */ global_get_handle = - GNUNET_DHT_get_start (peer2dht, GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_DHT_get_start (peer2dht, GNUNET_BLOCK_TYPE_TEST, &key, 1, GNUNET_DHT_RO_NONE, NULL, 0, &get_result_iterator, NULL); } @@ -272,9 +285,9 @@ do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) memset (data, 43, sizeof (data)); /* Insert the data at the first peer */ - GNUNET_DHT_put (peer1dht, &key, 1, GNUNET_DHT_RO_NONE, GNUNET_BLOCK_TYPE_TEST, - sizeof (data), data, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_TIME_UNIT_FOREVER_REL, &put_finished, NULL); + put_op = GNUNET_DHT_put (peer1dht, &key, 1, GNUNET_DHT_RO_NONE, GNUNET_BLOCK_TYPE_TEST, + sizeof (data), data, GNUNET_TIME_UNIT_FOREVER_ABS, + GNUNET_TIME_UNIT_FOREVER_REL, &put_finished, NULL); } @@ -299,29 +312,23 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, if (emsg == NULL) { total_connections++; -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s, distance %u\n", first_daemon->shortname, second_daemon->shortname, distance); -#endif } -#if VERBOSE else { failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to connect peer %s to peer %s with error :\n%s\n", first_daemon->shortname, second_daemon->shortname, emsg); } -#endif if (total_connections == expected_connections) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created %d total connections, which is our target number! Starting next phase of testing.\n", total_connections); -#endif GNUNET_SCHEDULER_cancel (die_task); die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from test gets"); @@ -389,10 +396,8 @@ peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, if (peers_left == 0) /* Indicates all peers started */ { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All %d daemons started, now connecting peers!\n", num_peers); -#endif expected_connections = -1; if ((pg != NULL)) /* Sanity check */ { @@ -463,9 +468,6 @@ check () char *const argv[] = { "test-dht-twopeer-put-get", /* Name to give running binary */ "-c", "test_dht_twopeer_data.conf", /* Config file to use */ -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -490,11 +492,7 @@ main (int argc, char *argv[]) int ret; GNUNET_log_setup ("test-dht-twopeer", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); /** diff --git a/src/dns/Makefile.am b/src/dns/Makefile.am index 5bc8709..ed000aa 100644 --- a/src/dns/Makefile.am +++ b/src/dns/Makefile.am @@ -21,7 +21,7 @@ install-exec-hook: $(SUDO_BINARY) chown root $(bindir)/gnunet-helper-dns || true $(SUDO_BINARY) chgrp $(GNUNETDNS_GROUP) $(bindir)/gnunet-helper-dns || true $(SUDO_BINARY) chmod 4750 $(bindir)/gnunet-helper-dns || true - $(SUDO_BINARY) chgrp $(GNUNETDNS_GROUP) $(bindir)/gnunet-service-dns || true + $(SUDO_BINARY) chown gnunet:$(GNUNETDNS_GROUP) $(bindir)/gnunet-service-dns || true $(SUDO_BINARY) chmod 2750 $(bindir)/gnunet-service-dns || true else install-exec-hook: @@ -40,9 +40,10 @@ noinst_PROGRAMS = \ plugin_LTLIBRARIES = \ libgnunet_plugin_block_dns.la +if LINUX check_SCRIPTS = \ test_gnunet_dns.sh - +endif gnunet_helper_dns_SOURCES = \ gnunet-helper-dns.c diff --git a/src/dns/Makefile.in b/src/dns/Makefile.in index ee45c56..3a717ab 100644 --- a/src/dns/Makefile.in +++ b/src/dns/Makefile.in @@ -228,6 +228,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -261,6 +262,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -393,8 +395,8 @@ lib_LTLIBRARIES = \ plugin_LTLIBRARIES = \ libgnunet_plugin_block_dns.la -check_SCRIPTS = \ - test_gnunet_dns.sh +@LINUX_TRUE@check_SCRIPTS = \ +@LINUX_TRUE@ test_gnunet_dns.sh gnunet_helper_dns_SOURCES = \ gnunet-helper-dns.c @@ -1008,7 +1010,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ @LINUX_TRUE@ $(SUDO_BINARY) chown root $(bindir)/gnunet-helper-dns || true @LINUX_TRUE@ $(SUDO_BINARY) chgrp $(GNUNETDNS_GROUP) $(bindir)/gnunet-helper-dns || true @LINUX_TRUE@ $(SUDO_BINARY) chmod 4750 $(bindir)/gnunet-helper-dns || true -@LINUX_TRUE@ $(SUDO_BINARY) chgrp $(GNUNETDNS_GROUP) $(bindir)/gnunet-service-dns || true +@LINUX_TRUE@ $(SUDO_BINARY) chown gnunet:$(GNUNETDNS_GROUP) $(bindir)/gnunet-service-dns || true @LINUX_TRUE@ $(SUDO_BINARY) chmod 2750 $(bindir)/gnunet-service-dns || true @LINUX_FALSE@install-exec-hook: diff --git a/src/dns/dns.h b/src/dns/dns.h index 2b0ad03..ee95d9c 100644 --- a/src/dns/dns.h +++ b/src/dns/dns.h @@ -23,8 +23,8 @@ * @brief IPC messages between DNS API and DNS service * @author Christian Grothoff */ -#ifndef DNS_NEW_H -#define DNS_NEW_H +#ifndef DNS_H +#define DNS_H GNUNET_NETWORK_STRUCT_BEGIN diff --git a/src/dns/dns_api.c b/src/dns/dns_api.c index a280265..e006993 100644 --- a/src/dns/dns_api.c +++ b/src/dns/dns_api.c @@ -202,7 +202,7 @@ disconnect (struct GNUNET_DNS_Handle *dh) } if (NULL != dh->dns_connection) { - GNUNET_CLIENT_disconnect (dh->dns_connection, GNUNET_NO); + GNUNET_CLIENT_disconnect (dh->dns_connection); dh->dns_connection = NULL; } while (NULL != (qe = dh->rq_head)) diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index 1f48b10..6337538 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c @@ -289,6 +289,11 @@ struct TunnelState }; +/** + * Global return value from 'main'. + */ +static int global_ret; + /** * The configuration to use */ @@ -535,7 +540,7 @@ request_done (struct RequestRecord *rr) return; } { - char buf[reply_len]; + char buf[reply_len] GNUNET_ALIGN; size_t off; struct GNUNET_TUN_IPv4Header ip4; struct GNUNET_TUN_IPv6Header ip6; @@ -626,10 +631,10 @@ request_done (struct RequestRecord *rr) } /* final checks & sending */ GNUNET_assert (off == reply_len); - GNUNET_HELPER_send (hijacker, - hdr, - GNUNET_YES, - NULL, NULL); + (void) GNUNET_HELPER_send (hijacker, + hdr, + GNUNET_YES, + NULL, NULL); GNUNET_STATISTICS_update (stats, gettext_noop ("# DNS requests answered via TUN interface"), 1, GNUNET_NO); @@ -650,7 +655,7 @@ static void send_request_to_client (struct RequestRecord *rr, struct GNUNET_SERVER_Client *client) { - char buf[sizeof (struct GNUNET_DNS_Request) + rr->payload_length]; + char buf[sizeof (struct GNUNET_DNS_Request) + rr->payload_length] GNUNET_ALIGN; struct GNUNET_DNS_Request *req; if (sizeof (buf) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) @@ -729,7 +734,6 @@ get_request_socket (int af) if (NULL != rs->dnsout6) GNUNET_NETWORK_fdset_set (rset, rs->dnsout6); rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, REQUEST_TIMEOUT, rset, NULL, @@ -982,7 +986,7 @@ do_dns_read (struct GNUNET_NETWORK_Handle *dnsout) #endif { - unsigned char buf[len]; + unsigned char buf[len] GNUNET_ALIGN; addrlen = sizeof (addr); memset (&addr, 0, sizeof (addr)); @@ -1095,7 +1099,6 @@ read_response (void *cls, if (NULL != rs->dnsout6) GNUNET_NETWORK_fdset_set (rset, rs->dnsout6); rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_absolute_get_remaining (rs->timeout), rset, NULL, @@ -1193,10 +1196,8 @@ handle_client_response (void *cls GNUNET_UNUSED, return; } GNUNET_free_non_null (rr->payload); -#if DEBUG_DNS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Changing DNS reply according to client specifications\n")); -#endif + "Changing DNS reply according to client specifications\n"); rr->payload = GNUNET_malloc (msize); rr->payload_length = msize; memcpy (rr->payload, &resp[1], msize); @@ -1238,7 +1239,7 @@ handle_client_response (void *cls GNUNET_UNUSED, * @param client identification of the client * @param message the actual message, a DNS request we should handle */ -static void +static int process_helper_messages (void *cls GNUNET_UNUSED, void *client, const struct GNUNET_MessageHeader *message) { @@ -1259,7 +1260,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, { /* non-IP packet received on TUN!? */ GNUNET_break (0); - return; + return GNUNET_OK; } msize -= sizeof (struct GNUNET_MessageHeader); tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1]; @@ -1268,6 +1269,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, { case ETH_P_IPV4: ip4 = (const struct GNUNET_TUN_IPv4Header *) &tun[1]; + ip6 = NULL; /* make compiler happy */ if ( (msize < sizeof (struct GNUNET_TUN_IPv4Header)) || (ip4->version != 4) || (ip4->header_length != sizeof (struct GNUNET_TUN_IPv4Header) / 4) || @@ -1277,12 +1279,13 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, /* non-IP/UDP packet received on TUN (or with options) */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received malformed IPv4-UDP packet on TUN interface.\n")); - return; + return GNUNET_OK; } udp = (const struct GNUNET_TUN_UdpHeader*) &ip4[1]; msize -= sizeof (struct GNUNET_TUN_IPv4Header); break; case ETH_P_IPV6: + ip4 = NULL; /* make compiler happy */ ip6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1]; if ( (msize < sizeof (struct GNUNET_TUN_IPv6Header)) || (ip6->version != 6) || @@ -1292,7 +1295,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, /* non-IP/UDP packet received on TUN (or with extensions) */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received malformed IPv6-UDP packet on TUN interface.\n")); - return; + return GNUNET_OK; } udp = (const struct GNUNET_TUN_UdpHeader*) &ip6[1]; msize -= sizeof (struct GNUNET_TUN_IPv6Header); @@ -1303,7 +1306,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, _("Got non-IP packet with %u bytes and protocol %u from TUN\n"), (unsigned int) msize, ntohs (tun->proto)); - return; + return GNUNET_OK; } if (msize <= sizeof (struct GNUNET_TUN_UdpHeader) + sizeof (struct GNUNET_TUN_DnsHeader)) { @@ -1311,7 +1314,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, GNUNET_STATISTICS_update (stats, gettext_noop ("# Non-DNS UDP packet received via TUN interface"), 1, GNUNET_NO); - return; + return GNUNET_OK; } msize -= sizeof (struct GNUNET_TUN_UdpHeader); dns = (const struct GNUNET_TUN_DnsHeader*) &udp[1]; @@ -1378,6 +1381,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, 1, GNUNET_NO); /* start request processing state machine */ next_phase (rr); + return GNUNET_OK; } @@ -1404,7 +1408,7 @@ receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, const struct GNUNET_TUN_DnsHeader *dns; size_t mlen = ntohs (message->size); size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); - char buf[dlen]; + char buf[dlen] GNUNET_ALIGN; struct GNUNET_TUN_DnsHeader *dout; struct sockaddr_in v4; struct sockaddr_in6 v6; @@ -1550,6 +1554,16 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, struct in6_addr dns_exit6; cfg = cfg_; + if (GNUNET_YES != + GNUNET_OS_check_helper_binary ("gnunet-helper-dns")) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("`%s' must be installed SUID, refusing to run\n"), + "gnunet-helper-dns"); + global_ret = 1; + return; + } + stats = GNUNET_STATISTICS_create ("dns", cfg); nc = GNUNET_SERVER_notification_context_create (server, 1); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, @@ -1660,7 +1674,7 @@ main (int argc, char *const *argv) { return (GNUNET_OK == GNUNET_SERVICE_run (argc, argv, "dns", GNUNET_SERVICE_OPTION_NONE, - &run, NULL)) ? 0 : 1; + &run, NULL)) ? global_ret : 1; } diff --git a/src/dns/plugin_block_dns.c b/src/dns/plugin_block_dns.c index 96a4dc0..da8add5 100644 --- a/src/dns/plugin_block_dns.c +++ b/src/dns/plugin_block_dns.c @@ -85,7 +85,7 @@ block_plugin_dns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } - if (GNUNET_TIME_relative_get_zero ().rel_value == + if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (rec->expiration_time)).rel_value) { diff --git a/src/dv/Makefile.in b/src/dv/Makefile.in index 93f5228..3389e56 100644 --- a/src/dv/Makefile.in +++ b/src/dv/Makefile.in @@ -210,6 +210,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -243,6 +244,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c index 876282e..93891ca 100644 --- a/src/dv/dv_api.c +++ b/src/dv/dv_api.c @@ -618,7 +618,7 @@ GNUNET_DV_disconnect (struct GNUNET_DV_Handle *handle) } if (handle->client != NULL) /* Finally, disconnect from the service */ { - GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (handle->client); handle->client = NULL; } diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index 50aac09..956595f 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c @@ -582,7 +582,7 @@ static char *my_short_id; /** * Transmit handle to the plugin. */ -static struct GNUNET_CONNECTION_TransmitHandle *plugin_transmit_handle; +static struct GNUNET_SERVER_TransmitHandle *plugin_transmit_handle; /** * Head of DLL for client messages @@ -1288,7 +1288,7 @@ checkPeerID (void *cls, const GNUNET_HashCode * key, void *value) * @param client the TokenizedMessageContext which contains message information * @param message the actual message */ -void +int tokenized_message_handler (void *cls, void *client, const struct GNUNET_MessageHeader *message) { @@ -1312,6 +1312,7 @@ tokenized_message_handler (void *cls, void *client, send_to_plugin (ctx->peer, message, ntohs (message->size), &ctx->distant->identity, ctx->distant->cost); } + return GNUNET_OK; } #if DELAY_FORWARDS @@ -1333,7 +1334,7 @@ send_message_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { send_message (&msg_ctx->dest, &msg_ctx->sender, NULL, msg_ctx->message, msg_ctx->message_size, default_dv_priority, msg_ctx->uid, - GNUNET_TIME_relative_get_forever ()); + GNUNET_TIME_UNIT_FOREVER_REL); GNUNET_free (msg_ctx->message); GNUNET_free (msg_ctx); } @@ -1628,7 +1629,7 @@ handle_dv_data_message (void *cls, const struct GNUNET_PeerIdentity *peer, send_message (destination, original_sender, NULL, packed_message, packed_message_size, default_dv_priority, ntohl (incoming->uid), - GNUNET_TIME_relative_get_forever ()); + GNUNET_TIME_UNIT_FOREVER_REL); } if (ret != GNUNET_SYSERR) return GNUNET_OK; @@ -1763,7 +1764,7 @@ neighbor_send_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sizeof (p2p_dv_MESSAGE_NeighborInfo)); pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1]; pending_message->importance = default_dv_priority; - pending_message->timeout = GNUNET_TIME_relative_get_forever (); + pending_message->timeout = GNUNET_TIME_UNIT_FOREVER_REL; memcpy (&pending_message->recipient, &to->identity, sizeof (struct GNUNET_PeerIdentity)); pending_message->msg_size = sizeof (p2p_dv_MESSAGE_NeighborInfo); @@ -1783,7 +1784,7 @@ neighbor_send_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_SCHEDULER_add_now (try_core_send, NULL); /*if (core_transmit_handle == NULL) - * core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI, GNUNET_YES, default_dv_priority, GNUNET_TIME_relative_get_forever(), &to->identity, sizeof(p2p_dv_MESSAGE_NeighborInfo), &core_transmit_notify, NULL); */ + * core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI, GNUNET_YES, default_dv_priority, GNUNET_TIME_UNIT_FOREVER_REL, &to->identity, sizeof(p2p_dv_MESSAGE_NeighborInfo), &core_transmit_notify, NULL); */ } @@ -2192,7 +2193,7 @@ schedule_disconnect_messages (void *cls, const GNUNET_HashCode * key, sizeof (p2p_dv_MESSAGE_Disconnect)); pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1]; pending_message->importance = default_dv_priority; - pending_message->timeout = GNUNET_TIME_relative_get_forever (); + pending_message->timeout = GNUNET_TIME_UNIT_FOREVER_REL; memcpy (&pending_message->recipient, ¬ify->identity, sizeof (struct GNUNET_PeerIdentity)); pending_message->msg_size = sizeof (p2p_dv_MESSAGE_Disconnect); @@ -2206,7 +2207,7 @@ schedule_disconnect_messages (void *cls, const GNUNET_HashCode * key, GNUNET_SCHEDULER_add_now (try_core_send, NULL); /*if (core_transmit_handle == NULL) - * core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI, GNUNET_YES, default_dv_priority, GNUNET_TIME_relative_get_forever(), ¬ify->identity, sizeof(p2p_dv_MESSAGE_Disconnect), &core_transmit_notify, NULL); */ + * core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI, GNUNET_YES, default_dv_priority, GNUNET_TIME_UNIT_FOREVER_REL, ¬ify->identity, sizeof(p2p_dv_MESSAGE_Disconnect), &core_transmit_notify, NULL); */ return GNUNET_YES; } diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c index 8ee49c5..3a8bafc 100644 --- a/src/dv/plugin_transport_dv.c +++ b/src/dv/plugin_transport_dv.c @@ -385,9 +385,7 @@ dv_plugin_check_address (void *cls, const void *addr, size_t addrlen) * notify us by calling the env->session_end function * * @param cls the plugin - * @param target the neighbour id - * @param addr pointer to the address - * @param addrlen length of addr + * @param address the address * @return the session if the address is valid, NULL otherwise */ static struct Session * diff --git a/src/dv/test_transport_api_dv.c b/src/dv/test_transport_api_dv.c index 386ea5f..6165a9d 100644 --- a/src/dv/test_transport_api_dv.c +++ b/src/dv/test_transport_api_dv.c @@ -1127,7 +1127,7 @@ run (void *cls, char *const *args, const char *cfgfile, "connect_topology_option_modifier", &connect_topology_option_modifier_string)) { - if (sscanf + if (SSCANF (connect_topology_option_modifier_string, "%lf", &connect_topology_option_modifier) != 1) { diff --git a/src/exit/Makefile.in b/src/exit/Makefile.in index 8e334e2..0caead9 100644 --- a/src/exit/Makefile.in +++ b/src/exit/Makefile.in @@ -187,6 +187,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -220,6 +221,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/exit/exit.h b/src/exit/exit.h index dcc50f1..90df26d 100644 --- a/src/exit/exit.h +++ b/src/exit/exit.h @@ -49,7 +49,7 @@ struct GNUNET_EXIT_TcpServiceStartMessage /** * Identification for the desired service. */ - GNUNET_HashCode service_descriptor GNUNET_PACKED; + GNUNET_HashCode service_descriptor; /** * Skeleton of the TCP header to send. Port numbers are to @@ -142,7 +142,7 @@ struct GNUNET_EXIT_UdpServiceMessage /** * Identification for the desired service. */ - GNUNET_HashCode service_descriptor GNUNET_PACKED; + GNUNET_HashCode service_descriptor; /* followed by UDP payload */ }; @@ -230,7 +230,7 @@ struct GNUNET_EXIT_IcmpServiceMessage /** * Identification for the desired service. */ - GNUNET_HashCode service_descriptor GNUNET_PACKED; + GNUNET_HashCode service_descriptor; /** * ICMP header to use. diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index 3bf26d7..26f3e75 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c @@ -284,7 +284,7 @@ static struct GNUNET_CONTAINER_Heap *connections_heap; /** * If there are at least this many connections, old ones will be removed */ -static long long unsigned int max_connections; +static unsigned long long max_connections; /** * This hashmaps saves interesting things about the configured UDP services @@ -876,7 +876,7 @@ tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, const void *source_ip) { struct TunnelState *state; - char buf[pktlen]; + char buf[pktlen] GNUNET_ALIGN; struct GNUNET_TUN_TcpHeader *mtcp; struct GNUNET_EXIT_TcpDataMessage *tdm; struct TunnelMessageQueue *tnq; @@ -953,7 +953,7 @@ tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, * @param client unsued * @param message message received from helper */ -static void +static int message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, const struct GNUNET_MessageHeader *message) { @@ -970,13 +970,13 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) { GNUNET_break (0); - return; + return GNUNET_OK; } size = ntohs (message->size); if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader)) { GNUNET_break (0); - return; + return GNUNET_OK; } GNUNET_STATISTICS_update (stats, gettext_noop ("# Bytes received from TUN"), @@ -993,20 +993,20 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, { /* Kernel to blame? */ GNUNET_break (0); - return; + return GNUNET_OK; } pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1]; if (size != ntohs (pkt4->total_length)) { /* Kernel to blame? */ GNUNET_break (0); - return; + return GNUNET_OK; } if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("IPv4 packet options received. Ignored.\n")); - return; + return GNUNET_OK; } size -= sizeof (struct GNUNET_TUN_IPv4Header); @@ -1034,7 +1034,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("IPv4 packet with unsupported next header %u received. Ignored.\n"), (int) pkt4->protocol); - return; + return GNUNET_OK; } } break; @@ -1046,14 +1046,14 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, { /* Kernel to blame? */ GNUNET_break (0); - return; + return GNUNET_OK; } pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1]; if (size != ntohs (pkt6->payload_length) + sizeof (struct GNUNET_TUN_IPv6Header)) { /* Kernel to blame? */ GNUNET_break (0); - return; + return GNUNET_OK; } size -= sizeof (struct GNUNET_TUN_IPv6Header); switch (pkt6->next_header) @@ -1080,7 +1080,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("IPv6 packet with unsupported next header %d received. Ignored.\n"), pkt6->next_header); - return; + return GNUNET_OK; } } break; @@ -1090,6 +1090,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, ntohs (pkt_tun->proto)); break; } + return GNUNET_OK; } @@ -1493,7 +1494,7 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, return; } { - char buf[len]; + char buf[len] GNUNET_ALIGN; struct GNUNET_MessageHeader *hdr; struct GNUNET_TUN_Layer2PacketHeader *tun; @@ -1852,7 +1853,7 @@ send_icmp_packet_via_tun (const struct SocketAddress *destination_address, return; } { - char buf[len]; + char buf[len] GNUNET_ALIGN; struct GNUNET_MessageHeader *hdr; struct GNUNET_TUN_Layer2PacketHeader *tun; @@ -1985,7 +1986,7 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, const struct in_addr *v4; const struct in6_addr *v6; const void *payload; - char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8]; + char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; int af; GNUNET_STATISTICS_update (stats, @@ -2227,7 +2228,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel const struct GNUNET_EXIT_IcmpServiceMessage *msg; uint16_t pkt_len = ntohs (message->size); struct GNUNET_TUN_IcmpHeader icmp; - char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8]; + char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; const void *payload; GNUNET_STATISTICS_update (stats, @@ -2435,7 +2436,7 @@ send_udp_packet_via_tun (const struct SocketAddress *destination_address, return; } { - char buf[len]; + char buf[len] GNUNET_ALIGN; struct GNUNET_MessageHeader *hdr; struct GNUNET_TUN_Layer2PacketHeader *tun; @@ -3027,9 +3028,9 @@ run (void *cls, char *const *args GNUNET_UNUSED, if (GNUNET_YES != GNUNET_OS_check_helper_binary ("gnunet-helper-exit")) { - fprintf (stderr, - "`%s' is not SUID, refusing to run.\n", - "gnunet-helper-exit"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("`%s' must be installed SUID, refusing to run\n"), + "gnunet-helper-exit"); global_ret = 1; return; } diff --git a/src/fragmentation/Makefile.am b/src/fragmentation/Makefile.am index 1cdbefc..c5027c7 100644 --- a/src/fragmentation/Makefile.am +++ b/src/fragmentation/Makefile.am @@ -18,7 +18,7 @@ libgnunetfragmentation_la_LIBADD = -lm \ $(top_builddir)/src/util/libgnunetutil.la libgnunetfragmentation_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 0:0:0 + -version-info 1:0:1 check_PROGRAMS = \ test_fragmentation diff --git a/src/fragmentation/Makefile.in b/src/fragmentation/Makefile.in index 2ccad77..2c297cb 100644 --- a/src/fragmentation/Makefile.in +++ b/src/fragmentation/Makefile.in @@ -189,6 +189,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -222,6 +223,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -352,7 +354,7 @@ libgnunetfragmentation_la_LIBADD = -lm \ libgnunetfragmentation_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 0:0:0 + -version-info 1:0:1 @ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) test_fragmentation_SOURCES = \ diff --git a/src/fragmentation/defragmentation.c b/src/fragmentation/defragmentation.c index b07f204..2d3f4a5 100644 --- a/src/fragmentation/defragmentation.c +++ b/src/fragmentation/defragmentation.c @@ -362,7 +362,7 @@ estimate_latency (struct MessageContext *mc) if (ret.rel_value == 0) ret = GNUNET_TIME_UNIT_MILLISECONDS; /* always at least 1 */ return ret; -}; +} /** @@ -420,7 +420,9 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, unsigned int bc; unsigned int b; unsigned int n; + unsigned int num_fragments; int duplicate; + int last; if (ntohs (msg->size) < sizeof (struct FragmentHeader)) { @@ -452,6 +454,12 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, return GNUNET_SYSERR; } GNUNET_STATISTICS_update (dc->stats, _("# fragments received"), 1, GNUNET_NO); + num_fragments = (ntohs (msg->size) + dc->mtu - sizeof (struct FragmentHeader)-1) / (dc->mtu - sizeof (struct FragmentHeader)); + last = 0; + for (mc = dc->head; NULL != mc; mc = mc->next) + if (mc->fragment_id > fid) + last++; + mc = dc->head; while ((NULL != mc) && (fid != mc->fragment_id)) mc = mc->next; @@ -530,10 +538,16 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, } /* send ACK */ if (mc->frag_times_write_offset - mc->frag_times_start_offset > 1) + { dc->latency = estimate_latency (mc); + } delay = GNUNET_TIME_relative_multiply (dc->latency, bc + 1); - if ((0 == mc->bits) || (GNUNET_YES == duplicate)) /* message complete or duplicate, ACK now! */ + if ( (last + fid == num_fragments) || + (0 == mc->bits) || + (GNUNET_YES == duplicate)) { + /* message complete or duplicate or last missing fragment in + linear sequence; ACK now! */ delay = GNUNET_TIME_UNIT_ZERO; } if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task) diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c index 8fab3fe..4749f53 100644 --- a/src/fragmentation/fragmentation.c +++ b/src/fragmentation/fragmentation.c @@ -28,6 +28,12 @@ #include "fragmentation.h" +/** + * Absolute minimum delay we impose between sending and expecting ACK to arrive. + */ +#define MIN_ACK_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1) + + /** * Fragmentation context. */ @@ -104,6 +110,11 @@ struct GNUNET_FRAGMENT_Context */ unsigned int num_rounds; + /** + * How many transmission have we completed in this round? + */ + unsigned int num_transmissions; + /** * GNUNET_YES if we called 'proc' and are now waiting for 'GNUNET_FRAGMENT_transmission_done' */ @@ -145,13 +156,12 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (GNUNET_NO == fc->proc_busy); if (0 == fc->acks) return; /* all done */ - /* calculate delay */ wrap = 0; while (0 == (fc->acks & (1LL << fc->next_transmission))) { fc->next_transmission = (fc->next_transmission + 1) % 64; - wrap |= (fc->next_transmission == 0); + wrap |= (0 == fc->next_transmission); } bit = fc->next_transmission; size = ntohs (fc->msg->size); @@ -161,7 +171,7 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sizeof (struct FragmentHeader); else fsize = fc->mtu; - if (fc->tracker != NULL) + if (NULL != fc->tracker) delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize); else delay = GNUNET_TIME_UNIT_ZERO; @@ -172,6 +182,11 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } fc->next_transmission = (fc->next_transmission + 1) % 64; wrap |= (fc->next_transmission == 0); + while (0 == (fc->acks & (1LL << fc->next_transmission))) + { + fc->next_transmission = (fc->next_transmission + 1) % 64; + wrap |= (fc->next_transmission == 0); + } /* assemble fragmentation message */ mbuf = (const char *) &fc[1]; @@ -211,12 +226,15 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_TIME_relative_multiply (fc->delay, fc->num_rounds)); /* never use zero, need some time for ACK always */ - delay = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, delay); - fc->last_round = GNUNET_TIME_absolute_get (); + delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay); fc->wack = GNUNET_YES; + fc->last_round = GNUNET_TIME_absolute_get (); + GNUNET_STATISTICS_update (fc->stats, _("# fragments wrap arounds"), 1, + GNUNET_NO); } fc->proc_busy = GNUNET_YES; fc->delay_until = GNUNET_TIME_relative_to_absolute (delay); + fc->num_transmissions++; fc->proc (fc->proc_cls, &fh->header); } @@ -251,7 +269,7 @@ GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, struct GNUNET_FRAGMENT_Context *fc; size_t size; uint64_t bits; - + GNUNET_STATISTICS_update (stats, _("# messages fragmented"), 1, GNUNET_NO); GNUNET_assert (mtu >= 1024 + sizeof (struct FragmentHeader)); size = ntohs (msg->size); @@ -331,13 +349,15 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc, if (ntohl (fa->fragment_id) != fc->fragment_id) return GNUNET_SYSERR; /* not our ACK */ abits = GNUNET_ntohll (fa->bits); - if ((GNUNET_YES == fc->wack) && (abits == (fc->acks & abits))) + if ( (GNUNET_YES == fc->wack) && + (0 != fc->num_transmissions) ) { /* normal ACK, can update running average of delay... */ fc->wack = GNUNET_NO; ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round); fc->delay.rel_value = - (ndelay.rel_value * fc->num_rounds + 3 * fc->delay.rel_value) / 4; + (ndelay.rel_value / fc->num_transmissions + 3 * fc->delay.rel_value) / 4; + fc->num_transmissions = 0; } GNUNET_STATISTICS_update (fc->stats, _("# fragment acknowledgements received"), 1, diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index 0de739d..b916e4e 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am @@ -50,7 +50,7 @@ libgnunetfs_la_LIBADD = \ libgnunetfs_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 2:0:0 + -version-info 2:1:0 libgnunetfstest_a_SOURCES = \ @@ -206,6 +206,7 @@ check_PROGRAMS = \ test_fs_publish \ test_fs_publish_persistence \ test_fs_search \ + test_fs_search_probes \ test_fs_search_persistence \ test_fs_start_stop \ test_fs_test_lib \ @@ -225,6 +226,11 @@ check_SCRIPTS = \ test_gnunet_fs_ns.py endif +if ENABLE_MONKEY + TESTS_ENVIRONMENT = @MONKEYPREFIX@ + AM_LDFLAGS = -no-install +endif + if ENABLE_TEST_RUN TESTS = \ @@ -239,6 +245,7 @@ TESTS = \ test_fs_publish \ test_fs_publish_persistence \ test_fs_search \ + test_fs_search_probes \ test_fs_search_persistence \ test_fs_start_stop \ test_fs_unindex \ @@ -329,6 +336,11 @@ test_fs_search_SOURCES = \ test_fs_search_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la +test_fs_search_probes_SOURCES = \ + test_fs_search_probes.c +test_fs_search_probes_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la + test_fs_search_persistence_SOURCES = \ test_fs_search_persistence.c test_fs_search_persistence_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \ diff --git a/src/fs/Makefile.in b/src/fs/Makefile.in index cbc844e..1dc8dba 100644 --- a/src/fs/Makefile.in +++ b/src/fs/Makefile.in @@ -51,7 +51,8 @@ check_PROGRAMS = test_fs_directory$(EXEEXT) test_fs_download$(EXEEXT) \ test_fs_list_indexed$(EXEEXT) test_fs_namespace$(EXEEXT) \ test_fs_namespace_list_updateable$(EXEEXT) \ test_fs_publish$(EXEEXT) test_fs_publish_persistence$(EXEEXT) \ - test_fs_search$(EXEEXT) test_fs_search_persistence$(EXEEXT) \ + test_fs_search$(EXEEXT) test_fs_search_probes$(EXEEXT) \ + test_fs_search_persistence$(EXEEXT) \ test_fs_start_stop$(EXEEXT) test_fs_test_lib$(EXEEXT) \ test_fs_unindex$(EXEEXT) test_fs_unindex_persistence$(EXEEXT) \ test_fs_uri$(EXEEXT) test_gnunet_service_fs_migration$(EXEEXT) \ @@ -67,6 +68,7 @@ check_PROGRAMS = test_fs_directory$(EXEEXT) test_fs_download$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_publish$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_publish_persistence$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_search$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_fs_search_probes$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_search_persistence$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_start_stop$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_unindex$(EXEEXT) \ @@ -310,6 +312,11 @@ test_fs_search_persistence_OBJECTS = \ test_fs_search_persistence_DEPENDENCIES = \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la +am_test_fs_search_probes_OBJECTS = test_fs_search_probes.$(OBJEXT) +test_fs_search_probes_OBJECTS = $(am_test_fs_search_probes_OBJECTS) +test_fs_search_probes_DEPENDENCIES = \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la am_test_fs_start_stop_OBJECTS = test_fs_start_stop.$(OBJEXT) test_fs_start_stop_OBJECTS = $(am_test_fs_start_stop_OBJECTS) test_fs_start_stop_DEPENDENCIES = \ @@ -401,8 +408,8 @@ SOURCES = $(libgnunetfstest_a_SOURCES) \ $(test_fs_publish_persistence_SOURCES) \ $(test_fs_search_SOURCES) \ $(test_fs_search_persistence_SOURCES) \ - $(test_fs_start_stop_SOURCES) $(test_fs_test_lib_SOURCES) \ - $(test_fs_unindex_SOURCES) \ + $(test_fs_search_probes_SOURCES) $(test_fs_start_stop_SOURCES) \ + $(test_fs_test_lib_SOURCES) $(test_fs_unindex_SOURCES) \ $(test_fs_unindex_persistence_SOURCES) $(test_fs_uri_SOURCES) \ $(test_gnunet_service_fs_migration_SOURCES) \ $(test_gnunet_service_fs_p2p_SOURCES) @@ -428,8 +435,8 @@ DIST_SOURCES = $(libgnunetfstest_a_SOURCES) \ $(test_fs_publish_persistence_SOURCES) \ $(test_fs_search_SOURCES) \ $(test_fs_search_persistence_SOURCES) \ - $(test_fs_start_stop_SOURCES) $(test_fs_test_lib_SOURCES) \ - $(test_fs_unindex_SOURCES) \ + $(test_fs_search_probes_SOURCES) $(test_fs_start_stop_SOURCES) \ + $(test_fs_test_lib_SOURCES) $(test_fs_unindex_SOURCES) \ $(test_fs_unindex_persistence_SOURCES) $(test_fs_uri_SOURCES) \ $(test_gnunet_service_fs_migration_SOURCES) \ $(test_gnunet_service_fs_p2p_SOURCES) @@ -494,6 +501,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -527,6 +535,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -683,7 +692,7 @@ libgnunetfs_la_LIBADD = \ libgnunetfs_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 2:0:0 + -version-info 2:1:0 libgnunetfstest_a_SOURCES = \ fs_test_lib.c fs_test_lib.h @@ -836,6 +845,8 @@ libgnunet_plugin_block_fs_la_DEPENDENCIES = \ @HAVE_PYTHON_PEXPECT_TRUE@ test_gnunet_fs_idx.py \ @HAVE_PYTHON_PEXPECT_TRUE@ test_gnunet_fs_ns.py +@ENABLE_MONKEY_TRUE@TESTS_ENVIRONMENT = @MONKEYPREFIX@ +@ENABLE_MONKEY_TRUE@AM_LDFLAGS = -no-install test_fs_directory_SOURCES = \ test_fs_directory.c @@ -921,6 +932,12 @@ test_fs_search_SOURCES = \ test_fs_search_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la +test_fs_search_probes_SOURCES = \ + test_fs_search_probes.c + +test_fs_search_probes_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la + test_fs_search_persistence_SOURCES = \ test_fs_search_persistence.c @@ -1288,6 +1305,9 @@ test_fs_search$(EXEEXT): $(test_fs_search_OBJECTS) $(test_fs_search_DEPENDENCIES test_fs_search_persistence$(EXEEXT): $(test_fs_search_persistence_OBJECTS) $(test_fs_search_persistence_DEPENDENCIES) @rm -f test_fs_search_persistence$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_search_persistence_OBJECTS) $(test_fs_search_persistence_LDADD) $(LIBS) +test_fs_search_probes$(EXEEXT): $(test_fs_search_probes_OBJECTS) $(test_fs_search_probes_DEPENDENCIES) + @rm -f test_fs_search_probes$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_fs_search_probes_OBJECTS) $(test_fs_search_probes_LDADD) $(LIBS) test_fs_start_stop$(EXEEXT): $(test_fs_start_stop_OBJECTS) $(test_fs_start_stop_DEPENDENCIES) @rm -f test_fs_start_stop$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_start_stop_OBJECTS) $(test_fs_start_stop_LDADD) $(LIBS) @@ -1400,6 +1420,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_publish_persistence.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_search.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_search_persistence.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_search_probes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_start_stop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_test_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_unindex.Po@am__quote@ diff --git a/src/fs/fs.conf.in b/src/fs/fs.conf.in index 48c8b52..a908b1f 100644 --- a/src/fs/fs.conf.in +++ b/src/fs/fs.conf.in @@ -1,10 +1,10 @@ [fs] AUTOSTART = YES -INDEXDB = $SERVICEHOME/idxinfo.lst -TRUST = $SERVICEHOME/data/credit/ -IDENTITY_DIR = $SERVICEHOME/identities/ -STATE_DIR = $SERVICEHOME/persistence/ -UPDATE_DIR = $SERVICEHOME/updates/ +INDEXDB = $SERVICEHOME/fs/idxinfo.lst +TRUST = $SERVICEHOME/fs/credit/ +IDENTITY_DIR = $SERVICEHOME/fs/identities/ +STATE_DIR = $SERVICEHOME/fs/persistence/ +UPDATE_DIR = $SERVICEHOME/fs/updates/ @UNIXONLY@ PORT = 2094 HOSTNAME = localhost HOME = $SERVICEHOME @@ -20,7 +20,6 @@ CONTENT_PUSHING = YES UNIXPATH = /tmp/gnunet-service-fs.sock UNIX_MATCH_UID = NO UNIX_MATCH_GID = YES -# DISABLE_SOCKET_FORWARDING = NO # DEBUG = YES MAX_PENDING_REQUESTS = 65536 # Maximum frequency we're allowed to poll the datastore @@ -29,4 +28,6 @@ MAX_PENDING_REQUESTS = 65536 MIN_MIGRATION_DELAY = 100 ms EXPECTED_NEIGHBOUR_COUNT = 128 +# Enable monkey? +PREFIX = @MONKEYPREFIX@ diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c index 1df9b2e..651c174 100644 --- a/src/fs/fs_api.c +++ b/src/fs/fs_api.c @@ -30,6 +30,15 @@ #include "fs_api.h" #include "fs_tree.h" +/** + * How many block requests can we have outstanding in parallel at a time by default? + */ +#define DEFAULT_MAX_PARALLEL_REQUESTS (1024 * 10) + +/** + * How many downloads can we have outstanding in parallel at a time by default? + */ +#define DEFAULT_MAX_PARALLEL_DOWNLOADS 16 /** * Start the given job (send signal, remove from pending queue, update @@ -99,6 +108,8 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_TIME_Absolute end_time; h->queue_job = GNUNET_SCHEDULER_NO_TASK; + restart_at = GNUNET_TIME_UNIT_FOREVER_REL; + /* first, see if we can start all the jobs */ next = h->pending_head; while (NULL != (qe = next)) { @@ -109,7 +120,7 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) continue; } if ((qe->blocks + h->active_blocks <= h->max_parallel_requests) && - (h->active_downloads + 1 <= h->max_parallel_downloads)) + (h->active_downloads < h->max_parallel_downloads)) { start_job (qe); continue; @@ -117,7 +128,7 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } if (h->pending_head == NULL) return; /* no need to stop anything */ - restart_at = GNUNET_TIME_UNIT_FOREVER_REL; + /* then, check if we should stop some jobs */ next = h->running_head; while (NULL != (qe = next)) { @@ -125,6 +136,22 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) run_time = GNUNET_TIME_relative_multiply (h->avg_block_latency, qe->blocks * qe->start_times); + switch (qe->priority) + { + case GNUNET_FS_QUEUE_PRIORITY_PROBE: + /* run probes for at most 1s * number-of-restarts; note that + as the total runtime of a probe is limited to 2m, we don't + need to additionally limit the total time of a probe to + strictly limit its lifetime. */ + run_time = GNUNET_TIME_relative_min (run_time, + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, + 1 + qe->start_times)); + break; + case GNUNET_FS_QUEUE_PRIORITY_NORMAL: + break; + default: + GNUNET_break (0); + } end_time = GNUNET_TIME_absolute_add (qe->start_time, run_time); rst = GNUNET_TIME_absolute_get_remaining (end_time); restart_at = GNUNET_TIME_relative_min (rst, restart_at); @@ -132,6 +159,18 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) continue; stop_job (qe); } + /* finally, start some more tasks if we now have empty slots */ + next = h->pending_head; + while (NULL != (qe = next)) + { + next = qe->next; + if ((qe->blocks + h->active_blocks <= h->max_parallel_requests) && + (h->active_downloads < h->max_parallel_downloads)) + { + start_job (qe); + continue; + } + } h->queue_job = GNUNET_SCHEDULER_add_delayed (restart_at, &process_job_queue, h); } @@ -145,11 +184,13 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param stop function to call to pause the job, or on dequeue (if the job was running) * @param cls closure for start and stop * @param blocks number of blocks this jobs uses + * @param priority how important is this download * @return queue handle */ struct GNUNET_FS_QueueEntry * GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, GNUNET_FS_QueueStart start, - GNUNET_FS_QueueStop stop, void *cls, unsigned int blocks) + GNUNET_FS_QueueStop stop, void *cls, unsigned int blocks, + enum GNUNET_FS_QueuePriority priority) { struct GNUNET_FS_QueueEntry *qe; @@ -160,6 +201,7 @@ GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, GNUNET_FS_QueueStart start, qe->cls = cls; qe->queue_time = GNUNET_TIME_absolute_get (); qe->blocks = blocks; + qe->priority = priority; GNUNET_CONTAINER_DLL_insert_after (h->pending_head, h->pending_tail, h->pending_tail, qe); if (h->queue_job != GNUNET_SCHEDULER_NO_TASK) @@ -249,7 +291,11 @@ struct FileInfo * @param cls closure (points to the file information) * @param offset offset to read from; it is possible * that the caller might need to go backwards - * a bit at times + * a bit at times; set to UINT64_MAX to tell + * the reader that we won't be reading for a while + * (used to close the file descriptor but NOT fully + * clean up the reader's state); in this case, + * a value of '0' for max should be ignored * @param max maximum number of bytes that should be * copied to buf; readers are not allowed * to provide less data unless there is an error; @@ -266,20 +312,29 @@ GNUNET_FS_data_reader_file_ (void *cls, uint64_t offset, size_t max, void *buf, struct FileInfo *fi = cls; ssize_t ret; - if (max == 0) + if (UINT64_MAX == offset) { - if (fi->fd != NULL) + if (NULL != fi->fd) + { + GNUNET_DISK_file_close (fi->fd); + fi->fd = NULL; + } + return 0; + } + if (0 == max) + { + if (NULL != fi->fd) GNUNET_DISK_file_close (fi->fd); GNUNET_free (fi->filename); GNUNET_free (fi); return 0; } - if (fi->fd == NULL) + if (NULL == fi->fd) { fi->fd = GNUNET_DISK_file_open (fi->filename, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); - if (fi->fd == NULL) + if (NULL == fi->fd) { GNUNET_asprintf (emsg, _("Could not open file `%s': %s"), fi->filename, STRERROR (errno)); @@ -288,7 +343,7 @@ GNUNET_FS_data_reader_file_ (void *cls, uint64_t offset, size_t max, void *buf, } GNUNET_DISK_file_seek (fi->fd, offset, GNUNET_DISK_SEEK_SET); ret = GNUNET_DISK_file_read (fi->fd, buf, max); - if (ret == -1) + if (-1 == ret) { GNUNET_asprintf (emsg, _("Could not read file `%s': %s"), fi->filename, STRERROR (errno)); @@ -332,7 +387,11 @@ GNUNET_FS_make_file_reader_context_ (const char *filename) * @param cls closure (points to the buffer) * @param offset offset to read from; it is possible * that the caller might need to go backwards - * a bit at times + * a bit at times; set to UINT64_MAX to tell + * the reader that we won't be reading for a while + * (used to close the file descriptor but NOT fully + * clean up the reader's state); in this case, + * a value of '0' for max should be ignored * @param max maximum number of bytes that should be * copied to buf; readers are not allowed * to provide less data unless there is an error; @@ -348,6 +407,8 @@ GNUNET_FS_data_reader_copy_ (void *cls, uint64_t offset, size_t max, void *buf, { char *data = cls; + if (UINT64_MAX == offset) + return 0; if (max == 0) { GNUNET_free_non_null (data); @@ -1482,6 +1543,7 @@ void GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc) { struct GNUNET_BIO_WriteHandle *wh; + char *uris; if (NULL == uc->serialization) uc->serialization = @@ -1496,10 +1558,18 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc) GNUNET_break (0); goto cleanup; } + if (NULL != uc->ksk_uri) + uris = GNUNET_FS_uri_to_string (uc->ksk_uri); + else + uris = NULL; if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uc->filename)) || (GNUNET_OK != GNUNET_BIO_write_int64 (wh, uc->file_size)) || (GNUNET_OK != write_start_time (wh, uc->start_time)) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) uc->state)) || + (GNUNET_OK != + GNUNET_BIO_write (wh, &uc->chk, sizeof (struct ContentHashKey))) || + (GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) || + (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) uc->ksk_offset)) || ((uc->state == UNINDEX_STATE_FS_NOTIFY) && (GNUNET_OK != GNUNET_BIO_write (wh, &uc->file_id, sizeof (GNUNET_HashCode)))) || @@ -1637,9 +1707,8 @@ get_download_sync_filename (struct GNUNET_FS_DownloadContext *dc, if (dc->parent == NULL) return get_serialization_file_name (dc->h, - (dc->search != - NULL) ? - GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD : + (dc->search != NULL) ? + GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD, uni); if (dc->parent->serialization == NULL) @@ -1669,6 +1738,8 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc) char *fn; char *dir; + if (0 != (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE)) + return; /* we don't sync probes */ if (NULL == dc->serialization) { dir = get_download_sync_filename (dc, "", ""); @@ -1920,6 +1991,7 @@ deserialize_unindex_file (void *cls, const char *filename) struct GNUNET_FS_UnindexContext *uc; struct GNUNET_FS_ProgressInfo pi; char *emsg; + char *uris; uint32_t state; uc = GNUNET_malloc (sizeof (struct GNUNET_FS_UnindexContext)); @@ -1931,15 +2003,37 @@ deserialize_unindex_file (void *cls, const char *filename) GNUNET_break (0); goto cleanup; } + uris = NULL; if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "unindex-fn", &uc->filename, 10 * 1024)) || (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &uc->file_size)) || (GNUNET_OK != read_start_time (rh, &uc->start_time)) || - (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &state))) + (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &state)) || + (GNUNET_OK != GNUNET_BIO_read (rh, "uri", &uc->chk, sizeof (struct ContentHashKey))) || + (GNUNET_OK != GNUNET_BIO_read_string (rh, "unindex-kskuri", &uris, 10 * 1024)) || + (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &uc->ksk_offset)) ) { + GNUNET_free_non_null (uris); GNUNET_break (0); goto cleanup; } + if (NULL != uris) + { + uc->ksk_uri = GNUNET_FS_uri_parse (uris, &emsg); + GNUNET_free (uris); + if (NULL == uc->ksk_uri) + { + GNUNET_break (0); + goto cleanup; + } + } + if ( (uc->ksk_offset > 0) && + ( (NULL == uc->ksk_uri) || + (uc->ksk_offset > uc->ksk_uri->data.ksk.keywordCount) ) ) + { + GNUNET_break (0); + goto cleanup; + } uc->state = (enum UnindexState) state; switch (state) { @@ -1955,6 +2049,8 @@ deserialize_unindex_file (void *cls, const char *filename) } break; case UNINDEX_STATE_DS_REMOVE: + case UNINDEX_STATE_EXTRACT_KEYWORDS: + case UNINDEX_STATE_DS_REMOVE_KBLOCKS: break; case UNINDEX_STATE_COMPLETE: break; @@ -1991,6 +2087,12 @@ deserialize_unindex_file (void *cls, const char *filename) case UNINDEX_STATE_DS_REMOVE: GNUNET_FS_unindex_do_remove_ (uc); break; + case UNINDEX_STATE_EXTRACT_KEYWORDS: + GNUNET_FS_unindex_do_extract_keywords_ (uc); + break; + case UNINDEX_STATE_DS_REMOVE_KBLOCKS: + GNUNET_FS_unindex_do_remove_kblocks_ (uc); + break; case UNINDEX_STATE_COMPLETE: case UNINDEX_STATE_ERROR: /* no need to resume any operation, we were done */ @@ -2762,8 +2864,8 @@ GNUNET_FS_start (const struct GNUNET_CONFIGURATION_Handle *cfg, ret->upcb = upcb; ret->upcb_cls = upcb_cls; ret->flags = flags; - ret->max_parallel_downloads = 1; - ret->max_parallel_requests = 1; + ret->max_parallel_downloads = DEFAULT_MAX_PARALLEL_DOWNLOADS; + ret->max_parallel_requests = DEFAULT_MAX_PARALLEL_REQUESTS; ret->avg_block_latency = GNUNET_TIME_UNIT_MINUTES; /* conservative starting point */ va_start (ap, flags); while (GNUNET_FS_OPTIONS_END != (opt = va_arg (ap, enum GNUNET_FS_OPTIONS))) diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h index de66ac6..e75b75f 100644 --- a/src/fs/fs_api.h +++ b/src/fs/fs_api.h @@ -417,6 +417,24 @@ typedef void (*GNUNET_FS_QueueStart) (void *cls, typedef void (*GNUNET_FS_QueueStop) (void *cls); + +/** + * Priorities for the queue. + */ +enum GNUNET_FS_QueuePriority + { + /** + * This is a probe (low priority). + */ + GNUNET_FS_QUEUE_PRIORITY_PROBE, + + /** + * Default priority. + */ + GNUNET_FS_QUEUE_PRIORITY_NORMAL + }; + + /** * Entry in the job queue. */ @@ -478,6 +496,11 @@ struct GNUNET_FS_QueueEntry */ unsigned int blocks; + /** + * How important is this download? + */ + enum GNUNET_FS_QueuePriority priority; + /** * How often have we (re)started this download? */ @@ -599,11 +622,13 @@ struct GNUNET_FS_SearchResult * @param stop function to call to pause the job, or on dequeue (if the job was running) * @param cls closure for start and stop * @param blocks number of blocks this download has + * @param priority how important is this download * @return queue handle */ struct GNUNET_FS_QueueEntry * GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, GNUNET_FS_QueueStart start, - GNUNET_FS_QueueStop stop, void *cls, unsigned int blocks); + GNUNET_FS_QueueStop stop, void *cls, unsigned int blocks, + enum GNUNET_FS_QueuePriority priority); /** @@ -708,6 +733,24 @@ void GNUNET_FS_unindex_process_hash_ (void *cls, const GNUNET_HashCode * file_id); +/** + * Extract the keywords for KBlock removal + * + * @param uc context for the unindex operation. + */ +void +GNUNET_FS_unindex_do_extract_keywords_ (struct GNUNET_FS_UnindexContext *uc); + + +/** + * If necessary, connect to the datastore and remove the KBlocks. + * + * @param uc context for the unindex operation. + */ +void +GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc); + + /** * Fill in all of the generic fields for a publish event and call the * callback. @@ -1219,32 +1262,42 @@ struct GNUNET_FS_PublishContext */ enum UnindexState { - /** - * We're currently hashing the file. - */ + /** + * We're currently hashing the file. + */ UNINDEX_STATE_HASHING = 0, - /** - * We're telling the datastore to delete - * the respective entries. - */ + /** + * We're telling the datastore to delete + * the respective DBlocks and IBlocks. + */ UNINDEX_STATE_DS_REMOVE = 1, + + /** + * Find out which keywords apply. + */ + UNINDEX_STATE_EXTRACT_KEYWORDS = 2, - /** - * We're notifying the FS service about - * the unindexing. - */ - UNINDEX_STATE_FS_NOTIFY = 2, - - /** - * We're done. - */ - UNINDEX_STATE_COMPLETE = 3, + /** + * We're telling the datastore to remove KBlocks. + */ + UNINDEX_STATE_DS_REMOVE_KBLOCKS = 3, - /** - * We've encountered a fatal error. - */ - UNINDEX_STATE_ERROR = 4 + /** + * We're notifying the FS service about + * the unindexing. + */ + UNINDEX_STATE_FS_NOTIFY = 4, + + /** + * We're done. + */ + UNINDEX_STATE_COMPLETE = 5, + + /** + * We've encountered a fatal error. + */ + UNINDEX_STATE_ERROR = 6 }; @@ -1254,6 +1307,12 @@ enum UnindexState struct GNUNET_FS_UnindexContext { + /** + * The content hash key of the last block we processed, will in the + * end be set to the CHK from the URI. Used to remove the KBlocks. + */ + struct ContentHashKey chk; + /** * Global FS context. */ @@ -1264,6 +1323,21 @@ struct GNUNET_FS_UnindexContext */ struct TopLevelActivity *top; + /** + * Directory scanner to find keywords (KBlock removal). + */ + struct GNUNET_FS_DirScanner *dscan; + + /** + * Keywords found (telling us which KBlocks to remove). + */ + struct GNUNET_FS_Uri *ksk_uri; + + /** + * Current offset in KSK removal. + */ + uint32_t ksk_offset; + /** * Name of the file that we are unindexing. */ @@ -1301,6 +1375,27 @@ struct GNUNET_FS_UnindexContext */ struct GNUNET_DISK_FileHandle *fh; + /** + * Handle to datastore 'get_key' operation issued for + * obtaining KBlocks. + */ + struct GNUNET_DATASTORE_QueueEntry *dqe; + + /** + * Current key for decrypting KBLocks from 'get_key' operation. + */ + GNUNET_HashCode key; + + /** + * Current query of 'get_key' operation. + */ + GNUNET_HashCode query; + + /** + * First content UID, 0 for none. + */ + uint64_t first_uid; + /** * Error message, NULL on success. */ @@ -1316,6 +1411,11 @@ struct GNUNET_FS_UnindexContext */ uint64_t file_size; + /** + * Random offset given to 'GNUNET_DATASTORE_get_key'. + */ + uint64_t roff; + /** * When did we start? */ @@ -1590,6 +1690,11 @@ struct DownloadRequest */ unsigned int depth; + /** + * Offset of the CHK for this block in the parent block + */ + unsigned int chk_idx; + /** * State in the FSM. */ @@ -1821,6 +1926,11 @@ struct GNUNET_FS_DownloadContext */ int in_receive; + /** + * Are we ready to issue requests (reconstructions are finished)? + */ + int issue_requests; + }; diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c index 4e5354e..6dac690 100644 --- a/src/fs/fs_dirmetascan.c +++ b/src/fs/fs_dirmetascan.c @@ -248,7 +248,7 @@ finish_scan (void *cls, * @param client always NULL * @param msg message from the helper process */ -static void +static int process_helper_msgs (void *cls, void *client, const struct GNUNET_MessageHeader *msg) @@ -257,6 +257,11 @@ process_helper_msgs (void *cls, const char *filename; size_t left; +#if 0 + fprintf (stderr, "DMS parses %u-byte message of type %u\n", + (unsigned int) ntohs (msg->size), + (unsigned int) ntohs (msg->type)); +#endif left = ntohs (msg->size) - sizeof (struct GNUNET_MessageHeader); filename = (const char*) &msg[1]; switch (ntohs (msg->type)) @@ -276,7 +281,7 @@ process_helper_msgs (void *cls, else (void) expand_tree (ds->pos, filename, GNUNET_NO); - return; + return GNUNET_OK; case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY: if (filename[left-1] != '\0') { @@ -291,7 +296,7 @@ process_helper_msgs (void *cls, break; } ds->pos = ds->pos->parent; - return; + return GNUNET_OK; } ds->progress_callback (ds->progress_callback_cls, filename, GNUNET_YES, @@ -300,16 +305,16 @@ process_helper_msgs (void *cls, filename, GNUNET_YES); if (NULL == ds->toplevel) ds->toplevel = ds->pos; - return; + return GNUNET_OK; case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR: break; case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE: - if (filename[left-1] != '\0') + if ('\0' != filename[left-1]) break; ds->progress_callback (ds->progress_callback_cls, filename, GNUNET_SYSERR, GNUNET_FS_DIRSCANNER_FILE_IGNORED); - return; + return GNUNET_OK; case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE: if (0 != left) { @@ -325,9 +330,9 @@ process_helper_msgs (void *cls, NULL, GNUNET_SYSERR, GNUNET_FS_DIRSCANNER_ALL_COUNTED); ds->pos = ds->toplevel; - if (ds->pos->is_directory == GNUNET_YES) + if (GNUNET_YES == ds->pos->is_directory) ds->pos = advance (ds->pos); - return; + return GNUNET_OK; case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA: { size_t nlen; @@ -377,7 +382,7 @@ process_helper_msgs (void *cls, } ds->pos->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (ds->pos->meta); ds->pos = advance (ds->pos); - return; + return GNUNET_OK; } case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED: if (NULL != ds->pos) @@ -397,7 +402,7 @@ process_helper_msgs (void *cls, } ds->stop_task = GNUNET_SCHEDULER_add_now (&finish_scan, ds); - return; + return GNUNET_OK; default: GNUNET_break (0); break; @@ -405,6 +410,7 @@ process_helper_msgs (void *cls, ds->progress_callback (ds->progress_callback_cls, NULL, GNUNET_SYSERR, GNUNET_FS_DIRSCANNER_INTERNAL_ERROR); + return GNUNET_OK; } diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index b23d14b..7c4dccb 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001-2011 Christian Grothoff (and other contributing authors) + (C) 2001-2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -21,9 +21,6 @@ * @file fs/fs_download.c * @brief download methods * @author Christian Grothoff - * - * TODO: - * - different priority for scheduling probe downloads? */ #include "platform.h" #include "gnunet_constants.h" @@ -41,7 +38,7 @@ is_recursive_download (struct GNUNET_FS_DownloadContext *dc) { return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) && ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (dc->meta)) || - ((dc->meta == NULL) && + ((NULL == dc->meta) && ((NULL == dc->filename) || ((strlen (dc->filename) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && (NULL != @@ -75,7 +72,7 @@ compute_disk_offset (uint64_t fsize, uint64_t off, unsigned int depth) uint64_t loff; /* where do IBlocks for depth "i" start? */ unsigned int ioff; /* which IBlock corresponds to "off" at depth "i"? */ - if (depth == 0) + if (0 == depth) return off; /* first IBlocks start at the end of file, rounded up * to full DBLOCK_SIZE */ @@ -111,9 +108,9 @@ GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi, pi->value.download.dc = dc; pi->value.download.cctx = dc->client_info; pi->value.download.pctx = - (dc->parent == NULL) ? NULL : dc->parent->client_info; + (NULL == dc->parent) ? NULL : dc->parent->client_info; pi->value.download.sctx = - (dc->search == NULL) ? NULL : dc->search->client_info; + (NULL == dc->search) ? NULL : dc->search->client_info; pi->value.download.uri = dc->uri; pi->value.download.filename = dc->filename; pi->value.download.size = dc->length; @@ -124,7 +121,7 @@ GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi, pi->value.download.anonymity = dc->anonymity; pi->value.download.eta = GNUNET_TIME_calculate_eta (dc->start_time, dc->completed, dc->length); - pi->value.download.is_active = (dc->client == NULL) ? GNUNET_NO : GNUNET_YES; + pi->value.download.is_active = (NULL == dc->client) ? GNUNET_NO : GNUNET_YES; if (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE)) dc->client_info = dc->h->upcb (dc->h->upcb_cls, pi); else @@ -183,6 +180,9 @@ struct ProcessResultClosure */ int do_store; + /** + * When did we last transmit the request? + */ struct GNUNET_TIME_Absolute last_transmission; }; @@ -240,7 +240,8 @@ encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc, return GNUNET_SYSERR; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Matching block for `%s' at offset %llu already present, no need for download!\n", + "Matching %u byte block for `%s' at offset %llu already present, no need for download!\n", + (unsigned int) len, dc->filename, (unsigned long long) dr->offset); /* already got it! */ prc.dc = dc; @@ -310,21 +311,21 @@ full_recursive_download (struct GNUNET_FS_DownloadContext *dc) ("Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n")); return; } - if (dc->filename != NULL) + if (NULL != dc->filename) { h = GNUNET_DISK_file_open (dc->filename, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); } else { - GNUNET_assert (dc->temp_filename != NULL); + GNUNET_assert (NULL != dc->temp_filename); h = GNUNET_DISK_file_open (dc->temp_filename, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); } - if (h == NULL) + if (NULL == h) return; /* oops */ data = GNUNET_DISK_file_map (h, &m, GNUNET_DISK_MAP_TYPE_READ, size); - if (data == NULL) + if (NULL == data) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Directory too large for system address space\n")); @@ -336,7 +337,7 @@ full_recursive_download (struct GNUNET_FS_DownloadContext *dc) GNUNET_DISK_file_unmap (m); } GNUNET_DISK_file_close (h); - if (dc->filename == NULL) + if (NULL == dc->filename) { if (0 != UNLINK (dc->temp_filename)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", @@ -364,25 +365,33 @@ check_completed (struct GNUNET_FS_DownloadContext *dc) struct GNUNET_FS_DownloadContext *pos; /* first, check if we need to download children */ - if ((dc->child_head == NULL) && (is_recursive_download (dc))) + if ((NULL == dc->child_head) && (is_recursive_download (dc))) full_recursive_download (dc); /* then, check if children are done already */ - pos = dc->child_head; - while (pos != NULL) + for (pos = dc->child_head; NULL != pos; pos = pos->next) { if ((pos->emsg == NULL) && (pos->completed < pos->length)) return; /* not done yet */ if ((pos->child_head != NULL) && (pos->has_finished != GNUNET_YES)) return; /* not transitively done yet */ - pos = pos->next; } /* All of our children are done, so mark this download done */ dc->has_finished = GNUNET_YES; - if (dc->job_queue != NULL) + if (NULL != dc->job_queue) { GNUNET_FS_dequeue_ (dc->job_queue); dc->job_queue = NULL; } + if (GNUNET_SCHEDULER_NO_TASK != dc->task) + { + GNUNET_SCHEDULER_cancel (dc->task); + dc->task = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != dc->rfh) + { + GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh)); + dc->rfh = NULL; + } GNUNET_FS_download_sync_ (dc); /* signal completion */ @@ -390,7 +399,7 @@ check_completed (struct GNUNET_FS_DownloadContext *dc) GNUNET_FS_download_make_status_ (&pi, dc); /* let parent know */ - if (dc->parent != NULL) + if (NULL != dc->parent) check_completed (dc->parent); } @@ -473,7 +482,7 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, break; } /* write block to disk */ - fn = dc->filename != NULL ? dc->filename : dc->temp_filename; + fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename; fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE | @@ -482,7 +491,7 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_GROUP_READ | GNUNET_DISK_PERM_OTHER_READ); - if (fh == NULL) + if (NULL == fh) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn); GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"), @@ -517,6 +526,7 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, pi.value.download.specifics.progress.data_len = dlen; pi.value.download.specifics.progress.depth = 0; pi.value.download.specifics.progress.trust_offered = 0; + pi.value.download.specifics.progress.block_download_duration = GNUNET_TIME_UNIT_ZERO; GNUNET_FS_download_make_status_ (&pi, dc); if ((NULL != dc->filename) && (0 != @@ -559,7 +569,7 @@ match_full_data (void *cls, const char *plugin_name, { struct GNUNET_FS_DownloadContext *dc = cls; - if (type != EXTRACTOR_METATYPE_GNUNET_FULL_DATA) + if (EXTRACTOR_METATYPE_GNUNET_FULL_DATA != type) return 0; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u bytes of FD!\n", (unsigned int) data_len); @@ -588,7 +598,7 @@ propagate_up (struct DownloadRequest *dr) { dr->state = BRS_DOWNLOAD_UP; dr = dr->parent; - if (dr == NULL) + if (NULL == dr) break; for (i = 0; i < dr->num_children; i++) if (dr->children[i]->state != BRS_DOWNLOAD_UP) @@ -618,14 +628,13 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, uint64_t total; size_t len; unsigned int i; - unsigned int chk_off; struct DownloadRequest *drc; uint64_t child_block_size; const struct ContentHashKey *chks; int up_done; - GNUNET_assert (dc->rfh != NULL); - GNUNET_assert (dr->state == BRS_CHK_SET); + GNUNET_assert (NULL != dc->rfh); + GNUNET_assert (BRS_CHK_SET == dr->state); total = GNUNET_FS_uri_chk_get_file_size (dc->uri); GNUNET_assert (dr->depth < dc->treedepth); len = GNUNET_FS_tree_calculate_block_size (total, dr->offset, dr->depth); @@ -652,7 +661,7 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, /* hash matches but encrypted block does not, really bad */ dr->state = BRS_ERROR; /* propagate up */ - while (dr->parent != NULL) + while (NULL != dr->parent) { dr = dr->parent; dr->state = BRS_ERROR; @@ -670,18 +679,17 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, drc = dr->children[i]; GNUNET_assert (drc->offset >= dr->offset); child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth); - GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size); - chk_off = (drc->offset - dr->offset) / child_block_size; - if (drc->state == BRS_INIT) + GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size); + if (BRS_INIT == drc->state) { drc->state = BRS_CHK_SET; - drc->chk = chks[chk_off]; + drc->chk = chks[drc->chk_idx]; try_top_down_reconstruction (dc, drc); } - if (drc->state != BRS_DOWNLOAD_UP) + if (BRS_DOWNLOAD_UP != drc->state) up_done = GNUNET_NO; /* children not all done */ } - if (up_done == GNUNET_YES) + if (GNUNET_YES == up_done) propagate_up (dr); /* children all done (or no children...) */ } @@ -736,7 +744,7 @@ schedule_block_download (struct GNUNET_FS_DownloadContext *dc, return; /* already active */ GNUNET_CONTAINER_multihashmap_put (dc->active, &dr->chk.query, dr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - if (dc->client == NULL) + if (NULL == dc->client) return; /* download not active */ GNUNET_CONTAINER_DLL_insert (dc->pending_head, dc->pending_tail, dr); dr->is_pending = GNUNET_YES; @@ -783,26 +791,26 @@ trigger_recursive_download (void *cls, const char *filename, if (NULL == uri) return; /* entry for the directory itself */ cpos = dc->child_head; - while (cpos != NULL) + while (NULL != cpos) { if ((GNUNET_FS_uri_test_equal (uri, cpos->uri)) || - ((filename != NULL) && (0 == strcmp (cpos->filename, filename)))) + ((NULL != filename) && (0 == strcmp (cpos->filename, filename)))) break; cpos = cpos->next; } - if (cpos != NULL) + if (NULL != cpos) return; /* already exists */ fn = NULL; if (NULL == filename) { fn = GNUNET_FS_meta_data_suggest_filename (meta); - if (fn == NULL) + if (NULL == fn) { us = GNUNET_FS_uri_to_string (uri); fn = GNUNET_strdup (&us[strlen (GNUNET_FS_URI_CHK_PREFIX)]); GNUNET_free (us); } - else if (fn[0] == '.') + else if ('.' == fn[0]) { ext = fn; us = GNUNET_FS_uri_to_string (uri); @@ -827,7 +835,7 @@ trigger_recursive_download (void *cls, const char *filename, } filename = fn; } - if (dc->filename == NULL) + if (NULL == dc->filename) { full_name = NULL; } @@ -839,7 +847,7 @@ trigger_recursive_download (void *cls, const char *filename, strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT), GNUNET_FS_DIRECTORY_EXT))); sfn = GNUNET_strdup (filename); - while ((strlen (sfn) > 0) && (filename[strlen (sfn) - 1] == '/')) + while ((strlen (sfn) > 0) && ('/' == filename[strlen (sfn) - 1])) sfn[strlen (sfn) - 1] = '\0'; if ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && (NULL != @@ -862,7 +870,7 @@ trigger_recursive_download (void *cls, const char *filename, GNUNET_free (sfn); GNUNET_free (dn); } - if ((full_name != NULL) && + if ((NULL != full_name) && (GNUNET_OK != GNUNET_DISK_directory_create_for_file (full_name))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -899,7 +907,7 @@ GNUNET_FS_free_download_request_ (struct DownloadRequest *dr) { unsigned int i; - if (dr == NULL) + if (NULL == dr) return; for (i = 0; i < dr->num_children; i++) GNUNET_FS_free_download_request_ (dr->children[i]); @@ -937,7 +945,8 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, struct ContentHashKey *chkarr; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received block `%s' matching pending request at depth %u and offset %llu/%llu\n", + "Received %u byte block `%s' matching pending request at depth %u and offset %llu/%llu\n", + (unsigned int) prc->size, GNUNET_h2s (key), dr->depth, (unsigned long long) dr->offset, (unsigned long long) GNUNET_ntohll (dc->uri->data. chk.file_length)); @@ -948,13 +957,13 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, { GNUNET_asprintf (&dc->emsg, _ - ("Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)\n"), + ("Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)"), bs, dr->depth, (unsigned long long) dr->offset, (unsigned long long) GNUNET_ntohll (dc->uri->data. chk.file_length), prc->size); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s", dc->emsg); - while (dr->parent != NULL) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", dc->emsg); + while (NULL != dr->parent) { dr->state = BRS_ERROR; dr = dr->parent; @@ -982,12 +991,12 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, dr->offset, dr->depth); /* save to disk */ if ((GNUNET_YES == prc->do_store) && - ((dc->filename != NULL) || (is_recursive_download (dc))) && + ((NULL != dc->filename) || (is_recursive_download (dc))) && ((dr->depth == dc->treedepth) || (0 == (dc->options & GNUNET_FS_DOWNLOAD_NO_TEMPORARIES)))) { - fh = GNUNET_DISK_file_open (dc->filename != - NULL ? dc->filename : dc->temp_filename, + fh = GNUNET_DISK_file_open (NULL != dc->filename + ? dc->filename : dc->temp_filename, GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | @@ -997,7 +1006,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, if (NULL == fh) { GNUNET_asprintf (&dc->emsg, - _("Download failed: could not open file `%s': %s\n"), + _("Download failed: could not open file `%s': %s"), dc->filename, STRERROR (errno)); goto signal_error; } @@ -1007,7 +1016,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, if ((off != GNUNET_DISK_file_seek (fh, off, GNUNET_DISK_SEEK_SET))) { GNUNET_asprintf (&dc->emsg, - _("Failed to seek to offset %llu in file `%s': %s\n"), + _("Failed to seek to offset %llu in file `%s': %s"), (unsigned long long) off, dc->filename, STRERROR (errno)); goto signal_error; @@ -1016,7 +1025,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, { GNUNET_asprintf (&dc->emsg, _ - ("Failed to write block of %u bytes at offset %llu in file `%s': %s\n"), + ("Failed to write block of %u bytes at offset %llu in file `%s': %s"), (unsigned int) prc->size, (unsigned long long) off, dc->filename, STRERROR (errno)); goto signal_error; @@ -1025,7 +1034,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, fh = NULL; } - if (dr->depth == 0) + if (0 == dr->depth) { /* DBLOCK, update progress and try recursion if applicable */ app = prc->size; @@ -1052,7 +1061,6 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, if (is_recursive_download (dc)) GNUNET_FS_directory_list_contents (prc->size, pt, off, &trigger_recursive_download, dc); - } GNUNET_assert (dc->completed <= dc->length); dr->state = BRS_DOWNLOAD_DOWN; @@ -1063,13 +1071,13 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, pi.value.download.specifics.progress.depth = dr->depth; pi.value.download.specifics.progress.trust_offered = 0; if (prc->last_transmission.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value) - pi.value.download.specifics.progress.block_download_duration = - GNUNET_TIME_absolute_get_duration (prc->last_transmission); + pi.value.download.specifics.progress.block_download_duration + = GNUNET_TIME_absolute_get_duration (prc->last_transmission); else - pi.value.download.specifics.progress.block_download_duration.rel_value = - GNUNET_TIME_UNIT_FOREVER_REL.rel_value; + pi.value.download.specifics.progress.block_download_duration + = GNUNET_TIME_UNIT_ZERO; /* found locally */ GNUNET_FS_download_make_status_ (&pi, dc); - if (dr->depth == 0) + if (0 == dr->depth) propagate_up (dr); if (dc->completed == dc->length) @@ -1080,7 +1088,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, (unsigned long long) GNUNET_ntohll (dc->uri->data. chk.file_length)); /* truncate file to size (since we store IBlocks at the end) */ - if (dc->filename != NULL) + if (NULL != dc->filename) { if (0 != truncate (dc->filename, @@ -1088,10 +1096,10 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "truncate", dc->filename); } - GNUNET_assert (dr->depth == 0); + GNUNET_assert (0 == dr->depth); check_completed (dc); } - if (dr->depth == 0) + if (0 == dr->depth) { /* bottom of the tree, no child downloads possible, just sync */ GNUNET_FS_download_sync_ (dc); @@ -1103,15 +1111,24 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, dr->depth, (unsigned long long) dr->offset); GNUNET_assert (0 == (prc->size % sizeof (struct ContentHashKey))); chkarr = (struct ContentHashKey *) pt; - for (i = (prc->size / sizeof (struct ContentHashKey)) - 1; i >= 0; i--) + for (i = dr->num_children - 1; i >= 0; i--) { drc = dr->children[i]; switch (drc->state) { case BRS_INIT: - drc->chk = chkarr[i]; + if ((drc->chk_idx + 1) * sizeof (struct ContentHashKey) > prc->size) + { + /* 'chkarr' does not have enough space for this chk_idx; + internal error! */ + GNUNET_break (0); + dc->emsg = GNUNET_strdup (_("internal error decoding tree")); + goto signal_error; + } + drc->chk = chkarr[drc->chk_idx]; drc->state = BRS_CHK_SET; - schedule_block_download (dc, drc); + if (GNUNET_YES == dc->issue_requests) + schedule_block_download (dc, drc); break; case BRS_RECONSTRUCT_DOWN: GNUNET_assert (0); @@ -1143,7 +1160,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, return GNUNET_YES; signal_error: - if (fh != NULL) + if (NULL != fh) GNUNET_DISK_file_close (fh); pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; pi.value.download.specifics.error.message = dc->emsg; @@ -1154,7 +1171,7 @@ signal_error: GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); dc->th = NULL; } - GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (dc->client); dc->in_receive = GNUNET_NO; dc->client = NULL; GNUNET_FS_free_download_request_ (dc->top_request); @@ -1218,7 +1235,7 @@ receive_results (void *cls, const struct GNUNET_MessageHeader *msg) if ((NULL == msg) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_PUT) || (sizeof (struct ClientPutMessage) > ntohs (msg->size))) { - GNUNET_break (msg == NULL); + GNUNET_break (NULL == msg); try_reconnect (dc); return; } @@ -1227,7 +1244,7 @@ receive_results (void *cls, const struct GNUNET_MessageHeader *msg) process_result (dc, ntohl (cm->type), GNUNET_TIME_absolute_ntoh (cm->last_transmission), &cm[1], msize - sizeof (struct ClientPutMessage)); - if (dc->client == NULL) + if (NULL == dc->client) return; /* fatal error */ /* continue receiving */ GNUNET_CLIENT_receive (dc->client, &receive_results, dc, @@ -1235,7 +1252,6 @@ receive_results (void *cls, const struct GNUNET_MessageHeader *msg) } - /** * We're ready to transmit a search request to the * file-sharing service. Do it. If there is @@ -1279,7 +1295,7 @@ transmit_download_request (void *cls, size_t size, void *buf) sm->options = htonl (GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY); else sm->options = htonl (GNUNET_FS_SEARCH_OPTION_NONE); - if (dr->depth == 0) + if (0 == dr->depth) sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK); else sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK); @@ -1291,7 +1307,7 @@ transmit_download_request (void *cls, size_t size, void *buf) msize += sizeof (struct SearchMessage); sm++; } - if (dc->pending_head != NULL) + if (NULL != dc->pending_head) { dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, @@ -1299,7 +1315,7 @@ transmit_download_request (void *cls, size_t size, void *buf) GNUNET_CONSTANTS_SERVICE_TIMEOUT, GNUNET_NO, &transmit_download_request, dc); - GNUNET_assert (dc->th != NULL); + GNUNET_assert (NULL != dc->th); } if (GNUNET_NO == dc->in_receive) { @@ -1333,7 +1349,7 @@ do_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) return; } dc->client = client; - if (dc->pending_head != NULL) + if (NULL != dc->pending_head) { dc->th = GNUNET_CLIENT_notify_transmit_ready (client, @@ -1341,7 +1357,7 @@ do_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONSTANTS_SERVICE_TIMEOUT, GNUNET_NO, &transmit_download_request, dc); - GNUNET_assert (dc->th != NULL); + GNUNET_assert (NULL != dc->th); } } @@ -1392,7 +1408,7 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc) dc->pending_head = NULL; dc->pending_tail = NULL; GNUNET_CONTAINER_multihashmap_iterate (dc->active, &retry_entry, dc); - GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (dc->client); dc->in_receive = GNUNET_NO; dc->client = NULL; } @@ -1417,8 +1433,8 @@ activate_fs_download (void *cls, struct GNUNET_CLIENT_Connection *client) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download activated\n"); GNUNET_assert (NULL != client); - GNUNET_assert (dc->client == NULL); - GNUNET_assert (dc->th == NULL); + GNUNET_assert (NULL == dc->client); + GNUNET_assert (NULL == dc->th); dc->client = client; pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE; GNUNET_FS_download_make_status_ (&pi, dc); @@ -1427,7 +1443,7 @@ activate_fs_download (void *cls, struct GNUNET_CLIENT_Connection *client) GNUNET_CONTAINER_multihashmap_iterate (dc->active, &retry_entry, dc); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking for transmission to FS service\n"); - if (dc->pending_head != NULL) + if (NULL != dc->pending_head) { dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, @@ -1435,7 +1451,7 @@ activate_fs_download (void *cls, struct GNUNET_CLIENT_Connection *client) GNUNET_CONSTANTS_SERVICE_TIMEOUT, GNUNET_NO, &transmit_download_request, dc); - GNUNET_assert (dc->th != NULL); + GNUNET_assert (NULL != dc->th); } } @@ -1459,7 +1475,7 @@ deactivate_fs_download (void *cls) } if (NULL != dc->client) { - GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (dc->client); dc->in_receive = GNUNET_NO; dc->client = NULL; } @@ -1474,6 +1490,7 @@ deactivate_fs_download (void *cls) * (recursively) Create a download request structure. * * @param parent parent of the current entry + * @param chk_idx index of the chk for this block in the parent block * @param depth depth of the current entry, 0 are the DBLOCKs, * top level block is 'dc->treedepth - 1' * @param dr_offset offset in the original file this block maps to @@ -1489,7 +1506,9 @@ deactivate_fs_download (void *cls) * the specified depth */ static struct DownloadRequest * -create_download_request (struct DownloadRequest *parent, unsigned int depth, +create_download_request (struct DownloadRequest *parent, + unsigned int chk_idx, + unsigned int depth, uint64_t dr_offset, uint64_t file_start_offset, uint64_t desired_length) { @@ -1502,40 +1521,45 @@ create_download_request (struct DownloadRequest *parent, unsigned int depth, dr->parent = parent; dr->depth = depth; dr->offset = dr_offset; - if (depth > 0) - { - child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1); - - /* calculate how many blocks at this level are not interesting - * from the start (rounded down), either because of the requested - * file offset or because this IBlock is further along */ - if (dr_offset < file_start_offset) - head_skip = file_start_offset / child_block_size; - else - head_skip = dr_offset / child_block_size; - - /* calculate index of last block at this level that is interesting (rounded up) */ - dr->num_children = file_start_offset + desired_length / child_block_size; - if (dr->num_children * child_block_size < - file_start_offset + desired_length) - dr->num_children++; /* round up */ - - /* now we can get the total number of children for this block */ - dr->num_children -= head_skip; - if (dr->num_children > CHK_PER_INODE) - dr->num_children = CHK_PER_INODE; /* cap at max */ - - /* why else would we have gotten here to begin with? (that'd be a bad logic error) */ - GNUNET_assert (dr->num_children > 0); - - dr->children = - GNUNET_malloc (dr->num_children * sizeof (struct DownloadRequest *)); - for (i = 0; i < dr->num_children; i++) - dr->children[i] = - create_download_request (dr, depth - 1, - dr_offset + i * child_block_size, - file_start_offset, desired_length); - } + dr->chk_idx = chk_idx; + if (0 == depth) + return dr; + child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1); + + /* calculate how many blocks at this level are not interesting + * from the start (rounded down), either because of the requested + * file offset or because this IBlock is further along */ + if (dr_offset < file_start_offset) + head_skip = file_start_offset / child_block_size; + else + head_skip = 0; + + /* calculate index of last block at this level that is interesting (rounded up) */ + dr->num_children = (file_start_offset + desired_length - dr_offset) / child_block_size; + if (dr->num_children * child_block_size < + file_start_offset + desired_length - dr_offset) + dr->num_children++; /* round up */ + dr->num_children -= head_skip; + if (dr->num_children > CHK_PER_INODE) + dr->num_children = CHK_PER_INODE; /* cap at max */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Block at offset %llu and depth %u has %u children\n", + (unsigned long long) dr_offset, + depth, + dr->num_children); + + /* now we can get the total number of *interesting* children for this block */ + + /* why else would we have gotten here to begin with? (that'd be a bad logic error) */ + GNUNET_assert (dr->num_children > 0); + + dr->children = + GNUNET_malloc (dr->num_children * sizeof (struct DownloadRequest *)); + for (i = 0; i < dr->num_children; i++) + dr->children[i] = + create_download_request (dr, i + head_skip, depth - 1, + dr_offset + (i + head_skip) * child_block_size, + file_start_offset, desired_length); return dr; } @@ -1552,23 +1576,21 @@ reconstruct_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_DownloadContext *dc = cls; - /* clean up state from tree encoder */ - if (dc->te != NULL) - { - GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); - dc->te = NULL; - } + /* clean up state from tree encoder */ if (dc->task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (dc->task); dc->task = GNUNET_SCHEDULER_NO_TASK; } - if (dc->rfh != NULL) + if (NULL != dc->rfh) { GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh)); dc->rfh = NULL; } /* start "normal" download */ + dc->issue_requests = GNUNET_YES; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting normal download\n"); schedule_block_download (dc, dc->top_request); } @@ -1589,7 +1611,6 @@ get_next_block (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } - /** * Function called asking for the current (encoded) * block to be processed. After processing the @@ -1622,11 +1643,34 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, dr = dc->top_request; while (dr->depth > depth) { - blen = GNUNET_FS_tree_compute_tree_size (dr->depth); + GNUNET_assert (dr->num_children > 0); + blen = GNUNET_FS_tree_compute_tree_size (dr->depth - 1); chld = (offset - dr->offset) / blen; - GNUNET_assert (chld < dr->num_children); - dr = dr->children[chld]; + if (chld < dr->children[0]->chk_idx) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Block %u < %u irrelevant for our range\n", + chld, + dr->children[0]->chk_idx); + dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); + return; /* irrelevant block */ + } + if (chld > dr->children[dr->num_children-1]->chk_idx) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Block %u > %u irrelevant for our range\n", + chld, + dr->children[dr->num_children-1]->chk_idx); + dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); + return; /* irrelevant block */ + } + dr = dr->children[chld - dr->children[0]->chk_idx]; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Matched TE block with request at offset %llu and depth %u in state %d\n", + (unsigned long long) dr->offset, + dr->depth, + dr->state); /* FIXME: this code needs more testing and might need to handle more states... */ switch (dr->state) @@ -1642,11 +1686,14 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, case BRS_CHK_SET: if (0 == memcmp (chk, &dr->chk, sizeof (struct ContentHashKey))) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Reconstruction succeeded, can use block at offset %llu, depth %u\n", + (unsigned long long) offset, + depth); /* block matches, hence tree below matches; * this request is done! */ dr->state = BRS_DOWNLOAD_UP; - GNUNET_break (GNUNET_NO == - GNUNET_CONTAINER_multihashmap_remove (dc->active, &dr->chk.query, dr)); + (void) GNUNET_CONTAINER_multihashmap_remove (dc->active, &dr->chk.query, dr); if (GNUNET_YES == dr->is_pending) { GNUNET_break (0); /* how did we get here? */ @@ -1666,6 +1713,7 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, pi.value.download.specifics.progress.data_len = 0; pi.value.download.specifics.progress.depth = 0; pi.value.download.specifics.progress.trust_offered = 0; + pi.value.download.specifics.progress.block_download_duration = GNUNET_TIME_UNIT_ZERO; GNUNET_FS_download_make_status_ (&pi, dc); /* FIXME: duplicated code from 'process_result_with_request - refactor */ if (dc->completed == dc->length) @@ -1676,7 +1724,7 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, (unsigned long long) GNUNET_ntohll (dc->uri->data. chk.file_length)); /* truncate file to size (since we store IBlocks at the end) */ - if (dc->filename != NULL) + if (NULL != dc->filename) { if (0 != truncate (dc->filename, @@ -1686,6 +1734,11 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, } } } + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Reconstruction failed, need to download block at offset %llu, depth %u\n", + (unsigned long long) offset, + depth); break; case BRS_DOWNLOAD_DOWN: break; @@ -1697,12 +1750,9 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, GNUNET_assert (0); break; } + dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); if ((dr == dc->top_request) && (dr->state == BRS_DOWNLOAD_UP)) - { check_completed (dc); - return; - } - dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); } @@ -1725,16 +1775,19 @@ fh_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg) struct GNUNET_DISK_FileHandle *fh = dc->rfh; ssize_t ret; - *emsg = NULL; + if (NULL != emsg) + *emsg = NULL; if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET)) { - *emsg = GNUNET_strdup (strerror (errno)); + if (NULL != emsg) + *emsg = GNUNET_strdup (strerror (errno)); return 0; } ret = GNUNET_DISK_file_read (fh, buf, max); if (ret < 0) { - *emsg = GNUNET_strdup (strerror (errno)); + if (NULL != emsg) + *emsg = GNUNET_strdup (strerror (errno)); return 0; } return ret; @@ -1758,10 +1811,10 @@ GNUNET_FS_download_start_task_ (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start task running...\n"); dc->task = GNUNET_SCHEDULER_NO_TASK; - if (dc->length == 0) + if (0 == dc->length) { /* no bytes required! */ - if (dc->filename != NULL) + if (NULL != dc->filename) { fh = GNUNET_DISK_file_open (dc->filename, GNUNET_DISK_OPEN_READWRITE | @@ -1782,13 +1835,13 @@ GNUNET_FS_download_start_task_ (void *cls, check_completed (dc); return; } - if (dc->emsg != NULL) + if (NULL != dc->emsg) return; - if (dc->top_request == NULL) + if (NULL == dc->top_request) { dc->top_request = - create_download_request (NULL, dc->treedepth - 1, 0, dc->offset, - dc->length); + create_download_request (NULL, 0, dc->treedepth - 1, 0, dc->offset, + dc->length); dc->top_request->state = BRS_CHK_SET; dc->top_request->chk = (dc->uri->type == @@ -1809,7 +1862,7 @@ GNUNET_FS_download_start_task_ (void *cls, GNUNET_DISK_PERM_NONE); if (dc->top_request->state == BRS_CHK_SET) { - if (dc->rfh != NULL) + if (NULL != dc->rfh) { /* first, try top-down */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1823,7 +1876,7 @@ GNUNET_FS_download_start_task_ (void *cls, break; /* normal, some blocks already down */ case BRS_DOWNLOAD_UP: /* already done entirely, party! */ - if (dc->rfh != NULL) + if (NULL != dc->rfh) { /* avoid hanging on to file handle longer than * necessary */ @@ -1854,9 +1907,9 @@ GNUNET_FS_download_start_task_ (void *cls, (unsigned int) GNUNET_CONTAINER_meta_data_get_serialized_size (dc->meta)); GNUNET_CONTAINER_meta_data_iterate (dc->meta, &match_full_data, dc); - if (dc->top_request->state == BRS_DOWNLOAD_UP) + if (BRS_DOWNLOAD_UP == dc->top_request->state) { - if (dc->rfh != NULL) + if (NULL != dc->rfh) { /* avoid hanging on to file handle longer than * necessary */ @@ -1866,23 +1919,26 @@ GNUNET_FS_download_start_task_ (void *cls, return; /* finished, status update was already done for us */ } } - if (dc->rfh != NULL) + if (NULL != dc->rfh) { - /* finally, try bottom-up */ + /* finally, actually run bottom-up */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying bottom-up reconstruction of file `%s'\n", dc->filename); dc->te = - GNUNET_FS_tree_encoder_create (dc->h, dc->old_file_size, dc, &fh_reader, - &reconstruct_cb, NULL, - &reconstruct_cont); + GNUNET_FS_tree_encoder_create (dc->h, + GNUNET_FS_uri_chk_get_file_size (dc->uri), + dc, &fh_reader, + &reconstruct_cb, NULL, + &reconstruct_cont); dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); } else { /* simple, top-level download */ + dc->issue_requests = GNUNET_YES; schedule_block_download (dc, dc->top_request); } - if (dc->top_request->state == BRS_DOWNLOAD_UP) + if (BRS_DOWNLOAD_UP == dc->top_request->state) check_completed (dc); } @@ -1899,42 +1955,42 @@ GNUNET_FS_download_signal_suspend_ (void *cls) struct GNUNET_FS_DownloadContext *dc = cls; struct GNUNET_FS_ProgressInfo pi; - if (dc->top != NULL) + if (NULL != dc->top) GNUNET_FS_end_top (dc->h, dc->top); while (NULL != dc->child_head) GNUNET_FS_download_signal_suspend_ (dc->child_head); - if (dc->search != NULL) + if (NULL != dc->search) { dc->search->download = NULL; dc->search = NULL; } - if (dc->job_queue != NULL) + if (NULL != dc->job_queue) { GNUNET_FS_dequeue_ (dc->job_queue); dc->job_queue = NULL; } - if (dc->parent != NULL) + if (NULL != dc->parent) GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, dc->parent->child_tail, dc); - if (dc->task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != dc->task) { GNUNET_SCHEDULER_cancel (dc->task); dc->task = GNUNET_SCHEDULER_NO_TASK; } pi.status = GNUNET_FS_STATUS_DOWNLOAD_SUSPEND; GNUNET_FS_download_make_status_ (&pi, dc); - if (dc->te != NULL) + if (NULL != dc->te) { GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); dc->te = NULL; } - if (dc->rfh != NULL) + if (NULL != dc->rfh) { GNUNET_DISK_file_close (dc->rfh); dc->rfh = NULL; } GNUNET_FS_free_download_request_ (dc->top_request); - if (dc->active != NULL) + if (NULL != dc->active) { GNUNET_CONTAINER_multihashmap_destroy (dc->active); dc->active = NULL; @@ -1949,16 +2005,7 @@ GNUNET_FS_download_signal_suspend_ (void *cls) /** - * Download parts of a file. Note that this will store - * the blocks at the respective offset in the given file. Also, the - * download is still using the blocking of the underlying FS - * encoding. As a result, the download may *write* outside of the - * given boundaries (if offset and length do not match the 32k FS - * block boundaries).

- * - * This function should be used to focus a download towards a - * particular portion of the file (optimization), not to strictly - * limit the download to exactly those bytes. + * Helper function to setup the download context. * * @param h handle to the file sharing subsystem * @param uri the URI of the file (determines what to download); CHK or LOC URI @@ -1974,38 +2021,27 @@ GNUNET_FS_download_signal_suspend_ (void *cls) * @param anonymity anonymity level to use for the download * @param options various options * @param cctx initial value for the client context for this download - * @param parent parent download to associate this download with (use NULL - * for top-level downloads; useful for manually-triggered recursive downloads) * @return context that can be used to control this download */ struct GNUNET_FS_DownloadContext * -GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, - const struct GNUNET_FS_Uri *uri, - const struct GNUNET_CONTAINER_MetaData *meta, - const char *filename, const char *tempname, - uint64_t offset, uint64_t length, uint32_t anonymity, - enum GNUNET_FS_DownloadOptions options, void *cctx, - struct GNUNET_FS_DownloadContext *parent) +create_download_context (struct GNUNET_FS_Handle *h, + const struct GNUNET_FS_Uri *uri, + const struct GNUNET_CONTAINER_MetaData *meta, + const char *filename, const char *tempname, + uint64_t offset, uint64_t length, uint32_t anonymity, + enum GNUNET_FS_DownloadOptions options, void *cctx) { struct GNUNET_FS_DownloadContext *dc; GNUNET_assert (GNUNET_FS_uri_test_chk (uri) || GNUNET_FS_uri_test_loc (uri)); - if ((offset + length < offset) || (offset + length > GNUNET_FS_uri_chk_get_file_size (uri))) { GNUNET_break (0); return NULL; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting download `%s' of %llu bytes\n", - filename, (unsigned long long) length); dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext)); dc->h = h; - dc->parent = parent; - if (parent != NULL) - { - GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc); - } dc->uri = GNUNET_FS_uri_dup (uri); dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); dc->client_info = cctx; @@ -2014,7 +2050,7 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, { dc->filename = GNUNET_strdup (filename); if (GNUNET_YES == GNUNET_DISK_file_test (filename)) - GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES); + GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES, GNUNET_YES)); } if (GNUNET_FS_uri_test_loc (dc->uri)) GNUNET_assert (GNUNET_OK == @@ -2027,22 +2063,74 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); dc->treedepth = GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size (dc->uri)); - if ((filename == NULL) && (is_recursive_download (dc))) + if ((NULL == filename) && (is_recursive_download (dc))) { - if (tempname != NULL) + if (NULL != tempname) dc->temp_filename = GNUNET_strdup (tempname); else dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download tree has depth %u\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting download `%s' of %llu bytes with tree depth %u\n", + filename, + (unsigned long long) length, dc->treedepth); - if (parent == NULL) - { + dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc); + return dc; +} + + +/** + * Download parts of a file. Note that this will store + * the blocks at the respective offset in the given file. Also, the + * download is still using the blocking of the underlying FS + * encoding. As a result, the download may *write* outside of the + * given boundaries (if offset and length do not match the 32k FS + * block boundaries).

+ * + * This function should be used to focus a download towards a + * particular portion of the file (optimization), not to strictly + * limit the download to exactly those bytes. + * + * @param h handle to the file sharing subsystem + * @param uri the URI of the file (determines what to download); CHK or LOC URI + * @param meta known metadata for the file (can be NULL) + * @param filename where to store the file, maybe NULL (then no file is + * created on disk and data must be grabbed from the callbacks) + * @param tempname where to store temporary file data, not used if filename is non-NULL; + * can be NULL (in which case we will pick a name if needed); the temporary file + * may already exist, in which case we will try to use the data that is there and + * if it is not what is desired, will overwrite it + * @param offset at what offset should we start the download (typically 0) + * @param length how many bytes should be downloaded starting at offset + * @param anonymity anonymity level to use for the download + * @param options various options + * @param cctx initial value for the client context for this download + * @param parent parent download to associate this download with (use NULL + * for top-level downloads; useful for manually-triggered recursive downloads) + * @return context that can be used to control this download + */ +struct GNUNET_FS_DownloadContext * +GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, + const struct GNUNET_FS_Uri *uri, + const struct GNUNET_CONTAINER_MetaData *meta, + const char *filename, const char *tempname, + uint64_t offset, uint64_t length, uint32_t anonymity, + enum GNUNET_FS_DownloadOptions options, void *cctx, + struct GNUNET_FS_DownloadContext *parent) +{ + struct GNUNET_FS_DownloadContext *dc; + + dc = create_download_context (h, uri, meta, filename, tempname, + offset, length, anonymity, options, cctx); + if (NULL == dc) + return NULL; + dc->parent = parent; + if (NULL != parent) + GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc); + else dc->top = GNUNET_FS_make_top (dc->h, &GNUNET_FS_download_signal_suspend_, dc); - } - dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc); return dc; } @@ -2092,62 +2180,22 @@ GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, { struct GNUNET_FS_DownloadContext *dc; - if ((sr == NULL) || (sr->download != NULL)) + if ((NULL == sr) || (NULL != sr->download)) { GNUNET_break (0); return NULL; } - GNUNET_assert (GNUNET_FS_uri_test_chk (sr->uri) || - GNUNET_FS_uri_test_loc (sr->uri)); - if ((offset + length < offset) || - (offset + length > sr->uri->data.chk.file_length)) - { - GNUNET_break (0); + dc = create_download_context (h, sr->uri, sr->meta, filename, tempname, + offset, length, anonymity, options, cctx); + if (NULL == dc) return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting download `%s' of %llu bytes\n", - filename, (unsigned long long) length); - dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext)); - dc->h = h; dc->search = sr; sr->download = dc; - if (sr->probe_ctx != NULL) + if (NULL != sr->probe_ctx) { GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); sr->probe_ctx = NULL; } - dc->uri = GNUNET_FS_uri_dup (sr->uri); - dc->meta = GNUNET_CONTAINER_meta_data_duplicate (sr->meta); - dc->client_info = cctx; - dc->start_time = GNUNET_TIME_absolute_get (); - if (NULL != filename) - { - dc->filename = GNUNET_strdup (filename); - if (GNUNET_YES == GNUNET_DISK_file_test (filename)) - GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES); - } - if (GNUNET_FS_uri_test_loc (dc->uri)) - GNUNET_assert (GNUNET_OK == - GNUNET_FS_uri_loc_get_peer_identity (dc->uri, &dc->target)); - dc->offset = offset; - dc->length = length; - dc->anonymity = anonymity; - dc->options = options; - dc->active = - GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); - dc->treedepth = - GNUNET_FS_compute_depth (GNUNET_ntohll (dc->uri->data.chk.file_length)); - if ((filename == NULL) && (is_recursive_download (dc))) - { - if (tempname != NULL) - dc->temp_filename = GNUNET_strdup (tempname); - else - dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download tree has depth %u\n", - dc->treedepth); - dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc); return dc; } @@ -2162,10 +2210,13 @@ GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc) { if (dc->completed == dc->length) return; - GNUNET_assert (dc->job_queue == NULL); + GNUNET_assert (NULL == dc->job_queue); dc->job_queue = GNUNET_FS_queue_ (dc->h, &activate_fs_download, &deactivate_fs_download, - dc, (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE); + dc, (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE, + (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE)) + ? GNUNET_FS_QUEUE_PRIORITY_NORMAL + : GNUNET_FS_QUEUE_PRIORITY_PROBE); } @@ -2180,28 +2231,28 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete) { struct GNUNET_FS_ProgressInfo pi; int have_children; + int search_was_null; - if (dc->top != NULL) + if (NULL != dc->top) GNUNET_FS_end_top (dc->h, dc->top); - - - if (dc->task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != dc->task) { GNUNET_SCHEDULER_cancel (dc->task); dc->task = GNUNET_SCHEDULER_NO_TASK; } - if (dc->search != NULL) + search_was_null = (NULL == dc->search); + if (NULL != dc->search) { dc->search->download = NULL; GNUNET_FS_search_result_sync_ (dc->search); dc->search = NULL; } - if (dc->job_queue != NULL) + if (NULL != dc->job_queue) { GNUNET_FS_dequeue_ (dc->job_queue); dc->job_queue = NULL; } - if (dc->te != NULL) + if (NULL != dc->te) { GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); dc->te = NULL; @@ -2209,32 +2260,30 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete) have_children = (NULL != dc->child_head) ? GNUNET_YES : GNUNET_NO; while (NULL != dc->child_head) GNUNET_FS_download_stop (dc->child_head, do_delete); - if (dc->parent != NULL) + if (NULL != dc->parent) GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, dc->parent->child_tail, dc); - if (dc->serialization != NULL) + if (NULL != dc->serialization) GNUNET_FS_remove_sync_file_ (dc->h, - ((dc->parent != NULL) || - (dc->search != - NULL)) ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD : + ((NULL != dc->parent) || + (! search_was_null)) ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD, dc->serialization); - if ((GNUNET_YES == have_children) && (dc->parent == NULL)) + if ((GNUNET_YES == have_children) && (NULL == dc->parent)) GNUNET_FS_remove_sync_dir_ (dc->h, - (dc->search != - NULL) ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD : + (! search_was_null) ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD, dc->serialization); pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED; GNUNET_FS_download_make_status_ (&pi, dc); GNUNET_FS_free_download_request_ (dc->top_request); dc->top_request = NULL; - if (dc->active != NULL) + if (NULL != dc->active) { GNUNET_CONTAINER_multihashmap_destroy (dc->active); dc->active = NULL; } - if (dc->filename != NULL) + if (NULL != dc->filename) { if ((dc->completed != dc->length) && (GNUNET_YES == do_delete)) { diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c index 85a076f..8065927 100644 --- a/src/fs/fs_file_information.c +++ b/src/fs/fs_file_information.c @@ -107,7 +107,7 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h, *bo) { struct FileInfo *fi; - struct stat sbuf; + uint64_t fsize; struct GNUNET_FS_FileInformation *ret; const char *fn; const char *ss; @@ -116,7 +116,8 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h, char fn_conv[MAX_PATH]; #endif - if (0 != STAT (filename, &sbuf)) + /* FIXME: should includeSymLinks be GNUNET_NO or GNUNET_YES here? */ + if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fsize, GNUNET_NO, GNUNET_YES)) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename); return NULL; @@ -129,7 +130,7 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h, } ret = GNUNET_FS_file_information_create_from_reader (h, client_info, - sbuf.st_size, + fsize, &GNUNET_FS_data_reader_file_, fi, keywords, meta, do_index, bo); @@ -145,6 +146,9 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h, #endif while (NULL != (ss = strstr (fn, DIR_SEPARATOR_STR))) fn = ss + 1; +/* FIXME: If we assume that on other platforms CRT is UTF-8-aware, then + * this should be changed to EXTRACTOR_METAFORMAT_UTF8 + */ #if !WINDOWS GNUNET_CONTAINER_meta_data_insert (ret->meta, "", EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, diff --git a/src/fs/fs_list_indexed.c b/src/fs/fs_list_indexed.c index 784c988..ef03dee 100644 --- a/src/fs/fs_list_indexed.c +++ b/src/fs/fs_list_indexed.c @@ -176,7 +176,7 @@ GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, void GNUNET_FS_get_indexed_files_cancel (struct GNUNET_FS_GetIndexedContext *gic) { - GNUNET_CLIENT_disconnect (gic->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (gic->client); GNUNET_free (gic); } diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 1657e29..93c3046 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -98,7 +98,7 @@ publish_cleanup (struct GNUNET_FS_PublishContext *pc) } if (pc->client != NULL) { - GNUNET_CLIENT_disconnect (pc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (pc->client); pc->client = NULL; } GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); @@ -355,6 +355,8 @@ block_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg) } else { + if (UINT64_MAX == offset) + return p->data.file.reader (p->data.file.reader_cls, offset, 0, NULL, NULL); pt_size = GNUNET_MIN (max, p->data.file.file_size - offset); if (pt_size == 0) return 0; /* calling reader with pt_size==0 @@ -385,10 +387,10 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) char *emsg; uint64_t flen; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished with tree encoder\n"); p = pc->fi_pos; GNUNET_FS_tree_encoder_finish (p->te, &p->chk_uri, &emsg); p->te = NULL; - GNUNET_FS_file_information_sync_ (p); if (NULL != emsg) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error during tree walk: %s\n", emsg); @@ -399,16 +401,19 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) pi.value.publish.specifics.error.message = p->emsg; p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, 0); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished with tree encoder\n"); + else + { /* final progress event */ - flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri); - pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; - pi.value.publish.specifics.progress.data = NULL; - pi.value.publish.specifics.progress.offset = flen; - pi.value.publish.specifics.progress.data_len = 0; - pi.value.publish.specifics.progress.depth = GNUNET_FS_compute_depth (flen); - p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, flen); - + GNUNET_assert (NULL != p->chk_uri); + flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri); + pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; + pi.value.publish.specifics.progress.data = NULL; + pi.value.publish.specifics.progress.offset = flen; + pi.value.publish.specifics.progress.data_len = 0; + pi.value.publish.specifics.progress.depth = GNUNET_FS_compute_depth (flen); + p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, flen); + } + GNUNET_FS_file_information_sync_ (p); /* continue with main */ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); pc->upload_task = @@ -606,7 +611,7 @@ process_index_start_response (void *cls, const struct GNUNET_MessageHeader *msg) const char *emsg; uint16_t msize; - GNUNET_CLIENT_disconnect (pc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (pc->client); pc->client = NULL; p = pc->fi_pos; if (msg == NULL) @@ -942,10 +947,9 @@ fip_signal_start (void *cls, struct GNUNET_FS_FileInformation *fi, pi.status = GNUNET_FS_STATUS_PUBLISH_START; *client_info = GNUNET_FS_publish_make_status_ (&pi, pc, fi, 0); GNUNET_FS_file_information_sync_ (fi); - if (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta) - && (fi->dir != NULL)) + if ((fi->is_directory) && (fi->dir != NULL)) { - /* process entries in directory */ + /* We are a directory, and we are not top-level; process entries in directory */ pc->skip_next_fi_callback = GNUNET_YES; GNUNET_FS_file_information_inspect (fi, &fip_signal_start, pc); } diff --git a/src/fs/fs_publish_ksk.c b/src/fs/fs_publish_ksk.c index 5119de4..0b6d407 100644 --- a/src/fs/fs_publish_ksk.c +++ b/src/fs/fs_publish_ksk.c @@ -188,7 +188,7 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n", - keyword); + &keyword[1]); /* first character of keyword indicates if it is * mandatory or not -- ignore for hashing */ GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key); diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index a163d97..b280670 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001-2006, 2008-2011 Christian Grothoff (and other contributing authors) + (C) 2001-2006, 2008-2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,10 +14,9 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Free Software Foundation, Inc., 59 Tem ple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file fs/fs_search.c * @brief Helper functions for searching. @@ -30,7 +29,6 @@ #include "gnunet_protocols.h" #include "fs_api.h" -#define DEBUG_SEARCH GNUNET_EXTRA_LOGGING /** * Number of availability trials we perform per search result. @@ -54,7 +52,7 @@ GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi, pi->value.search.sc = sc; pi->value.search.cctx = sc->client_info; pi->value.search.pctx = - (sc->psearch_result == NULL) ? NULL : sc->psearch_result->client_info; + (NULL == sc->psearch_result) ? NULL : sc->psearch_result->client_info; pi->value.search.query = sc->uri; pi->value.search.duration = GNUNET_TIME_absolute_get_duration (sc->start_time); @@ -121,7 +119,7 @@ notify_client_chk_update (struct GNUNET_FS_SearchContext *sc, struct GNUNET_FS_SearchResult *sr) { struct GNUNET_FS_ProgressInfo pi; - + pi.status = GNUNET_FS_STATUS_SEARCH_UPDATE; pi.value.search.specifics.update.cctx = sr->client_info; pi.value.search.specifics.update.meta = sr->meta; @@ -184,7 +182,7 @@ signal_probe_result (struct GNUNET_FS_SearchResult *sr) { struct GNUNET_FS_ProgressInfo pi; - pi.status = GNUNET_FS_STATUS_SEARCH_START; + pi.status = GNUNET_FS_STATUS_SEARCH_UPDATE; pi.value.search.specifics.update.cctx = sr->client_info; pi.value.search.specifics.update.meta = sr->meta; pi.value.search.specifics.update.uri = sr->uri; @@ -192,7 +190,7 @@ signal_probe_result (struct GNUNET_FS_SearchResult *sr) pi.value.search.specifics.update.availability_certainty = sr->availability_trials; pi.value.search.specifics.update.applicability_rank = sr->optional_support; - sr->sc->client_info = GNUNET_FS_search_make_status_ (&pi, sr->sc); + sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->sc); GNUNET_FS_search_start_probe_ (sr); } @@ -208,7 +206,10 @@ probe_failure_handler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_SearchResult *sr = cls; + sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; sr->availability_trials++; + GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); + sr->probe_ctx = NULL; GNUNET_FS_search_result_sync_ (sr); signal_probe_result (sr); } @@ -225,8 +226,11 @@ probe_success_handler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_SearchResult *sr = cls; + sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; sr->availability_trials++; sr->availability_success++; + GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); + sr->probe_ctx = NULL; GNUNET_FS_search_result_sync_ (sr); signal_probe_result (sr); } @@ -271,7 +275,7 @@ GNUNET_FS_search_probe_progress_ (void *cls, /* ignore */ break; case GNUNET_FS_STATUS_DOWNLOAD_ERROR: - if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) { GNUNET_SCHEDULER_cancel (sr->probe_cancel_task); sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; @@ -281,17 +285,16 @@ GNUNET_FS_search_probe_progress_ (void *cls, &probe_failure_handler, sr); break; case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: - if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) { GNUNET_SCHEDULER_cancel (sr->probe_cancel_task); sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; } sr->probe_cancel_task = - GNUNET_SCHEDULER_add_delayed (sr->remaining_probe_time, - &probe_success_handler, sr); + GNUNET_SCHEDULER_add_now (&probe_success_handler, sr); break; case GNUNET_FS_STATUS_DOWNLOAD_STOPPED: - if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) { GNUNET_SCHEDULER_cancel (sr->probe_cancel_task); sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; @@ -299,14 +302,14 @@ GNUNET_FS_search_probe_progress_ (void *cls, sr = NULL; break; case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: - GNUNET_assert (sr->probe_cancel_task == GNUNET_SCHEDULER_NO_TASK); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sr->probe_cancel_task); sr->probe_active_time = GNUNET_TIME_absolute_get (); sr->probe_cancel_task = GNUNET_SCHEDULER_add_delayed (sr->remaining_probe_time, &probe_failure_handler, sr); break; case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: - if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) { GNUNET_SCHEDULER_cancel (sr->probe_cancel_task); sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; @@ -335,16 +338,18 @@ GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr) uint64_t off; uint64_t len; - if (sr->probe_ctx != NULL) + if (NULL != sr->probe_ctx) return; - if (sr->download != NULL) + if (NULL != sr->download) return; if (0 == (sr->sc->h->flags & GNUNET_FS_FLAGS_DO_PROBES)) return; if (sr->availability_trials > AVAILABILITY_TRIALS_MAX) return; + if ( (chk != sr->uri->type) && (loc != sr->uri->type)) + return; len = GNUNET_FS_uri_chk_get_file_size (sr->uri); - if (len == 0) + if (0 == len) return; if ((len <= DBLOCK_SIZE) && (sr->availability_success > 0)) return; @@ -497,7 +502,7 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update, /* notify client */ notify_client_chk_result (sc, sr); /* search for updates */ - if (strlen (id_update) == 0) + if (0 == strlen (id_update)) return; /* no updates */ uu.type = sks; uu.data.sks.namespace = sc->uri->data.sks.namespace; @@ -508,28 +513,32 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update, /** - * Process a keyword-search result. + * Decrypt a block using a 'keyword' as the passphrase. Given the + * KSK public key derived from the keyword, this function looks up + * the original keyword in the search context and decrypts the + * given ciphertext block. * - * @param sc our search context - * @param kb the kblock - * @param size size of kb + * @param sc search context with the keywords + * @param public_key public key to use to lookup the keyword + * @param edata encrypted data + * @param edata_size number of bytes in 'edata' (and 'data') + * @param data where to store the plaintext + * @return keyword index on success, GNUNET_SYSERR on error (no such + * keyword, internal error) */ -static void -process_kblock (struct GNUNET_FS_SearchContext *sc, const struct KBlock *kb, - size_t size) -{ - unsigned int i; - size_t j; +static int +decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key, + const void *edata, + size_t edata_size, + char *data) +{ GNUNET_HashCode q; - char pt[size - sizeof (struct KBlock)]; struct GNUNET_CRYPTO_AesSessionKey skey; struct GNUNET_CRYPTO_AesInitializationVector iv; - const char *eos; - struct GNUNET_CONTAINER_MetaData *meta; - struct GNUNET_FS_Uri *uri; - char *emsg; + int i; - GNUNET_CRYPTO_hash (&kb->keyspace, + GNUNET_CRYPTO_hash (public_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &q); /* find key */ @@ -540,17 +549,46 @@ process_kblock (struct GNUNET_FS_SearchContext *sc, const struct KBlock *kb, { /* oops, does not match any of our keywords!? */ GNUNET_break (0); - return; + return GNUNET_SYSERR; } /* decrypt */ GNUNET_CRYPTO_hash_to_aes_key (&sc->requests[i].key, &skey, &iv); if (-1 == - GNUNET_CRYPTO_aes_decrypt (&kb[1], size - sizeof (struct KBlock), &skey, - &iv, pt)) + GNUNET_CRYPTO_aes_decrypt (edata, edata_size, &skey, + &iv, data)) { GNUNET_break (0); - return; + return GNUNET_SYSERR; } + return i; +} + + +/** + * Process a keyword-search result. + * + * @param sc our search context + * @param kb the kblock + * @param size size of kb + */ +static void +process_kblock (struct GNUNET_FS_SearchContext *sc, const struct KBlock *kb, + size_t size) +{ + size_t j; + char pt[size - sizeof (struct KBlock)]; + const char *eos; + struct GNUNET_CONTAINER_MetaData *meta; + struct GNUNET_FS_Uri *uri; + char *emsg; + int i; + + if (-1 == (i = decrypt_block_with_keyword (sc, + &kb->keyspace, + &kb[1], + size - sizeof (struct KBlock), + pt))) + return; /* parse */ eos = memchr (pt, 0, sizeof (pt)); if (NULL == eos) @@ -563,13 +601,13 @@ process_kblock (struct GNUNET_FS_SearchContext *sc, const struct KBlock *kb, meta = GNUNET_CONTAINER_meta_data_create (); else meta = GNUNET_CONTAINER_meta_data_deserialize (&pt[j], sizeof (pt) - j); - if (meta == NULL) + if (NULL == meta) { GNUNET_break_op (0); /* kblock malformed */ return; } uri = GNUNET_FS_uri_parse (pt, &emsg); - if (uri == NULL) + if (NULL == uri) { GNUNET_break_op (0); /* kblock malformed */ GNUNET_free_non_null (emsg); @@ -596,39 +634,20 @@ static void process_nblock (struct GNUNET_FS_SearchContext *sc, const struct NBlock *nb, size_t size) { - unsigned int i; size_t j; - GNUNET_HashCode q; char pt[size - sizeof (struct NBlock)]; - struct GNUNET_CRYPTO_AesSessionKey skey; - struct GNUNET_CRYPTO_AesInitializationVector iv; const char *eos; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *uri; char *uris; + int i; - GNUNET_CRYPTO_hash (&nb->keyspace, - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &q); - /* find key */ - for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) - if (0 == memcmp (&q, &sc->requests[i].query, sizeof (GNUNET_HashCode))) - break; - if (i == sc->uri->data.ksk.keywordCount) - { - /* oops, does not match any of our keywords!? */ - GNUNET_break (0); - return; - } - /* decrypt */ - GNUNET_CRYPTO_hash_to_aes_key (&sc->requests[i].key, &skey, &iv); - if (-1 == - GNUNET_CRYPTO_aes_decrypt (&nb[1], size - sizeof (struct NBlock), &skey, - &iv, pt)) - { - GNUNET_break (0); + if (-1 == (i = decrypt_block_with_keyword (sc, + &nb->keyspace, + &nb[1], + size - sizeof (struct NBlock), + pt))) return; - } /* parse */ eos = memchr (pt, 0, sizeof (pt)); if (NULL == eos) @@ -641,7 +660,7 @@ process_nblock (struct GNUNET_FS_SearchContext *sc, const struct NBlock *nb, meta = GNUNET_CONTAINER_meta_data_create (); else meta = GNUNET_CONTAINER_meta_data_deserialize (&pt[j], sizeof (pt) - j); - if (meta == NULL) + if (NULL == meta) { GNUNET_break_op (0); /* nblock malformed */ return; @@ -703,7 +722,7 @@ process_sblock (struct GNUNET_FS_SearchContext *sc, const struct SBlock *sb, } /* parse */ off = GNUNET_STRINGS_buffer_tokenize (pt, len, 2, &id, &uris); - if (off == 0) + if (0 == off) { GNUNET_break_op (0); /* sblock malformed */ return; @@ -715,7 +734,7 @@ process_sblock (struct GNUNET_FS_SearchContext *sc, const struct SBlock *sb, return; } uri = GNUNET_FS_uri_parse (uris, &emsg); - if (uri == NULL) + if (NULL == uri) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to parse URI `%s': %s\n", uris, emsg); @@ -914,7 +933,7 @@ build_result_set (void *cls, const GNUNET_HashCode * key, void *value) struct MessageBuilderContext *mbc = cls; struct GNUNET_FS_SearchResult *sr = value; - if ( (sr->keyword_bitmap != NULL) && + if ( (NULL != sr->keyword_bitmap) && (0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1 << (mbc->keyword_offset % 8)))) ) return GNUNET_OK; /* have no match for this keyword yet */ if (mbc->skip_cnt > 0) @@ -922,7 +941,7 @@ build_result_set (void *cls, const GNUNET_HashCode * key, void *value) mbc->skip_cnt--; return GNUNET_OK; } - if (mbc->put_cnt == 0) + if (0 == mbc->put_cnt) return GNUNET_SYSERR; mbc->sc->search_request_map_offset++; mbc->xoff[--mbc->put_cnt] = *key; @@ -946,7 +965,7 @@ find_result_set (void *cls, const GNUNET_HashCode * key, void *value) struct MessageBuilderContext *mbc = cls; struct GNUNET_FS_SearchResult *sr = value; - if ( (sr->keyword_bitmap != NULL) && + if ( (NULL != sr->keyword_bitmap) && (0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1 << (mbc->keyword_offset % 8)))) ) return GNUNET_OK; /* have no match for this keyword yet */ mbc->put_cnt++; @@ -1133,7 +1152,7 @@ try_reconnect (struct GNUNET_FS_SearchContext *sc) { if (NULL != sc->client) { - GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (sc->client); sc->client = NULL; } sc->task = @@ -1168,7 +1187,7 @@ search_start (struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, sc->uri = GNUNET_FS_uri_dup (uri); sc->anonymity = anonymity; sc->start_time = GNUNET_TIME_absolute_get (); - if (psearch != NULL) + if (NULL != psearch) { sc->psearch_result = psearch; psearch->update_search = sc; @@ -1217,7 +1236,7 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc) keyword = &sc->uri->data.ksk.keywords[i][1]; GNUNET_CRYPTO_hash (keyword, strlen (keyword), &hc); pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&hc); - GNUNET_assert (pk != NULL); + GNUNET_assert (NULL != pk); GNUNET_CRYPTO_rsa_key_get_public (pk, &pub); GNUNET_CRYPTO_rsa_key_free (pk); GNUNET_CRYPTO_hash (&pub, @@ -1253,17 +1272,17 @@ search_result_freeze_probes (void *cls, const GNUNET_HashCode * key, { struct GNUNET_FS_SearchResult *sr = value; - if (sr->probe_ctx != NULL) + if (NULL != sr->probe_ctx) { GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); sr->probe_ctx = NULL; } - if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) { GNUNET_SCHEDULER_cancel (sr->probe_cancel_task); sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; } - if (sr->update_search != NULL) + if (NULL != sr->update_search) GNUNET_FS_search_pause (sr->update_search); return GNUNET_OK; } @@ -1284,7 +1303,7 @@ search_result_resume_probes (void *cls, const GNUNET_HashCode * key, struct GNUNET_FS_SearchResult *sr = value; GNUNET_FS_search_start_probe_ (sr); - if (sr->update_search != NULL) + if (NULL != sr->update_search) GNUNET_FS_search_continue (sr->update_search); return GNUNET_OK; } @@ -1305,10 +1324,21 @@ search_result_suspend (void *cls, const GNUNET_HashCode * key, void *value) struct GNUNET_FS_SearchResult *sr = value; struct GNUNET_FS_ProgressInfo pi; - if (sr->download != NULL) + if (NULL != sr->download) + { GNUNET_FS_download_signal_suspend_ (sr->download); - if (sr->update_search != NULL) + sr->download = NULL; + } + if (NULL != sr->probe_ctx) + { + GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); + sr->probe_ctx = NULL; + } + if (NULL != sr->update_search) + { GNUNET_FS_search_signal_suspend_ (sr->update_search); + sr->update_search = NULL; + } pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND; pi.value.search.specifics.result_suspend.cctx = sr->client_info; pi.value.search.specifics.result_suspend.meta = sr->meta; @@ -1318,10 +1348,11 @@ search_result_suspend (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_free_non_null (sr->serialization); GNUNET_FS_uri_destroy (sr->uri); GNUNET_CONTAINER_meta_data_destroy (sr->meta); - if (sr->probe_ctx != NULL) - GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); - if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) + { GNUNET_SCHEDULER_cancel (sr->probe_cancel_task); + sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK; + } GNUNET_free_non_null (sr->keyword_bitmap); GNUNET_free (sr); return GNUNET_OK; @@ -1350,9 +1381,9 @@ GNUNET_FS_search_signal_suspend_ (void *cls) if (sc->task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (sc->task); if (NULL != sc->client) - GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (sc->client); GNUNET_CONTAINER_multihashmap_destroy (sc->master_result_map); - if (sc->requests != NULL) + if (NULL != sc->requests) { GNUNET_assert (GNUNET_FS_uri_test_ksk (sc->uri)); for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) @@ -1385,7 +1416,7 @@ GNUNET_FS_search_start (struct GNUNET_FS_Handle *h, struct GNUNET_FS_SearchContext *ret; ret = search_start (h, uri, anonymity, options, cctx, NULL); - if (ret == NULL) + if (NULL == ret) return NULL; ret->top = GNUNET_FS_make_top (h, &GNUNET_FS_search_signal_suspend_, ret); return ret; @@ -1402,11 +1433,11 @@ GNUNET_FS_search_pause (struct GNUNET_FS_SearchContext *sc) { struct GNUNET_FS_ProgressInfo pi; - if (sc->task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sc->task) GNUNET_SCHEDULER_cancel (sc->task); sc->task = GNUNET_SCHEDULER_NO_TASK; if (NULL != sc->client) - GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (sc->client); sc->client = NULL; GNUNET_FS_search_sync_ (sc); GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, @@ -1426,8 +1457,8 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc) { struct GNUNET_FS_ProgressInfo pi; - GNUNET_assert (sc->client == NULL); - GNUNET_assert (sc->task == GNUNET_SCHEDULER_NO_TASK); + GNUNET_assert (NULL == sc->client); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sc->task); do_reconnect (sc, NULL); GNUNET_FS_search_sync_ (sc); pi.status = GNUNET_FS_STATUS_SEARCH_CONTINUED; @@ -1438,7 +1469,7 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc) /** - * Free the given search result. + * Signal stop for the given search result. * * @param cls the global FS handle * @param key the key for the search result (unused) @@ -1446,7 +1477,7 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc) * @return GNUNET_OK */ static int -search_result_free (void *cls, const GNUNET_HashCode * key, void *value) +search_result_stop (void *cls, const GNUNET_HashCode * key, void *value) { struct GNUNET_FS_SearchContext *sc = cls; struct GNUNET_FS_SearchResult *sr = value; @@ -1470,23 +1501,40 @@ search_result_free (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_FS_download_sync_ (sr->download); sr->download = NULL; } - if (NULL != sr->update_search) - { - GNUNET_FS_search_stop (sr->update_search); - GNUNET_assert (sr->update_search == NULL); - } pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED; pi.value.search.specifics.result_stopped.cctx = sr->client_info; pi.value.search.specifics.result_stopped.meta = sr->meta; pi.value.search.specifics.result_stopped.uri = sr->uri; sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc); + return GNUNET_OK; +} + + +/** + * Free the given search result. + * + * @param cls the global FS handle + * @param key the key for the search result (unused) + * @param value the search result to free + * @return GNUNET_OK + */ +static int +search_result_free (void *cls, const GNUNET_HashCode * key, void *value) +{ + struct GNUNET_FS_SearchResult *sr = value; + + if (NULL != sr->update_search) + { + GNUNET_FS_search_stop (sr->update_search); + GNUNET_assert (NULL == sr->update_search); + } GNUNET_break (NULL == sr->client_info); GNUNET_free_non_null (sr->serialization); GNUNET_FS_uri_destroy (sr->uri); GNUNET_CONTAINER_meta_data_destroy (sr->meta); - if (sr->probe_ctx != NULL) + if (NULL != sr->probe_ctx) GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); - if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) GNUNET_SCHEDULER_cancel (sr->probe_cancel_task); GNUNET_free_non_null (sr->keyword_bitmap); GNUNET_free (sr); @@ -1505,13 +1553,13 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc) struct GNUNET_FS_ProgressInfo pi; unsigned int i; - if (sc->top != NULL) + if (NULL != sc->top) GNUNET_FS_end_top (sc->h, sc->top); - if (sc->psearch_result != NULL) - sc->psearch_result->update_search = NULL; GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, - &search_result_free, sc); - if (sc->serialization != NULL) + &search_result_stop, sc); + if (NULL != sc->psearch_result) + sc->psearch_result->update_search = NULL; + if (NULL != sc->serialization) { GNUNET_FS_remove_sync_file_ (sc->h, (sc->psearch_result != @@ -1528,12 +1576,14 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc) pi.status = GNUNET_FS_STATUS_SEARCH_STOPPED; sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc); GNUNET_break (NULL == sc->client_info); - if (sc->task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != sc->task) GNUNET_SCHEDULER_cancel (sc->task); if (NULL != sc->client) - GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (sc->client); + GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, + &search_result_free, sc); GNUNET_CONTAINER_multihashmap_destroy (sc->master_result_map); - if (sc->requests != NULL) + if (NULL != sc->requests) { GNUNET_assert (GNUNET_FS_uri_test_ksk (sc->uri)); for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) diff --git a/src/fs/fs_tree.c b/src/fs/fs_tree.c index b3bbdc7..30cdded 100644 --- a/src/fs/fs_tree.c +++ b/src/fs/fs_tree.c @@ -287,6 +287,10 @@ GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h, uint64_t size, te->chk_tree = GNUNET_malloc (te->chk_tree_depth * CHK_PER_INODE * sizeof (struct ContentHashKey)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Created tree encoder for file with %llu bytes and depth %u\n", + (unsigned long long) size, + te->chk_tree_depth); return te; } @@ -357,8 +361,8 @@ GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te) if (pt_size != te->reader (te->cls, te->publish_offset, pt_size, iob, &te->emsg)) { - te->cont (te->cls, NULL); te->in_next = GNUNET_NO; + te->cont (te->cls, NULL); return; } pt_block = iob; @@ -425,6 +429,7 @@ void GNUNET_FS_tree_encoder_finish (struct GNUNET_FS_TreeEncoder *te, struct GNUNET_FS_Uri **uri, char **emsg) { + (void) te->reader (te->cls, UINT64_MAX, 0, 0, NULL); GNUNET_assert (GNUNET_NO == te->in_next); if (uri != NULL) *uri = te->uri; diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c index ff1996a..6910321 100644 --- a/src/fs/fs_unindex.c +++ b/src/fs/fs_unindex.c @@ -30,6 +30,7 @@ #include "gnunet_protocols.h" #include "fs_api.h" #include "fs_tree.h" +#include "block_fs.h" /** @@ -203,6 +204,7 @@ unindex_process (void *cls, const struct ContentHashKey *chk, uint64_t offset, "Sending REMOVE request to DATASTORE service\n"); GNUNET_DATASTORE_remove (uc->dsh, &chk->query, size, data, -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, &process_cont, uc); + uc->chk = *chk; } @@ -221,7 +223,7 @@ process_fs_response (void *cls, const struct GNUNET_MessageHeader *msg) if (uc->client != NULL) { - GNUNET_CLIENT_disconnect (uc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (uc->client); uc->client = NULL; } if (uc->state != UNINDEX_STATE_FS_NOTIFY) @@ -258,16 +260,15 @@ process_fs_response (void *cls, const struct GNUNET_MessageHeader *msg) /** - * Function called when the tree encoder has - * processed all blocks. Clean up. + * Function called when we are done with removing KBlocks. + * Disconnect from datastore and notify FS service about + * the unindex event. * - * @param cls our unindexing context - * @param tc not used + * @param uc our unindexing context */ static void -unindex_finish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +unindex_finish (struct GNUNET_FS_UnindexContext *uc) { - struct GNUNET_FS_UnindexContext *uc = cls; char *emsg; struct GNUNET_FS_Uri *uri; struct UnindexMessage req; @@ -310,6 +311,297 @@ unindex_finish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } + +/** + * Function called by the directory scanner as we extract keywords + * that we will need to remove KBlocks. + * + * @param cls the 'struct GNUNET_FS_UnindexContext *' + * @param filename which file we are making progress on + * @param is_directory GNUNET_YES if this is a directory, + * GNUNET_NO if this is a file + * GNUNET_SYSERR if it is neither (or unknown) + * @param reason kind of progress we are making + */ +static void +unindex_directory_scan_cb (void *cls, + const char *filename, + int is_directory, + enum GNUNET_FS_DirScannerProgressUpdateReason reason) +{ + struct GNUNET_FS_UnindexContext *uc = cls; + static struct GNUNET_FS_ShareTreeItem * directory_scan_result; + + switch (reason) + { + case GNUNET_FS_DIRSCANNER_FINISHED: + directory_scan_result = GNUNET_FS_directory_scan_get_result (uc->dscan); + uc->dscan = NULL; + if (NULL != directory_scan_result->ksk_uri) + { + uc->ksk_uri = GNUNET_FS_uri_dup (directory_scan_result->ksk_uri); + uc->state = UNINDEX_STATE_DS_REMOVE_KBLOCKS; + uc->emsg = GNUNET_strdup (_("Failed to get KSKs from directory scan.")); + GNUNET_FS_unindex_sync_ (uc); + GNUNET_FS_unindex_do_remove_kblocks_ (uc); + } + else + { + unindex_finish (uc); + } + GNUNET_FS_share_tree_free (directory_scan_result); + break; + case GNUNET_FS_DIRSCANNER_INTERNAL_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Internal error scanning `%s'.\n"), + uc->filename); + break; + default: + break; + } + +} + + +/** + * If necessary, connect to the datastore and remove the KBlocks. + * + * @param uc context for the unindex operation. + */ +void +GNUNET_FS_unindex_do_extract_keywords_ (struct GNUNET_FS_UnindexContext *uc) +{ + char *ex; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (uc->h->cfg, "FS", "EXTRACTORS", &ex)) + ex = NULL; + uc->dscan = GNUNET_FS_directory_scan_start (uc->filename, + GNUNET_NO, ex, + &unindex_directory_scan_cb, + uc); + GNUNET_free_non_null (ex); +} + + +/** + * Continuation called to notify client about result of the remove + * operation for the KBlock. + * + * @param cls the 'struct GNUNET_FS_UnindexContext *' + * @param success GNUNET_SYSERR on failure (including timeout/queue drop) + * GNUNET_NO if content was already there + * GNUNET_YES (or other positive value) on success + * @param min_expiration minimum expiration time required for 0-priority content to be stored + * by the datacache at this time, zero for unknown, forever if we have no + * space for 0-priority content + * @param msg NULL on success, otherwise an error message + */ +static void +continue_after_remove (void *cls, + int32_t success, + struct GNUNET_TIME_Absolute min_expiration, + const char *msg) +{ + struct GNUNET_FS_UnindexContext *uc = cls; + + uc->dqe = NULL; + if (success != GNUNET_YES) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to remove KBlock: %s\n"), + msg); + uc->ksk_offset++; + GNUNET_FS_unindex_do_remove_kblocks_ (uc); +} + + +/** + * Function called from datastore with result from us looking for + * a KBlock. There are four cases: + * 1) no result, means we move on to the next keyword + * 2) UID is the same as the first UID, means we move on to next keyword + * 3) KBlock for a different CHK, means we keep looking for more + * 4) KBlock is for our CHK, means we remove the block and then move + * on to the next keyword + * + * @param cls the 'struct GNUNET_FS_UnindexContext *' + * @param key key for the content + * @param size number of bytes in data + * @param data content stored + * @param type type of the content + * @param priority priority of the content + * @param anonymity anonymity-level for the content + * @param expiration expiration time for the content + * @param uid unique identifier for the datum; + * maybe 0 if no unique identifier is available + */ +static void +process_kblock_for_unindex (void *cls, + const GNUNET_HashCode * key, + size_t size, const void *data, + enum GNUNET_BLOCK_Type type, + uint32_t priority, + uint32_t anonymity, + struct GNUNET_TIME_Absolute + expiration, uint64_t uid) +{ + struct GNUNET_FS_UnindexContext *uc = cls; + const struct KBlock *kb; + struct GNUNET_FS_Uri *chk_uri; + + uc->dqe = NULL; + if (NULL == data) + { + /* no result */ + uc->ksk_offset++; + GNUNET_FS_unindex_do_remove_kblocks_ (uc); + return; + } + if (0 == uc->first_uid) + { + /* remember UID of first result to detect cycles */ + uc->first_uid = uid; + } + else if (uid == uc->first_uid) + { + /* no more additional results */ + uc->ksk_offset++; + GNUNET_FS_unindex_do_remove_kblocks_ (uc); + return; + } + GNUNET_assert (GNUNET_BLOCK_TYPE_FS_KBLOCK == type); + if (size < sizeof (struct KBlock)) + { + GNUNET_break (0); + goto get_next; + } + kb = data; + { + char pt[size - sizeof (struct KBlock)]; + struct GNUNET_CRYPTO_AesSessionKey skey; + struct GNUNET_CRYPTO_AesInitializationVector iv; + + GNUNET_CRYPTO_hash_to_aes_key (&uc->key, &skey, &iv); + if (-1 == + GNUNET_CRYPTO_aes_decrypt (&kb[1], size - sizeof (struct KBlock), &skey, + &iv, pt)) + { + GNUNET_break (0); + goto get_next; + } + if (NULL == memchr (pt, 0, sizeof (pt))) + { + GNUNET_break (0); + goto get_next; + } + chk_uri = GNUNET_FS_uri_parse (pt, NULL); + if (NULL == chk_uri) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to parse URI `%s' from KBlock!\n"), + pt); + GNUNET_break (0); + goto get_next; + } + } + if (0 != memcmp (&uc->chk, + &chk_uri->data.chk.chk, + sizeof (struct ContentHashKey))) + { + /* different CHK, ignore */ + GNUNET_FS_uri_destroy (chk_uri); + goto get_next; + } + GNUNET_FS_uri_destroy (chk_uri); + /* matches! */ + uc->dqe = GNUNET_DATASTORE_remove (uc->dsh, + key, size, data, + 0 /* priority */, 1 /* queue size */, + GNUNET_TIME_UNIT_FOREVER_REL, + &continue_after_remove, + uc); + return; + get_next: + uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, + uc->roff++, + &uc->query, + GNUNET_BLOCK_TYPE_FS_KBLOCK, + 0 /* priority */, 1 /* queue size */, + GNUNET_TIME_UNIT_FOREVER_REL, + &process_kblock_for_unindex, + uc); +} + + +/** + * If necessary, connect to the datastore and remove the KBlocks. + * + * @param uc context for the unindex operation. + */ +void +GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc) +{ + const char *keyword; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; + struct GNUNET_CRYPTO_RsaPrivateKey *pk; + + if (NULL == uc->dsh) + uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg); + if (NULL == uc->dsh) + { + uc->state = UNINDEX_STATE_ERROR; + uc->emsg = GNUNET_strdup (_("Failed to connect to `datastore' service.")); + GNUNET_FS_unindex_sync_ (uc); + signal_unindex_error (uc); + return; + } + if ( (NULL == uc->ksk_uri) || + (uc->ksk_offset >= uc->ksk_uri->data.ksk.keywordCount) ) + { + unindex_finish (uc); + return; + } + /* FIXME: code duplication with fs_search.c here... */ + keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1]; + GNUNET_CRYPTO_hash (keyword, strlen (keyword), &uc->key); + pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&uc->key); + GNUNET_assert (pk != NULL); + GNUNET_CRYPTO_rsa_key_get_public (pk, &pub); + GNUNET_CRYPTO_rsa_key_free (pk); + GNUNET_CRYPTO_hash (&pub, + sizeof (struct + GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &uc->query); + uc->first_uid = 0; + uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, + uc->roff++, + &uc->query, + GNUNET_BLOCK_TYPE_FS_KBLOCK, + 0 /* priority */, 1 /* queue size */, + GNUNET_TIME_UNIT_FOREVER_REL, + &process_kblock_for_unindex, + uc); +} + + +/** + * Function called when the tree encoder has + * processed all blocks. Clean up. + * + * @param cls our unindexing context + * @param tc not used + */ +static void +unindex_extract_keywords (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_FS_UnindexContext *uc = cls; + + uc->state = UNINDEX_STATE_EXTRACT_KEYWORDS; + GNUNET_FS_unindex_sync_ (uc); + GNUNET_FS_unindex_do_extract_keywords_ (uc); +} + + /** * Connect to the datastore and remove the blocks. * @@ -318,7 +610,8 @@ unindex_finish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) void GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc) { - uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg); + if (NULL == uc->dsh) + uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg); if (NULL == uc->dsh) { uc->state = UNINDEX_STATE_ERROR; @@ -343,7 +636,7 @@ GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc) uc->tc = GNUNET_FS_tree_encoder_create (uc->h, uc->file_size, uc, &unindex_reader, &unindex_process, &unindex_progress, - &unindex_finish); + &unindex_extract_keywords); GNUNET_FS_tree_encoder_next (uc->tc); } @@ -393,14 +686,30 @@ GNUNET_FS_unindex_signal_suspend_ (void *cls) struct GNUNET_FS_UnindexContext *uc = cls; struct GNUNET_FS_ProgressInfo pi; + /* FIXME: lots of duplication with unindex_stop here! */ + if (uc->dscan != NULL) + { + GNUNET_FS_directory_scan_abort (uc->dscan); + uc->dscan = NULL; + } + if (NULL != uc->dqe) + { + GNUNET_DATASTORE_cancel (uc->dqe); + uc->dqe = NULL; + } if (uc->fhc != NULL) { GNUNET_CRYPTO_hash_file_cancel (uc->fhc); uc->fhc = NULL; } + if (NULL != uc->ksk_uri) + { + GNUNET_FS_uri_destroy (uc->ksk_uri); + uc->ksk_uri = NULL; + } if (uc->client != NULL) { - GNUNET_CLIENT_disconnect (uc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (uc->client); uc->client = NULL; } if (NULL != uc->dsh) @@ -447,7 +756,7 @@ GNUNET_FS_unindex_start (struct GNUNET_FS_Handle *h, const char *filename, struct GNUNET_FS_ProgressInfo pi; uint64_t size; - if (GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES)) + if (GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES, GNUNET_YES)) return NULL; ret = GNUNET_malloc (sizeof (struct GNUNET_FS_UnindexContext)); ret->h = h; @@ -478,6 +787,16 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc) { struct GNUNET_FS_ProgressInfo pi; + if (uc->dscan != NULL) + { + GNUNET_FS_directory_scan_abort (uc->dscan); + uc->dscan = NULL; + } + if (NULL != uc->dqe) + { + GNUNET_DATASTORE_cancel (uc->dqe); + uc->dqe = NULL; + } if (uc->fhc != NULL) { GNUNET_CRYPTO_hash_file_cancel (uc->fhc); @@ -485,7 +804,7 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc) } if (uc->client != NULL) { - GNUNET_CLIENT_disconnect (uc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (uc->client); uc->client = NULL; } if (NULL != uc->dsh) @@ -493,6 +812,11 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc) GNUNET_DATASTORE_disconnect (uc->dsh, GNUNET_NO); uc->dsh = NULL; } + if (NULL != uc->ksk_uri) + { + GNUNET_FS_uri_destroy (uc->ksk_uri); + uc->ksk_uri = NULL; + } if (NULL != uc->tc) { GNUNET_FS_tree_encoder_finish (uc->tc, NULL, NULL); @@ -517,6 +841,7 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc) (uc->state == UNINDEX_STATE_COMPLETE) ? uc->file_size : 0); GNUNET_break (NULL == uc->client_info); + GNUNET_free_non_null (uc->emsg); GNUNET_free (uc->filename); GNUNET_free (uc); } diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c index 5dfdcb5..0c2d64c 100644 --- a/src/fs/fs_uri.c +++ b/src/fs/fs_uri.c @@ -214,7 +214,7 @@ percent_decode_keyword (const char *in, char **emsg) { if (out[rpos] == '%') { - if (1 != sscanf (&out[rpos + 1], "%2X", &hx)) + if (1 != SSCANF (&out[rpos + 1], "%2X", &hx)) { GNUNET_free (out); *emsg = GNUNET_strdup (_("`%' must be followed by HEX number")); @@ -1378,14 +1378,16 @@ GNUNET_FS_uri_sks_to_string_fancy (struct GNUNET_CONFIGURATION_Handle *cfg, { char *ret; char *name; + char *unique_name; if (uri->type != sks) return NULL; - name = GNUNET_PSEUDONYM_id_to_name (cfg, &uri->data.sks.namespace); - if (name == NULL) - return GNUNET_FS_uri_to_string (uri); - GNUNET_asprintf (&ret, "%s: %s", name, uri->data.sks.identifier); + (void) GNUNET_PSEUDONYM_get_info (cfg, &uri->data.sks.namespace, + NULL, NULL, &name, NULL); + unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &uri->data.sks.namespace, name, NULL); GNUNET_free (name); + GNUNET_asprintf (&ret, "%s: %s", unique_name, uri->data.sks.identifier); + GNUNET_free (unique_name); return ret; } @@ -1499,6 +1501,10 @@ find_duplicate (const char *s, const char **array, int array_length) return GNUNET_NO; } + +/** + * FIXME: comment + */ static char * normalize_metadata (enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len) diff --git a/src/fs/gnunet-directory.c b/src/fs/gnunet-directory.c index 0721ea9..c722f57 100644 --- a/src/fs/gnunet-directory.c +++ b/src/fs/gnunet-directory.c @@ -136,7 +136,7 @@ run (void *cls, char *const *args, const char *cfgfile, i = 0; while (NULL != (filename = args[i++])) { - if ((GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES)) || + if ((GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES, GNUNET_YES)) || (NULL == (h = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, diff --git a/src/fs/gnunet-download.c b/src/fs/gnunet-download.c index ff10c39..5a66aea 100644 --- a/src/fs/gnunet-download.c +++ b/src/fs/gnunet-download.c @@ -90,7 +90,8 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) { - char *s, *s2; + char *s; + char *s2; char *t; switch (info->status) diff --git a/src/fs/gnunet-helper-fs-publish.c b/src/fs/gnunet-helper-fs-publish.c index 4f70464..86b0249 100644 --- a/src/fs/gnunet-helper-fs-publish.c +++ b/src/fs/gnunet-helper-fs-publish.c @@ -69,7 +69,8 @@ struct ScanTreeNode char *filename; /** - * Size of the file (if it is a file), in bytes + * Size of the file (if it is a file), in bytes. + * At the moment it is set to 0 for directories. */ uint64_t file_size; @@ -185,6 +186,11 @@ write_message (uint16_t message_type, { struct GNUNET_MessageHeader hdr; +#if 0 + fprintf (stderr, "Helper sends %u-byte message of type %u\n", + (unsigned int) (sizeof (struct GNUNET_MessageHeader) + data_length), + (unsigned int) message_type); +#endif hdr.type = htons (message_type); hdr.size = htons (sizeof (struct GNUNET_MessageHeader) + data_length); if ( (GNUNET_OK != @@ -204,7 +210,8 @@ write_message (uint16_t message_type, * the scan. Does NOT yet add any metadata. * * @param filename file or directory to scan - * @param dst where to store the resulting share tree item + * @param dst where to store the resulting share tree item; + * NULL is stored in 'dst' upon recoverable errors (GNUNET_OK is returned) * @return GNUNET_OK on success, GNUNET_SYSERR on error */ static int @@ -252,6 +259,8 @@ scan_callback (void *cls, rc->stop = GNUNET_YES; return GNUNET_SYSERR; } + if (NULL == chld) + return GNUNET_OK; chld->parent = rc->parent; GNUNET_CONTAINER_DLL_insert (rc->parent->children_head, rc->parent->children_tail, @@ -266,7 +275,8 @@ scan_callback (void *cls, * the scan. Does NOT yet add any metadata. * * @param filename file or directory to scan - * @param dst where to store the resulting share tree item + * @param dst where to store the resulting share tree item; + * NULL is stored in 'dst' upon recoverable errors (GNUNET_OK is returned) * @return GNUNET_OK on success, GNUNET_SYSERR on error */ static int @@ -275,8 +285,11 @@ preprocess_file (const char *filename, { struct ScanTreeNode *item; struct stat sbuf; + uint64_t fsize = 0; - if (0 != STAT (filename, &sbuf)) + if ((0 != STAT (filename, &sbuf)) || + ((!S_ISDIR (sbuf.st_mode)) && (GNUNET_OK != GNUNET_DISK_file_size ( + filename, &fsize, GNUNET_NO, GNUNET_YES)))) { /* If the file doesn't exist (or is not stat-able for any other reason) skip it (but report it), but do continue. */ @@ -284,6 +297,8 @@ preprocess_file (const char *filename, write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE, filename, strlen (filename) + 1)) return GNUNET_SYSERR; + /* recoverable error, store 'NULL' in *dst */ + *dst = NULL; return GNUNET_OK; } @@ -297,8 +312,8 @@ preprocess_file (const char *filename, item = GNUNET_malloc (sizeof (struct ScanTreeNode)); item->filename = GNUNET_strdup (filename); item->is_directory = (S_ISDIR (sbuf.st_mode)) ? GNUNET_YES : GNUNET_NO; - item->file_size = (uint64_t) sbuf.st_size; - if (item->is_directory == GNUNET_YES) + item->file_size = fsize; + if (GNUNET_YES == item->is_directory) { struct RecursionContext rc; @@ -307,7 +322,7 @@ preprocess_file (const char *filename, GNUNET_DISK_directory_scan (filename, &scan_callback, &rc); - if ( (rc.stop == GNUNET_YES) || + if ( (GNUNET_YES == rc.stop) || (GNUNET_OK != write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY, "..", 3)) ) @@ -334,7 +349,7 @@ extract_files (struct ScanTreeNode *item) ssize_t size; size_t slen; - if (item->is_directory == GNUNET_YES) + if (GNUNET_YES == item->is_directory) { /* for directories, we simply only descent, no extraction, no progress reporting */ @@ -369,8 +384,13 @@ extract_files (struct ScanTreeNode *item) memcpy (buf, item->filename, slen); size = GNUNET_CONTAINER_meta_data_serialize (meta, - &dst, size - slen, + &dst, size, GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); + if (size < 0) + { + GNUNET_break (0); + size = 0; + } GNUNET_CONTAINER_meta_data_destroy (meta); if (GNUNET_OK != write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA, @@ -407,7 +427,7 @@ int main(int argc, #endif /* parse command line */ - if ( (argc != 3) && (argc != 2) ) + if ( (3 != argc) && (2 != argc) ) { FPRINTF (stderr, "%s", @@ -416,7 +436,7 @@ int main(int argc, } filename_expanded = argv[1]; ex = argv[2]; - if ( (ex == NULL) || + if ( (NULL == ex) || (0 != strcmp (ex, "-")) ) { plugins = EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY); @@ -437,14 +457,17 @@ int main(int argc, if (GNUNET_OK != write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE, NULL, 0)) return 3; - if (GNUNET_OK != - extract_files (root)) + if (NULL != root) { - (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0); + if (GNUNET_OK != + extract_files (root)) + { + (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0); + free_tree (root); + return 4; + } free_tree (root); - return 4; } - free_tree (root); /* enable "clean" shutdown by telling parent that we are done */ (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED, NULL, 0); if (NULL != plugins) diff --git a/src/fs/gnunet-pseudonym.c b/src/fs/gnunet-pseudonym.c index 412ddd2..38826d1 100644 --- a/src/fs/gnunet-pseudonym.c +++ b/src/fs/gnunet-pseudonym.c @@ -106,20 +106,29 @@ ns_printer (void *cls, const char *name, const GNUNET_HashCode * id) static int pseudo_printer (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { char *id; - - id = GNUNET_PSEUDONYM_id_to_name (cfg, pseudonym); - if (id == NULL) + char *unique_id; + int getinfo_result; + + /* While we get a name from the caller, it might be NULL. + * GNUNET_PSEUDONYM_get_info () never returns NULL. + */ + getinfo_result = GNUNET_PSEUDONYM_get_info (cfg, pseudonym, + NULL, NULL, &id, NULL); + if (getinfo_result != GNUNET_OK) { GNUNET_break (0); return GNUNET_OK; } - FPRINTF (stdout, "%s (%d):\n", id, rating); + unique_id = GNUNET_PSEUDONYM_name_uniquify (cfg, pseudonym, id, NULL); + GNUNET_free (id); + FPRINTF (stdout, "%s (%d):\n", unique_id, rating); GNUNET_CONTAINER_meta_data_iterate (md, &EXTRACTOR_meta_data_print, stdout); FPRINTF (stdout, "%s", "\n"); - GNUNET_free (id); + GNUNET_free (unique_id); return GNUNET_OK; } @@ -162,7 +171,8 @@ post_advertising (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) } else { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Namespace `%s' unknown.\n"), + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + ("Namespace `%s' unknown. Make sure you specify its numeric suffix, if any.\n"), rating_change); } } diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c index 50f507d..a1b26db 100644 --- a/src/fs/gnunet-publish.c +++ b/src/fs/gnunet-publish.c @@ -291,6 +291,12 @@ publish_inspector (void *cls, struct GNUNET_FS_FileInformation *fi, } if (!do_disable_creation_time) GNUNET_CONTAINER_meta_data_add_publication_date (m); + if ( (disable_extractor) && + (NULL != *uri) ) + { + GNUNET_FS_uri_destroy (*uri); + *uri = NULL; + } if (extract_only) { fn = GNUNET_CONTAINER_meta_data_get_by_type (m, diff --git a/src/fs/gnunet-service-fs.h b/src/fs/gnunet-service-fs.h index 5ea73ee..0c796bf 100644 --- a/src/fs/gnunet-service-fs.h +++ b/src/fs/gnunet-service-fs.h @@ -129,7 +129,7 @@ struct GetMessage * Hashcodes of the file(s) we're looking for. * Details depend on the query type. */ - GNUNET_HashCode query GNUNET_PACKED; + GNUNET_HashCode query; /* this is followed by hash codes as specified in the "hash_bitmap"; * after that, an optional bloomfilter (with bits set for replies diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c index b563019..e452894 100644 --- a/src/fs/gnunet-service-fs_indexing.c +++ b/src/fs/gnunet-service-fs_indexing.c @@ -368,7 +368,7 @@ GNUNET_FS_handle_index_list_get (void *cls, struct GNUNET_SERVER_Client *client, { struct GNUNET_SERVER_TransmitContext *tc; struct IndexInfoMessage *iim; - char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; + char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; size_t slen; const char *fn; struct IndexInfo *pos; diff --git a/src/fs/gnunet-service-fs_lc.c b/src/fs/gnunet-service-fs_lc.c index 36aafdd..20d430e 100644 --- a/src/fs/gnunet-service-fs_lc.c +++ b/src/fs/gnunet-service-fs_lc.c @@ -140,7 +140,7 @@ struct GSF_LocalClient /** * Context for sending replies. */ - struct GNUNET_CONNECTION_TransmitHandle *th; + struct GNUNET_SERVER_TransmitHandle *th; }; @@ -259,7 +259,7 @@ client_response_handler (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, lc = cr->lc; msize = sizeof (struct ClientPutMessage) + data_len; { - char buf[msize]; + char buf[msize] GNUNET_ALIGN; pm = (struct ClientPutMessage *) buf; pm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_PUT); @@ -498,7 +498,7 @@ GSF_client_disconnect_handler_ (void *cls, struct GNUNET_SERVER_Client *client) } if (pos->th != NULL) { - GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->th); + GNUNET_SERVER_notify_transmit_ready_cancel (pos->th); pos->th = NULL; } GSF_handle_local_client_disconnect_ (pos); diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c index d4b4481..8ca4121 100644 --- a/src/fs/gnunet-service-fs_pr.c +++ b/src/fs/gnunet-service-fs_pr.c @@ -1057,7 +1057,7 @@ GSF_dht_lookup_ (struct GSF_PendingRequest *pr) const void *xquery; size_t xquery_size; struct GNUNET_PeerIdentity pi; - char buf[sizeof (GNUNET_HashCode) * 2]; + char buf[sizeof (GNUNET_HashCode) * 2] GNUNET_ALIGN; if (0 != pr->public_data.anonymity_level) return; @@ -1082,7 +1082,7 @@ GSF_dht_lookup_ (struct GSF_PendingRequest *pr) xquery_size += sizeof (struct GNUNET_PeerIdentity); } pr->gh = - GNUNET_DHT_get_start (GSF_dht, GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_DHT_get_start (GSF_dht, pr->public_data.type, &pr->public_data.query, 5 /* DEFAULT_GET_REPLICATION */ , GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, diff --git a/src/fs/gnunet-service-fs_put.c b/src/fs/gnunet-service-fs_put.c index 3ac6713..463acc0 100644 --- a/src/fs/gnunet-service-fs_put.c +++ b/src/fs/gnunet-service-fs_put.c @@ -33,6 +33,11 @@ */ #define MAX_DHT_PUT_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) +/** + * How many replicas do we try to create per PUT? + */ +#define DEFAULT_PUT_REPLICATION 5 + /** * Context for each zero-anonymity iterator. @@ -50,6 +55,11 @@ struct PutOperator */ enum GNUNET_BLOCK_Type dht_put_type; + /** + * Handle to PUT operation. + */ + struct GNUNET_DHT_PutHandle *dht_put; + /** * ID of task that collects blocks for DHT PUTs. */ @@ -92,20 +102,15 @@ gather_dht_put_blocks (void *cls, /** - * Task that is run periodically to obtain blocks for DHT PUTs. + * Calculate when to run the next PUT operation and schedule it. * - * @param cls type of blocks to gather - * @param tc scheduler context (unused) + * @param po put operator to schedule */ static void -delay_dht_put_blocks (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +schedule_next_put (struct PutOperator *po) { - struct PutOperator *po = cls; struct GNUNET_TIME_Relative delay; - po->dht_task = GNUNET_SCHEDULER_NO_TASK; - if (tc != NULL && 0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - return; if (po->zero_anonymity_count_estimate > 0) { delay = @@ -124,6 +129,42 @@ delay_dht_put_blocks (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } +/** + * Continuation called after DHT PUT operation has finished. + * + * @param cls type of blocks to gather + * @param success GNUNET_OK if the PUT was transmitted, + * GNUNET_NO on timeout, + * GNUNET_SYSERR on disconnect from service + * after the PUT message was transmitted + * (so we don't know if it was received or not) + */ +static void +delay_dht_put_blocks (void *cls, int success) +{ + struct PutOperator *po = cls; + + po->dht_put = NULL; + schedule_next_put (po); +} + + +/** + * Task that is run periodically to obtain blocks for DHT PUTs. + * + * @param cls type of blocks to gather + * @param tc scheduler context + */ +static void +delay_dht_put_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PutOperator *po = cls; + + po->dht_task = GNUNET_SCHEDULER_NO_TASK; + schedule_next_put (po); +} + + /** * Store content in DHT. * @@ -151,7 +192,7 @@ process_dht_put_content (void *cls, const GNUNET_HashCode * key, size_t size, { po->zero_anonymity_count_estimate = po->current_offset - 1; po->current_offset = 0; - po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_blocks, po); + po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po); return; } po->zero_anonymity_count_estimate = @@ -159,10 +200,10 @@ process_dht_put_content (void *cls, const GNUNET_HashCode * key, size_t size, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Retrieved block `%s' of type %u for DHT PUT\n", GNUNET_h2s (key), type); - GNUNET_DHT_put (GSF_dht, key, 5 /* DEFAULT_PUT_REPLICATION */ , - GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, type, size, data, - expiration, GNUNET_TIME_UNIT_FOREVER_REL, - &delay_dht_put_blocks, po); + po->dht_put = GNUNET_DHT_put (GSF_dht, key, DEFAULT_PUT_REPLICATION, + GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, type, size, data, + expiration, GNUNET_TIME_UNIT_FOREVER_REL, + &delay_dht_put_blocks, po); } @@ -187,7 +228,7 @@ gather_dht_put_blocks (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) po->dht_put_type, &process_dht_put_content, po); if (NULL == po->dht_qe) - po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_blocks, po); + po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po); } @@ -226,6 +267,11 @@ GSF_put_done_ () GNUNET_SCHEDULER_cancel (po->dht_task); po->dht_task = GNUNET_SCHEDULER_NO_TASK; } + if (NULL != po->dht_put) + { + GNUNET_DHT_put_cancel (po->dht_put); + po->dht_put = NULL; + } if (NULL != po->dht_qe) { GNUNET_DATASTORE_cancel (po->dht_qe); diff --git a/src/fs/perf_gnunet_service_fs_p2p.c b/src/fs/perf_gnunet_service_fs_p2p.c index 32dcffa..7b2c044 100644 --- a/src/fs/perf_gnunet_service_fs_p2p.c +++ b/src/fs/perf_gnunet_service_fs_p2p.c @@ -191,7 +191,7 @@ do_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) char *fancy; struct StatMaster *sm; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) + if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { del = GNUNET_TIME_absolute_get_duration (start_time); if (del.rel_value == 0) diff --git a/src/fs/test_fs_defaults.conf b/src/fs/test_fs_defaults.conf index 2bc3d26..fcb888c 100644 --- a/src/fs/test_fs_defaults.conf +++ b/src/fs/test_fs_defaults.conf @@ -85,3 +85,6 @@ AUTOSTART = NO [vpn] AUTOSTART = NO + +[namestore] +AUTOSTART = NO diff --git a/src/fs/test_fs_download.c b/src/fs/test_fs_download.c index 570eab9..2781974 100644 --- a/src/fs/test_fs_download.c +++ b/src/fs/test_fs_download.c @@ -118,7 +118,7 @@ abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_FS_download_stop (download, GNUNET_YES); download = NULL; } - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES)); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES, GNUNET_NO)); GNUNET_assert (size == FILESIZE); GNUNET_DISK_directory_remove (fn); GNUNET_free (fn); @@ -268,7 +268,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_download_indexed.c b/src/fs/test_fs_download_indexed.c index e8504f1..d16aa97 100644 --- a/src/fs/test_fs_download_indexed.c +++ b/src/fs/test_fs_download_indexed.c @@ -42,7 +42,7 @@ /** * How long until we give up on transmitting the message? */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) /** * How long should our test-content live? @@ -75,9 +75,11 @@ static char *fn1; static int err; + static void timeout_kill_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + fprintf (stderr, "Download not fast enough, timeout!\n"); if (download != NULL) { GNUNET_FS_download_stop (download, GNUNET_YES); @@ -102,6 +104,7 @@ abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } } + static void stop_fs_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -109,6 +112,7 @@ stop_fs_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) fs = NULL; } + static void abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -119,7 +123,7 @@ abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_FS_download_stop (download, GNUNET_YES); download = NULL; } - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES)); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES, GNUNET_NO)); GNUNET_assert (size == FILESIZE); GNUNET_DISK_directory_remove (fn); GNUNET_free (fn); @@ -248,9 +252,6 @@ setup_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); @@ -269,7 +270,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif @@ -335,9 +336,6 @@ main (int argc, char *argv[]) "test-fs-download-indexed", "-c", "test_fs_download_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -345,11 +343,7 @@ main (int argc, char *argv[]) }; GNUNET_log_setup ("test_fs_download_indexed", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, "test-fs-download-indexed", "nohelp", options, &run, diff --git a/src/fs/test_fs_download_persistence.c b/src/fs/test_fs_download_persistence.c index bcb1c54..ba776dd 100644 --- a/src/fs/test_fs_download_persistence.c +++ b/src/fs/test_fs_download_persistence.c @@ -113,7 +113,7 @@ abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_FS_download_stop (download, GNUNET_YES); download = NULL; } - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES)); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES, GNUNET_NO)); GNUNET_assert (size == FILESIZE); GNUNET_DISK_directory_remove (fn); GNUNET_free (fn); @@ -318,7 +318,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_list_indexed.c b/src/fs/test_fs_list_indexed.c index 535f8ef..d046a20 100644 --- a/src/fs/test_fs_list_indexed.c +++ b/src/fs/test_fs_list_indexed.c @@ -211,7 +211,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_namespace.c b/src/fs/test_fs_namespace.c index d25fd6f..78af1f1 100644 --- a/src/fs/test_fs_namespace.c +++ b/src/fs/test_fs_namespace.c @@ -69,9 +69,6 @@ setup_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); @@ -90,7 +87,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif @@ -261,6 +258,13 @@ sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) char *msg; struct GNUNET_FS_BlockOptions bo; + if (NULL == uri) + { + fprintf (stderr, "Error publishing: %s\n", emsg); + err = 1; + GNUNET_FS_stop (fs); + return; + } meta = GNUNET_CONTAINER_meta_data_create (); msg = NULL; ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg); @@ -378,9 +382,6 @@ main (int argc, char *argv[]) "test-fs-namespace", "-c", "test_fs_namespace_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -388,11 +389,7 @@ main (int argc, char *argv[]) }; GNUNET_log_setup ("test_fs_namespace", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, "test-fs-namespace", "nohelp", options, &run, NULL); diff --git a/src/fs/test_fs_namespace_list_updateable.c b/src/fs/test_fs_namespace_list_updateable.c index 44775ac..2cec67d 100644 --- a/src/fs/test_fs_namespace_list_updateable.c +++ b/src/fs/test_fs_namespace_list_updateable.c @@ -94,7 +94,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_publish.c b/src/fs/test_fs_publish.c index e527438..1560f4e 100644 --- a/src/fs/test_fs_publish.c +++ b/src/fs/test_fs_publish.c @@ -196,7 +196,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_publish_persistence.c b/src/fs/test_fs_publish_persistence.c index 7707eac..7d3bc32 100644 --- a/src/fs/test_fs_publish_persistence.c +++ b/src/fs/test_fs_publish_persistence.c @@ -259,7 +259,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_search.c b/src/fs/test_fs_search.c index f6c8f00..04c5897 100644 --- a/src/fs/test_fs_search.c +++ b/src/fs/test_fs_search.c @@ -176,9 +176,6 @@ setup_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); @@ -197,7 +194,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif @@ -254,9 +251,6 @@ main (int argc, char *argv[]) "test-fs-search", "-c", "test_fs_search_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -264,11 +258,7 @@ main (int argc, char *argv[]) }; GNUNET_log_setup ("test_fs_search", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, "test-fs-search", "nohelp", options, &run, NULL); diff --git a/src/fs/test_fs_search_persistence.c b/src/fs/test_fs_search_persistence.c index 38f88a8..d18b50e 100644 --- a/src/fs/test_fs_search_persistence.c +++ b/src/fs/test_fs_search_persistence.c @@ -259,7 +259,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_search_probes.c b/src/fs/test_fs_search_probes.c new file mode 100644 index 0000000..b816598 --- /dev/null +++ b/src/fs/test_fs_search_probes.c @@ -0,0 +1,268 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file fs/test_fs_search_probes.c + * @brief simple testcase for publish + search operation with probes + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_arm_service.h" +#include "gnunet_fs_service.h" + +#define START_ARM GNUNET_YES + +/** + * File-size we use for testing. + */ +#define FILESIZE 1024 + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) + +/** + * How long should our test-content live? + */ +#define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) + +struct PeerContext +{ + struct GNUNET_CONFIGURATION_Handle *cfg; + struct GNUNET_PeerIdentity id; +#if START_ARM + struct GNUNET_OS_Process *arm_proc; +#endif +}; + +static struct PeerContext p1; + +static struct GNUNET_TIME_Absolute start; + +static struct GNUNET_FS_Handle *fs; + +static struct GNUNET_FS_SearchContext *search; + +static struct GNUNET_FS_PublishContext *publish; + + +static void +abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_FS_publish_stop (publish); + publish = NULL; +} + + +static void +abort_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (search != NULL) + GNUNET_FS_search_stop (search); + search = NULL; +} + + +static void * +progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) +{ + const char *keywords[] = { + "down_foo" + }; + struct GNUNET_FS_Uri *kuri; + + switch (event->status) + { + case GNUNET_FS_STATUS_PUBLISH_PROGRESS: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Publish is progressing (%llu/%llu at level %u off %llu)...\n", + (unsigned long long) event->value.publish.completed, + (unsigned long long) event->value.publish.size, + event->value.publish.specifics.progress.depth, + (unsigned long long) event->value.publish.specifics. + progress.offset); + break; + case GNUNET_FS_STATUS_PUBLISH_COMPLETED: + kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords); + start = GNUNET_TIME_absolute_get (); + search = + GNUNET_FS_search_start (fs, kuri, 1, GNUNET_FS_SEARCH_OPTION_NONE, + "search"); + GNUNET_FS_uri_destroy (kuri); + GNUNET_assert (search != NULL); + break; + case GNUNET_FS_STATUS_SEARCH_RESULT: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Search complete.\n"); + break; + case GNUNET_FS_STATUS_PUBLISH_ERROR: + FPRINTF (stderr, "Error publishing file: %s\n", + event->value.publish.specifics.error.message); + GNUNET_break (0); + GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + break; + case GNUNET_FS_STATUS_SEARCH_ERROR: + FPRINTF (stderr, "Error searching file: %s\n", + event->value.search.specifics.error.message); + GNUNET_SCHEDULER_add_continuation (&abort_search_task, NULL, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + break; + case GNUNET_FS_STATUS_PUBLISH_START: + GNUNET_assert (0 == strcmp ("publish-context", event->value.publish.cctx)); + GNUNET_assert (NULL == event->value.publish.pctx); + GNUNET_assert (FILESIZE == event->value.publish.size); + GNUNET_assert (0 == event->value.publish.completed); + GNUNET_assert (1 == event->value.publish.anonymity); + break; + case GNUNET_FS_STATUS_PUBLISH_STOPPED: + GNUNET_assert (publish == event->value.publish.pc); + GNUNET_assert (FILESIZE == event->value.publish.size); + GNUNET_assert (1 == event->value.publish.anonymity); + GNUNET_FS_stop (fs); + fs = NULL; + break; + case GNUNET_FS_STATUS_SEARCH_UPDATE: + GNUNET_assert (0 < event->value.search.specifics.update.availability_rank); + GNUNET_assert (0 < event->value.search.specifics.update.availability_certainty); + GNUNET_SCHEDULER_add_now (&abort_search_task, NULL); + break; + case GNUNET_FS_STATUS_SEARCH_START: + GNUNET_assert (search == NULL); + GNUNET_assert (0 == strcmp ("search", event->value.search.cctx)); + GNUNET_assert (1 == event->value.search.anonymity); + break; + case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED: + break; + case GNUNET_FS_STATUS_SEARCH_STOPPED: + GNUNET_assert (search == event->value.search.sc); + GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + break; + default: + FPRINTF (stderr, "Unexpected event: %d\n", event->status); + break; + } + return NULL; +} + + +static void +setup_peer (struct PeerContext *p, const char *cfgname) +{ + p->cfg = GNUNET_CONFIGURATION_create (); +#if START_ARM + p->arm_proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", + "-c", cfgname, NULL); +#endif + GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); +} + + +static void +stop_arm (struct PeerContext *p) +{ +#if START_ARM + if (NULL != p->arm_proc) + { + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", + GNUNET_OS_process_get_pid (p->arm_proc)); + GNUNET_OS_process_destroy (p->arm_proc); + p->arm_proc = NULL; + } +#endif + GNUNET_CONFIGURATION_destroy (p->cfg); +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + const char *keywords[] = { + "down_foo", + "down_bar" + }; + char *buf; + struct GNUNET_CONTAINER_MetaData *meta; + struct GNUNET_FS_Uri *kuri; + struct GNUNET_FS_BlockOptions bo; + struct GNUNET_FS_FileInformation *fi; + size_t i; + + setup_peer (&p1, "test_fs_search_data.conf"); + fs = GNUNET_FS_start (cfg, "test-fs-search", &progress_cb, NULL, + GNUNET_FS_FLAGS_DO_PROBES, + GNUNET_FS_OPTIONS_END); + GNUNET_assert (NULL != fs); + buf = GNUNET_malloc (FILESIZE); + for (i = 0; i < FILESIZE; i++) + buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256); + meta = GNUNET_CONTAINER_meta_data_create (); + kuri = GNUNET_FS_uri_ksk_create_from_args (2, keywords); + bo.content_priority = 42; + bo.anonymity_level = 1; + bo.replication_level = 0; + bo.expiration_time = GNUNET_TIME_relative_to_absolute (LIFETIME); + fi = GNUNET_FS_file_information_create_from_data (fs, "publish-context", + FILESIZE, buf, kuri, meta, + GNUNET_NO, &bo); + GNUNET_FS_uri_destroy (kuri); + GNUNET_CONTAINER_meta_data_destroy (meta); + GNUNET_assert (NULL != fi); + start = GNUNET_TIME_absolute_get (); + publish = + GNUNET_FS_publish_start (fs, fi, NULL, NULL, NULL, + GNUNET_FS_PUBLISH_OPTION_NONE); + GNUNET_assert (publish != NULL); +} + + +int +main (int argc, char *argv[]) +{ + char *const argvx[] = { + "test-fs-search-probes", + "-c", + "test_fs_search_data.conf", + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_log_setup ("test_fs_search_probes", + "WARNING", + NULL); + GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, + "test-fs-search", "nohelp", options, &run, NULL); + stop_arm (&p1); + GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-search/"); + return 0; +} + +/* end of test_fs_search_probes.c */ diff --git a/src/fs/test_fs_start_stop.c b/src/fs/test_fs_start_stop.c index 0ef0723..6bd698a 100644 --- a/src/fs/test_fs_start_stop.c +++ b/src/fs/test_fs_start_stop.c @@ -80,7 +80,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_test_lib.c b/src/fs/test_fs_test_lib.c index 589abb3..29d5fe4 100644 --- a/src/fs/test_fs_test_lib.c +++ b/src/fs/test_fs_test_lib.c @@ -138,9 +138,6 @@ main (int argc, char *argv[]) "test-fs-test-lib", "-c", "fs_test_lib_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -149,11 +146,7 @@ main (int argc, char *argv[]) GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); GNUNET_log_setup ("test_fs_test_lib", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, "test-fs-test-lib", "nohelp", options, &run, NULL); diff --git a/src/fs/test_fs_unindex.c b/src/fs/test_fs_unindex.c index a8b68a3..ee76bf9 100644 --- a/src/fs/test_fs_unindex.c +++ b/src/fs/test_fs_unindex.c @@ -210,7 +210,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_fs_unindex_persistence.c b/src/fs/test_fs_unindex_persistence.c index 575e171..c6b1062 100644 --- a/src/fs/test_fs_unindex_persistence.c +++ b/src/fs/test_fs_unindex_persistence.c @@ -272,7 +272,7 @@ stop_arm (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif diff --git a/src/fs/test_gnunet_fs_idx.py.in b/src/fs/test_gnunet_fs_idx.py.in old mode 100755 new mode 100644 diff --git a/src/fs/test_gnunet_fs_ns.py.in b/src/fs/test_gnunet_fs_ns.py.in old mode 100755 new mode 100644 diff --git a/src/fs/test_gnunet_fs_psd.py.in b/src/fs/test_gnunet_fs_psd.py.in old mode 100755 new mode 100644 diff --git a/src/fs/test_gnunet_fs_rec.py.in b/src/fs/test_gnunet_fs_rec.py.in old mode 100755 new mode 100644 diff --git a/src/fs/test_gnunet_service_fs_migration.c b/src/fs/test_gnunet_service_fs_migration.c index 8b85e5e..00aab4f 100644 --- a/src/fs/test_gnunet_service_fs_migration.c +++ b/src/fs/test_gnunet_service_fs_migration.c @@ -66,7 +66,7 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) cc = NULL; } GNUNET_FS_TEST_daemons_stop (2, daemons); - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) + if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { del = GNUNET_TIME_absolute_get_duration (start_time); if (del.rel_value == 0) @@ -146,7 +146,7 @@ static void do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { cc = NULL; - if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { GNUNET_FS_TEST_daemons_stop (2, daemons); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, diff --git a/src/fs/test_gnunet_service_fs_p2p.c b/src/fs/test_gnunet_service_fs_p2p.c index a853897..7ca786e 100644 --- a/src/fs/test_gnunet_service_fs_p2p.c +++ b/src/fs/test_gnunet_service_fs_p2p.c @@ -62,7 +62,7 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) cc = NULL; } GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) + if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { del = GNUNET_TIME_absolute_get_duration (start_time); if (del.rel_value == 0) diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index cc19939..10b9ff3 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am @@ -1,5 +1,11 @@ INCLUDES = -I$(top_srcdir)/src/include +if HAVE_GLIBCNSS +NSS_SUBDIR = nss +endif + +SUBDIRS = . $(NSS_SUBDIR) + if MINGW WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols endif @@ -16,98 +22,272 @@ pkgcfg_DATA = \ gns.conf lib_LTLIBRARIES = \ - libgnunetgns.la libgnunetnamestore.la + libgnunetgns.la + +if HAVE_MHD + DO_FCFSD=gnunet-gns-fcfsd + DO_PROXY=gnunet-gns-proxy +endif bin_PROGRAMS = \ - gnunet-service-gns + gnunet-service-gns \ + $(DO_FCFSD) \ + $(DO_PROXY) \ + gnunet-gns #noinst_PROGRAMS = \ # gnunet-gns-lookup -check_SCRIPTS = \ - test_gnunet_gns.sh - check_PROGRAMS = \ - test_gns_twopeer + test_gns_simple_shorten \ + test_gns_simple_get_authority \ + test_gns_simple_lookup \ + test_gns_simple_delegated_lookup \ + test_gns_simple_mx_lookup \ + test_gns_simple_zkey_lookup \ + test_gns_dht_delegated_lookup \ + test_gns_pseu_shorten \ + test_gns_max_queries \ + test_gns_dht_threepeer + + +# test_gns_simple_lookup +# test_gns_simple_delegated_lookup +# test_gns_dht_delegated_lookup plugin_LTLIBRARIES = \ libgnunet_plugin_block_gns.la -test_gns_twopeer_SOURCES = \ - test_gns_twopeer.c -test_gns_twopeer_LDADD = \ +test_gns_dht_threepeer_SOURCES = \ + test_gns_dht_threepeer.c +test_gns_dht_threepeer_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_dht_threepeer_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_lookup_SOURCES = \ + test_gns_simple_lookup.c +test_gns_simple_lookup_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ $(top_builddir)/src/testing/libgnunettesting.la -test_gns_twopeer_DEPENDENCIES = \ +test_gns_simple_lookup_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ $(top_builddir)/src/testing/libgnunettesting.la -#gnunet_gns_lookup_SOURCES = \ -# gnunet-gns-lookup.c -#gnunet_gns_lookup_LDADD = \ -# $(top_builddir)/src/gns/libgnunetgns.la \ -# $(top_builddir)/src/util/libgnunetutil.la \ -# $(GN_LIBINTL) -#gnunet_dns_lookup_DEPENDENCIES = \ -# libgnunetgns.la +test_gns_simple_delegated_lookup_SOURCES = \ + test_gns_simple_delegated_lookup.c +test_gns_simple_delegated_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_simple_delegated_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_mx_lookup_SOURCES = \ + test_gns_simple_mx_lookup.c +test_gns_simple_mx_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_simple_mx_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_zkey_lookup_SOURCES = \ + test_gns_simple_zkey_lookup.c +test_gns_simple_zkey_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_simple_zkey_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_dht_delegated_lookup_SOURCES = \ + test_gns_dht_delegated_lookup.c +test_gns_dht_delegated_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_dht_delegated_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_shorten_SOURCES = \ + test_gns_simple_shorten.c +test_gns_simple_shorten_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_simple_shorten_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_get_authority_SOURCES = \ + test_gns_simple_get_authority.c +test_gns_simple_get_authority_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_simple_get_authority_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + + +test_gns_pseu_shorten_SOURCES = \ + test_gns_pseu_shorten.c +test_gns_pseu_shorten_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_pseu_shorten_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + + +test_gns_max_queries_SOURCES = \ + test_gns_max_queries.c +test_gns_max_queries_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_max_queries_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +gnunet_gns_SOURCES = \ + gnunet-gns.c +gnunet_gns_LDADD = \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(GN_LIBINTL) +gnunet_gns_DEPENDENCIES = \ + libgnunetgns.la + +gnunet_gns_proxy_SOURCES = \ + gnunet-gns-proxy.c gns_proxy_proto.h +gnunet_gns_proxy_LDADD = -lmicrohttpd \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) +gnunet_gns_proxy_DEPENDENCIES = \ + libgnunetgns.la gnunet_service_gns_SOURCES = \ - gnunet-service-gns.c + gnunet-service-gns.c \ + gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \ + gnunet-service-gns_interceptor.c gnunet-service-gns_interceptor.h gnunet_service_gns_LDADD = \ - $(top_builddir)/src/tun/libgnunettun.la \ - $(top_builddir)/src/mesh/libgnunetmesh.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/dns/libgnunetdns.la \ $(top_builddir)/src/dns/libgnunetdnsparser.la \ $(top_builddir)/src/dht/libgnunetdht.la \ - $(top_builddir)/src/gns/libgnunetnamestore.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ $(GN_LIBINTL) gnunet_service_gns_DEPENDENCIES = \ - $(top_builddir)/src/tun/libgnunettun.la \ - $(top_builddir)/src/mesh/libgnunetmesh.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/dns/libgnunetdns.la \ $(top_builddir)/src/dns/libgnunetdnsparser.la \ $(top_builddir)/src/dht/libgnunetdht.la \ - $(top_builddir)/src/gns/libgnunetnamestore.la + $(top_builddir)/src/namestore/libgnunetnamestore.la + + +gnunet_gns_fcfsd_SOURCES = \ + gnunet-gns-fcfsd.c +gnunet_gns_fcfsd_LDADD = -lmicrohttpd \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(GN_LIBINTL) +gnunet_gns_fcfsd_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + libgnunetgns_la_SOURCES = \ gns_api.c gns.h libgnunetgns_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la $(XLIB) + $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \ + $(top_builddir)/src/namestore/libgnunetnamestore.la libgnunetgns_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) libgnunetgns_la_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la libgnunet_plugin_block_gns_la_SOURCES = \ plugin_block_gns.c libgnunet_plugin_block_gns_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/block/libgnunetblock.la + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la libgnunet_plugin_block_gns_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) libgnunet_plugin_block_gns_la_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/block/libgnunetblock.la + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la #Build stub api -libgnunetnamestore_la_SOURCES = \ - namestore_stub_api.c -libgnunetnamestore_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la $(XLIB) -libgnunetnamestore_la_LDFLAGS = \ - $(GN_LIB_LDFLAGS) -libgnunetnamestore_la_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la +#libgnunetnamestore_la_SOURCES = \ +# namestore_stub_api.c +#libgnunetnamestore_la_LIBADD = \ +# $(top_builddir)/src/util/libgnunetutil.la $(XLIB) +#libgnunetnamestore_la_LDFLAGS = \ +# $(GN_LIB_LDFLAGS) +#libgnunetnamestore_la_DEPENDENCIES = \ +# $(top_builddir)/src/util/libgnunetutil.la if ENABLE_TEST_RUN -TESTS = $(check_PROGRAMS) $(check_SCRIPTS) +if LINUX +TESTS = $(check_PROGRAMS) +endif endif EXTRA_DIST = \ - $(check_SCRIPTS) \ - test_gns_twopeer.conf + test_gns_defaults.conf \ + test_gns_simple_lookup.conf \ + test_gns_dht_default.conf + diff --git a/src/gns/Makefile.in b/src/gns/Makefile.in index 87422ab..5bdd92a 100644 --- a/src/gns/Makefile.in +++ b/src/gns/Makefile.in @@ -37,8 +37,17 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -bin_PROGRAMS = gnunet-service-gns$(EXEEXT) -check_PROGRAMS = test_gns_twopeer$(EXEEXT) +bin_PROGRAMS = gnunet-service-gns$(EXEEXT) $(am__EXEEXT_1) \ + $(am__EXEEXT_2) gnunet-gns$(EXEEXT) +check_PROGRAMS = test_gns_simple_shorten$(EXEEXT) \ + test_gns_simple_get_authority$(EXEEXT) \ + test_gns_simple_lookup$(EXEEXT) \ + test_gns_simple_delegated_lookup$(EXEEXT) \ + test_gns_simple_mx_lookup$(EXEEXT) \ + test_gns_simple_zkey_lookup$(EXEEXT) \ + test_gns_dht_delegated_lookup$(EXEEXT) \ + test_gns_pseu_shorten$(EXEEXT) test_gns_max_queries$(EXEEXT) \ + test_gns_dht_threepeer$(EXEEXT) subdir = src/gns DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/gns.conf.in @@ -101,18 +110,52 @@ libgnunetgns_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunetgns_la_LDFLAGS) $(LDFLAGS) \ -o $@ -am_libgnunetnamestore_la_OBJECTS = namestore_stub_api.lo -libgnunetnamestore_la_OBJECTS = $(am_libgnunetnamestore_la_OBJECTS) -libgnunetnamestore_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libgnunetnamestore_la_LDFLAGS) \ - $(LDFLAGS) -o $@ +@HAVE_MHD_TRUE@am__EXEEXT_1 = gnunet-gns-fcfsd$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_2 = gnunet-gns-proxy$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) -am_gnunet_service_gns_OBJECTS = gnunet-service-gns.$(OBJEXT) -gnunet_service_gns_OBJECTS = $(am_gnunet_service_gns_OBJECTS) +am_gnunet_gns_OBJECTS = gnunet-gns.$(OBJEXT) +gnunet_gns_OBJECTS = $(am_gnunet_gns_OBJECTS) am__DEPENDENCIES_1 = -am_test_gns_twopeer_OBJECTS = test_gns_twopeer.$(OBJEXT) -test_gns_twopeer_OBJECTS = $(am_test_gns_twopeer_OBJECTS) +am_gnunet_gns_fcfsd_OBJECTS = gnunet-gns-fcfsd.$(OBJEXT) +gnunet_gns_fcfsd_OBJECTS = $(am_gnunet_gns_fcfsd_OBJECTS) +am_gnunet_gns_proxy_OBJECTS = gnunet-gns-proxy.$(OBJEXT) +gnunet_gns_proxy_OBJECTS = $(am_gnunet_gns_proxy_OBJECTS) +am_gnunet_service_gns_OBJECTS = gnunet-service-gns.$(OBJEXT) \ + gnunet-service-gns_resolver.$(OBJEXT) \ + gnunet-service-gns_interceptor.$(OBJEXT) +gnunet_service_gns_OBJECTS = $(am_gnunet_service_gns_OBJECTS) +am_test_gns_dht_delegated_lookup_OBJECTS = \ + test_gns_dht_delegated_lookup.$(OBJEXT) +test_gns_dht_delegated_lookup_OBJECTS = \ + $(am_test_gns_dht_delegated_lookup_OBJECTS) +am_test_gns_dht_threepeer_OBJECTS = test_gns_dht_threepeer.$(OBJEXT) +test_gns_dht_threepeer_OBJECTS = $(am_test_gns_dht_threepeer_OBJECTS) +am_test_gns_max_queries_OBJECTS = test_gns_max_queries.$(OBJEXT) +test_gns_max_queries_OBJECTS = $(am_test_gns_max_queries_OBJECTS) +am_test_gns_pseu_shorten_OBJECTS = test_gns_pseu_shorten.$(OBJEXT) +test_gns_pseu_shorten_OBJECTS = $(am_test_gns_pseu_shorten_OBJECTS) +am_test_gns_simple_delegated_lookup_OBJECTS = \ + test_gns_simple_delegated_lookup.$(OBJEXT) +test_gns_simple_delegated_lookup_OBJECTS = \ + $(am_test_gns_simple_delegated_lookup_OBJECTS) +am_test_gns_simple_get_authority_OBJECTS = \ + test_gns_simple_get_authority.$(OBJEXT) +test_gns_simple_get_authority_OBJECTS = \ + $(am_test_gns_simple_get_authority_OBJECTS) +am_test_gns_simple_lookup_OBJECTS = test_gns_simple_lookup.$(OBJEXT) +test_gns_simple_lookup_OBJECTS = $(am_test_gns_simple_lookup_OBJECTS) +am_test_gns_simple_mx_lookup_OBJECTS = \ + test_gns_simple_mx_lookup.$(OBJEXT) +test_gns_simple_mx_lookup_OBJECTS = \ + $(am_test_gns_simple_mx_lookup_OBJECTS) +am_test_gns_simple_shorten_OBJECTS = \ + test_gns_simple_shorten.$(OBJEXT) +test_gns_simple_shorten_OBJECTS = \ + $(am_test_gns_simple_shorten_OBJECTS) +am_test_gns_simple_zkey_lookup_OBJECTS = \ + test_gns_simple_zkey_lookup.$(OBJEXT) +test_gns_simple_zkey_lookup_OBJECTS = \ + $(am_test_gns_simple_zkey_lookup_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -140,17 +183,77 @@ AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgnunet_plugin_block_gns_la_SOURCES) \ - $(libgnunetgns_la_SOURCES) $(libgnunetnamestore_la_SOURCES) \ - $(gnunet_service_gns_SOURCES) $(test_gns_twopeer_SOURCES) + $(libgnunetgns_la_SOURCES) $(gnunet_gns_SOURCES) \ + $(gnunet_gns_fcfsd_SOURCES) $(gnunet_gns_proxy_SOURCES) \ + $(gnunet_service_gns_SOURCES) \ + $(test_gns_dht_delegated_lookup_SOURCES) \ + $(test_gns_dht_threepeer_SOURCES) \ + $(test_gns_max_queries_SOURCES) \ + $(test_gns_pseu_shorten_SOURCES) \ + $(test_gns_simple_delegated_lookup_SOURCES) \ + $(test_gns_simple_get_authority_SOURCES) \ + $(test_gns_simple_lookup_SOURCES) \ + $(test_gns_simple_mx_lookup_SOURCES) \ + $(test_gns_simple_shorten_SOURCES) \ + $(test_gns_simple_zkey_lookup_SOURCES) DIST_SOURCES = $(libgnunet_plugin_block_gns_la_SOURCES) \ - $(libgnunetgns_la_SOURCES) $(libgnunetnamestore_la_SOURCES) \ - $(gnunet_service_gns_SOURCES) $(test_gns_twopeer_SOURCES) + $(libgnunetgns_la_SOURCES) $(gnunet_gns_SOURCES) \ + $(gnunet_gns_fcfsd_SOURCES) $(gnunet_gns_proxy_SOURCES) \ + $(gnunet_service_gns_SOURCES) \ + $(test_gns_dht_delegated_lookup_SOURCES) \ + $(test_gns_dht_threepeer_SOURCES) \ + $(test_gns_max_queries_SOURCES) \ + $(test_gns_pseu_shorten_SOURCES) \ + $(test_gns_simple_delegated_lookup_SOURCES) \ + $(test_gns_simple_get_authority_SOURCES) \ + $(test_gns_simple_lookup_SOURCES) \ + $(test_gns_simple_mx_lookup_SOURCES) \ + $(test_gns_simple_shorten_SOURCES) \ + $(test_gns_simple_zkey_lookup_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive DATA = $(pkgcfg_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir ETAGS = etags CTAGS = ctags am__tty_colors = \ red=; grn=; lgn=; blu=; std= +DIST_SUBDIRS = . nss DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ @@ -206,6 +309,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -239,6 +343,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -356,6 +461,8 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = -I$(top_srcdir)/src/include +@HAVE_GLIBCNSS_TRUE@NSS_SUBDIR = nss +SUBDIRS = . $(NSS_SUBDIR) @MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols @USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0 pkgcfgdir = $(pkgdatadir)/config.d/ @@ -364,107 +471,275 @@ pkgcfg_DATA = \ gns.conf lib_LTLIBRARIES = \ - libgnunetgns.la libgnunetnamestore.la - + libgnunetgns.la -#noinst_PROGRAMS = \ -# gnunet-gns-lookup -check_SCRIPTS = \ - test_gnunet_gns.sh +@HAVE_MHD_TRUE@DO_FCFSD = gnunet-gns-fcfsd +@HAVE_MHD_TRUE@DO_PROXY = gnunet-gns-proxy +# test_gns_simple_lookup +# test_gns_simple_delegated_lookup +# test_gns_dht_delegated_lookup plugin_LTLIBRARIES = \ libgnunet_plugin_block_gns.la -test_gns_twopeer_SOURCES = \ - test_gns_twopeer.c +test_gns_dht_threepeer_SOURCES = \ + test_gns_dht_threepeer.c + +test_gns_dht_threepeer_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_dht_threepeer_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_lookup_SOURCES = \ + test_gns_simple_lookup.c + +test_gns_simple_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_delegated_lookup_SOURCES = \ + test_gns_simple_delegated_lookup.c + +test_gns_simple_delegated_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_delegated_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_mx_lookup_SOURCES = \ + test_gns_simple_mx_lookup.c + +test_gns_simple_mx_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_mx_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_zkey_lookup_SOURCES = \ + test_gns_simple_zkey_lookup.c + +test_gns_simple_zkey_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_zkey_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_dht_delegated_lookup_SOURCES = \ + test_gns_dht_delegated_lookup.c + +test_gns_dht_delegated_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_dht_delegated_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_shorten_SOURCES = \ + test_gns_simple_shorten.c + +test_gns_simple_shorten_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_shorten_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_simple_get_authority_SOURCES = \ + test_gns_simple_get_authority.c -test_gns_twopeer_LDADD = \ +test_gns_simple_get_authority_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ $(top_builddir)/src/testing/libgnunettesting.la -test_gns_twopeer_DEPENDENCIES = \ +test_gns_simple_get_authority_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ $(top_builddir)/src/testing/libgnunettesting.la +test_gns_pseu_shorten_SOURCES = \ + test_gns_pseu_shorten.c + +test_gns_pseu_shorten_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_pseu_shorten_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_max_queries_SOURCES = \ + test_gns_max_queries.c + +test_gns_max_queries_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_gns_max_queries_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +gnunet_gns_SOURCES = \ + gnunet-gns.c + +gnunet_gns_LDADD = \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(GN_LIBINTL) + +gnunet_gns_DEPENDENCIES = \ + libgnunetgns.la + +gnunet_gns_proxy_SOURCES = \ + gnunet-gns-proxy.c gns_proxy_proto.h + +gnunet_gns_proxy_LDADD = -lmicrohttpd \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) + +gnunet_gns_proxy_DEPENDENCIES = \ + libgnunetgns.la -#gnunet_gns_lookup_SOURCES = \ -# gnunet-gns-lookup.c -#gnunet_gns_lookup_LDADD = \ -# $(top_builddir)/src/gns/libgnunetgns.la \ -# $(top_builddir)/src/util/libgnunetutil.la \ -# $(GN_LIBINTL) -#gnunet_dns_lookup_DEPENDENCIES = \ -# libgnunetgns.la gnunet_service_gns_SOURCES = \ - gnunet-service-gns.c + gnunet-service-gns.c \ + gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \ + gnunet-service-gns_interceptor.c gnunet-service-gns_interceptor.h gnunet_service_gns_LDADD = \ - $(top_builddir)/src/tun/libgnunettun.la \ - $(top_builddir)/src/mesh/libgnunetmesh.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/dns/libgnunetdns.la \ $(top_builddir)/src/dns/libgnunetdnsparser.la \ $(top_builddir)/src/dht/libgnunetdht.la \ - $(top_builddir)/src/gns/libgnunetnamestore.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ $(GN_LIBINTL) gnunet_service_gns_DEPENDENCIES = \ - $(top_builddir)/src/tun/libgnunettun.la \ - $(top_builddir)/src/mesh/libgnunetmesh.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/dns/libgnunetdns.la \ $(top_builddir)/src/dns/libgnunetdnsparser.la \ $(top_builddir)/src/dht/libgnunetdht.la \ - $(top_builddir)/src/gns/libgnunetnamestore.la + $(top_builddir)/src/namestore/libgnunetnamestore.la + +gnunet_gns_fcfsd_SOURCES = \ + gnunet-gns-fcfsd.c + +gnunet_gns_fcfsd_LDADD = -lmicrohttpd \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(GN_LIBINTL) + +gnunet_gns_fcfsd_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la libgnunetgns_la_SOURCES = \ gns_api.c gns.h libgnunetgns_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la $(XLIB) + $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \ + $(top_builddir)/src/namestore/libgnunetnamestore.la libgnunetgns_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) libgnunetgns_la_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la libgnunet_plugin_block_gns_la_SOURCES = \ plugin_block_gns.c libgnunet_plugin_block_gns_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/block/libgnunetblock.la + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la libgnunet_plugin_block_gns_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) libgnunet_plugin_block_gns_la_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/block/libgnunetblock.la + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la #Build stub api -libgnunetnamestore_la_SOURCES = \ - namestore_stub_api.c - -libgnunetnamestore_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la $(XLIB) - -libgnunetnamestore_la_LDFLAGS = \ - $(GN_LIB_LDFLAGS) - -libgnunetnamestore_la_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la - -@ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) $(check_SCRIPTS) +#libgnunetnamestore_la_SOURCES = \ +# namestore_stub_api.c +#libgnunetnamestore_la_LIBADD = \ +# $(top_builddir)/src/util/libgnunetutil.la $(XLIB) +#libgnunetnamestore_la_LDFLAGS = \ +# $(GN_LIB_LDFLAGS) +#libgnunetnamestore_la_DEPENDENCIES = \ +# $(top_builddir)/src/util/libgnunetutil.la +@ENABLE_TEST_RUN_TRUE@@LINUX_TRUE@TESTS = $(check_PROGRAMS) EXTRA_DIST = \ - $(check_SCRIPTS) \ - test_gns_twopeer.conf + test_gns_defaults.conf \ + test_gns_simple_lookup.conf \ + test_gns_dht_default.conf -all: all-am +all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -566,8 +841,6 @@ libgnunet_plugin_block_gns.la: $(libgnunet_plugin_block_gns_la_OBJECTS) $(libgnu $(AM_V_CCLD)$(libgnunet_plugin_block_gns_la_LINK) -rpath $(plugindir) $(libgnunet_plugin_block_gns_la_OBJECTS) $(libgnunet_plugin_block_gns_la_LIBADD) $(LIBS) libgnunetgns.la: $(libgnunetgns_la_OBJECTS) $(libgnunetgns_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunetgns_la_LINK) -rpath $(libdir) $(libgnunetgns_la_OBJECTS) $(libgnunetgns_la_LIBADD) $(LIBS) -libgnunetnamestore.la: $(libgnunetnamestore_la_OBJECTS) $(libgnunetnamestore_la_DEPENDENCIES) - $(AM_V_CCLD)$(libgnunetnamestore_la_LINK) -rpath $(libdir) $(libgnunetnamestore_la_OBJECTS) $(libgnunetnamestore_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @@ -620,12 +893,48 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list +gnunet-gns$(EXEEXT): $(gnunet_gns_OBJECTS) $(gnunet_gns_DEPENDENCIES) + @rm -f gnunet-gns$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_gns_OBJECTS) $(gnunet_gns_LDADD) $(LIBS) +gnunet-gns-fcfsd$(EXEEXT): $(gnunet_gns_fcfsd_OBJECTS) $(gnunet_gns_fcfsd_DEPENDENCIES) + @rm -f gnunet-gns-fcfsd$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_gns_fcfsd_OBJECTS) $(gnunet_gns_fcfsd_LDADD) $(LIBS) +gnunet-gns-proxy$(EXEEXT): $(gnunet_gns_proxy_OBJECTS) $(gnunet_gns_proxy_DEPENDENCIES) + @rm -f gnunet-gns-proxy$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_gns_proxy_OBJECTS) $(gnunet_gns_proxy_LDADD) $(LIBS) gnunet-service-gns$(EXEEXT): $(gnunet_service_gns_OBJECTS) $(gnunet_service_gns_DEPENDENCIES) @rm -f gnunet-service-gns$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_service_gns_OBJECTS) $(gnunet_service_gns_LDADD) $(LIBS) -test_gns_twopeer$(EXEEXT): $(test_gns_twopeer_OBJECTS) $(test_gns_twopeer_DEPENDENCIES) - @rm -f test_gns_twopeer$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_gns_twopeer_OBJECTS) $(test_gns_twopeer_LDADD) $(LIBS) +test_gns_dht_delegated_lookup$(EXEEXT): $(test_gns_dht_delegated_lookup_OBJECTS) $(test_gns_dht_delegated_lookup_DEPENDENCIES) + @rm -f test_gns_dht_delegated_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_dht_delegated_lookup_OBJECTS) $(test_gns_dht_delegated_lookup_LDADD) $(LIBS) +test_gns_dht_threepeer$(EXEEXT): $(test_gns_dht_threepeer_OBJECTS) $(test_gns_dht_threepeer_DEPENDENCIES) + @rm -f test_gns_dht_threepeer$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_dht_threepeer_OBJECTS) $(test_gns_dht_threepeer_LDADD) $(LIBS) +test_gns_max_queries$(EXEEXT): $(test_gns_max_queries_OBJECTS) $(test_gns_max_queries_DEPENDENCIES) + @rm -f test_gns_max_queries$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_max_queries_OBJECTS) $(test_gns_max_queries_LDADD) $(LIBS) +test_gns_pseu_shorten$(EXEEXT): $(test_gns_pseu_shorten_OBJECTS) $(test_gns_pseu_shorten_DEPENDENCIES) + @rm -f test_gns_pseu_shorten$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_pseu_shorten_OBJECTS) $(test_gns_pseu_shorten_LDADD) $(LIBS) +test_gns_simple_delegated_lookup$(EXEEXT): $(test_gns_simple_delegated_lookup_OBJECTS) $(test_gns_simple_delegated_lookup_DEPENDENCIES) + @rm -f test_gns_simple_delegated_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_simple_delegated_lookup_OBJECTS) $(test_gns_simple_delegated_lookup_LDADD) $(LIBS) +test_gns_simple_get_authority$(EXEEXT): $(test_gns_simple_get_authority_OBJECTS) $(test_gns_simple_get_authority_DEPENDENCIES) + @rm -f test_gns_simple_get_authority$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_simple_get_authority_OBJECTS) $(test_gns_simple_get_authority_LDADD) $(LIBS) +test_gns_simple_lookup$(EXEEXT): $(test_gns_simple_lookup_OBJECTS) $(test_gns_simple_lookup_DEPENDENCIES) + @rm -f test_gns_simple_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_simple_lookup_OBJECTS) $(test_gns_simple_lookup_LDADD) $(LIBS) +test_gns_simple_mx_lookup$(EXEEXT): $(test_gns_simple_mx_lookup_OBJECTS) $(test_gns_simple_mx_lookup_DEPENDENCIES) + @rm -f test_gns_simple_mx_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_simple_mx_lookup_OBJECTS) $(test_gns_simple_mx_lookup_LDADD) $(LIBS) +test_gns_simple_shorten$(EXEEXT): $(test_gns_simple_shorten_OBJECTS) $(test_gns_simple_shorten_DEPENDENCIES) + @rm -f test_gns_simple_shorten$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_simple_shorten_OBJECTS) $(test_gns_simple_shorten_LDADD) $(LIBS) +test_gns_simple_zkey_lookup$(EXEEXT): $(test_gns_simple_zkey_lookup_OBJECTS) $(test_gns_simple_zkey_lookup_DEPENDENCIES) + @rm -f test_gns_simple_zkey_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gns_simple_zkey_lookup_OBJECTS) $(test_gns_simple_zkey_lookup_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -634,10 +943,23 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gns_api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-gns-fcfsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-gns-proxy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-gns.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-gns.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namestore_stub_api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-gns_interceptor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-gns_resolver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_block_gns.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_twopeer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_dht_delegated_lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_dht_threepeer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_max_queries.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_pseu_shorten.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_simple_delegated_lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_simple_get_authority.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_simple_lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_simple_mx_lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_simple_shorten.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gns_simple_zkey_lookup.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -689,6 +1011,76 @@ uninstall-pkgcfgDATA: echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ @@ -699,10 +1091,23 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) mkid -fID $$unique tags: TAGS -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ @@ -721,7 +1126,7 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ fi; \ fi ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ @@ -863,26 +1268,55 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS) + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am +check: check-recursive all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) install-binPROGRAMS: install-libLTLIBRARIES -installdirs: +installdirs: installdirs-recursive +installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -installcheck: installcheck-am +installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ @@ -899,85 +1333,87 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -clean: clean-am +clean: clean-recursive clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libLTLIBRARIES clean-libtool clean-pluginLTLIBRARIES \ mostlyclean-am -distclean: distclean-am +distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags -dvi: dvi-am +dvi: dvi-recursive dvi-am: -html: html-am +html: html-recursive html-am: -info: info-am +info: info-recursive info-am: install-data-am: install-pkgcfgDATA install-pluginLTLIBRARIES -install-dvi: install-dvi-am +install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-libLTLIBRARIES -install-html: install-html-am +install-html: install-html-recursive install-html-am: -install-info: install-info-am +install-info: install-info-recursive install-info-am: install-man: -install-pdf: install-pdf-am +install-pdf: install-pdf-recursive install-pdf-am: -install-ps: install-ps-am +install-ps: install-ps-recursive install-ps-am: installcheck-am: -maintainer-clean: maintainer-clean-am +maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-am +mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool -pdf: pdf-am +pdf: pdf-recursive pdf-am: -ps: ps-am +ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES -.MAKE: check-am install-am install-strip +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \ + ctags-recursive install-am install-strip tags-recursive -.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ - clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-pluginLTLIBRARIES \ - ctags distclean distclean-compile distclean-generic \ +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-TESTS check-am clean clean-binPROGRAMS \ + clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-pluginLTLIBRARIES ctags ctags-recursive \ + distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ @@ -986,11 +1422,12 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ install-man install-pdf install-pdf-am install-pkgcfgDATA \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-libLTLIBRARIES uninstall-pkgcfgDATA \ + uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/gns/gns.conf.in b/src/gns/gns.conf.in index 422efdb..80fb8c8 100644 --- a/src/gns/gns.conf.in +++ b/src/gns/gns.conf.in @@ -5,13 +5,20 @@ HOME = $SERVICEHOME CONFIG = $DEFAULTCONFIG BINARY = gnunet-service-gns UNIXPATH = /tmp/gnunet-service-gns.sock -ZONEKEY = /tmp/zonekey -TRUSTED = bob:/tmp/bobkey -HIJACK_DNS = YES -OPTIONS = -L INFO +ZONEKEY = $SERVICEHOME/gns/zonekey.zkey +HIJACK_DNS = NO +AUTO_IMPORT_PKEY = YES +AUTO_IMPORT_CONFIRMATION_REQ = NO +MAX_PARALLEL_BACKGROUND_QUERIES = 25 +DEFAULT_LOOKUP_TIMEOUT = 10 +RECORD_PUT_INTERVAL = 60 +ZONE_PUT_INTERVAL = 900 + +[fcfsd] +HTTPPORT = 18080 +ZONEKEY = $SERVICEHOME/fcfsd/zonekey.zkey +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-gns-fcfsd -# Access to this service can compromise all DNS queries in this -# system. Thus access should be restricted to the same UID. -# (see https://gnunet.org/gnunet-access-control-model) -UNIX_MATCH_UID = YES -UNIX_MATCH_GID = YES diff --git a/src/gns/gns.h b/src/gns/gns.h index cb47c81..408b686 100644 --- a/src/gns/gns.h +++ b/src/gns/gns.h @@ -18,6 +18,8 @@ Boston, MA 02111-1307, USA. */ +#include "gnunet_gns_service.h" + /** * @file gns/gns.h * @brief IPC messages between GNS API and GNS service @@ -26,6 +28,13 @@ #ifndef GNS_H #define GNS_H +#define GNUNET_GNS_TLD "gnunet" +#define GNUNET_GNS_TLD_ZKEY "zkey" +#define GNUNET_GNS_DHT_MAX_UPDATE_INTERVAL 3600 + +#define MAX_DNS_LABEL_LENGTH 63 +#define MAX_DNS_NAME_LENGTH 253 + GNUNET_NETWORK_STRUCT_BEGIN /** @@ -39,21 +48,24 @@ struct GNUNET_GNS_ClientLookupMessage struct GNUNET_MessageHeader header; /** - * A key. TODO some uid + * Unique identifier for this request (for key collisions). */ - GNUNET_HashCode key; + uint32_t id GNUNET_PACKED; /** - * Unique identifier for this request (for key collisions). + * Should we look up in the default zone? */ - // FIXME: unaligned - uint64_t unique_id; + uint32_t use_default_zone GNUNET_PACKED; + + /** + * If use_default_zone is empty this zone is used for lookup + */ + struct GNUNET_CRYPTO_ShortHashCode zone; /** * the type of record to look up */ - // FIXME: bad type - should be of GNUNET_GNS_RecordType - int type; + enum GNUNET_GNS_RecordType type; /* Followed by the name to look up */ }; @@ -62,7 +74,7 @@ struct GNUNET_GNS_ClientLookupMessage /** * Message from GNS service to client: new results. */ -struct GNUNET_GNS_ClientResultMessage +struct GNUNET_GNS_ClientLookupResultMessage { /** * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT @@ -72,26 +84,103 @@ struct GNUNET_GNS_ClientResultMessage /** * Unique identifier for this request (for key collisions). */ - // FIXME: unaligned - uint64_t unique_id; - - /** - * A key. TODO some uid - * // FIXME: why hash? - */ - GNUNET_HashCode key; + uint32_t id GNUNET_PACKED; /** * The number of records contained in response */ - uint32_t num_records; + uint32_t rd_count; // FIXME: what format has a GNS_Record? - /* followed by num_records GNUNET_GNS_Records*/ + /* followed by rd_count GNUNET_NAMESTORE_RecordData structs*/ }; +/** + * Message from client to GNS service to shorten names. + */ +struct GNUNET_GNS_ClientShortenMessage +{ + /** + * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN + */ + struct GNUNET_MessageHeader header; + /** + * Unique identifier for this request + */ + uint32_t id GNUNET_PACKED; + + /** + * Should we look up in the default zone? + */ + uint32_t use_default_zone GNUNET_PACKED; + + /** + * If use_default_zone is empty this zone is used for lookup + */ + struct GNUNET_CRYPTO_ShortHashCode zone; + + /* Followed by the name to shorten up */ +}; + + +/** + * Message from GNS service to client: shorten result. + */ +struct GNUNET_GNS_ClientShortenResultMessage +{ + /** + * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN_RESULT + */ + struct GNUNET_MessageHeader header; + + /** + * Unique identifier for this request (for key collisions). + */ + uint32_t id GNUNET_PACKED; + + /* followed by the shortened name or '\0' for no result*/ + +}; + +/** + * Message from client to GNS service to lookup an authority of a name. + */ +struct GNUNET_GNS_ClientGetAuthMessage +{ + /** + * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_GET_AUTH + */ + struct GNUNET_MessageHeader header; + + /** + * Unique identifier for this request + */ + uint32_t id GNUNET_PACKED; + + /* Followed by the name to get authority for */ +}; + + +/** + * Message from GNS service to client: authority result. + */ +struct GNUNET_GNS_ClientGetAuthResultMessage +{ + /** + * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_GET_AUTH_RESULT + */ + struct GNUNET_MessageHeader header; + + /** + * Unique identifier for this request (for key collisions). + */ + uint32_t id GNUNET_PACKED; + + /* followed by the authority part of the name or '\0' for no result*/ + +}; GNUNET_NETWORK_STRUCT_END #endif diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index ec9c159..a92280f 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c @@ -19,7 +19,6 @@ */ /** - * TODO: Do we really need a client API? * * @file gns/gns_api.c * @brief library to access the GNS service @@ -36,111 +35,73 @@ #include "gns.h" #include "gnunet_gns_service.h" -#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING - -#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) - /* TODO into gnunet_protocols */ -#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP 23 -#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT 24 +#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP 23 +#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 24 +#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN 25 +#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26 +#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH 27 +#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT 28 /** - * Entry in our list of messages to be (re-)transmitted. + * A QueueEntry. */ -struct PendingMessage +struct GNUNET_GNS_QueueEntry { /** - * This is a doubly-linked list. - */ - struct PendingMessage *prev; - - /** - * This is a doubly-linked list. - */ - struct PendingMessage *next; - - /** - * Message that is pending, allocated at the end - * of this struct. - */ - const struct GNUNET_MessageHeader *msg; - - /** - * Handle to the GNS API context. - */ - struct GNUNET_GNS_Handle *handle; - - /** - * Continuation to call when the request has been - * transmitted (for the first time) to the service; can be NULL. - */ - GNUNET_SCHEDULER_Task cont; - - /** - * Closure for 'cont'. - */ - void *cont_cls; - - /** - * Timeout task for this message - */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; - - /** - * Unique ID for this request - */ - uint64_t unique_id; - - /** - * Free the saved message once sent, set to GNUNET_YES for messages - * that do not receive responses; GNUNET_NO if this pending message - * is aliased from a 'struct GNUNET_DHT_RouteHandle' and will be freed - * from there. + * DLL */ - - int free_on_send; + struct GNUNET_GNS_QueueEntry *next; + /** - * GNUNET_YES if this message is in our pending queue right now. + * DLL */ - int in_pending_queue; + struct GNUNET_GNS_QueueEntry *prev; + /* request id */ + uint32_t r_id; + + /* handle to gns */ + struct GNUNET_GNS_Handle *gns_handle; + + /* processor to call on shorten result */ + GNUNET_GNS_ShortenResultProcessor shorten_proc; + + /* processor to call on lookup result */ + GNUNET_GNS_LookupResultProcessor lookup_proc; + + /* processor to call on authority lookup result */ + GNUNET_GNS_GetAuthResultProcessor auth_proc; + + /* processor closure */ + void *proc_cls; + }; + /** - * Handle to a Lookup request + * Entry in our list of messages to be (re-)transmitted. */ -struct GNUNET_GNS_LookupHandle +struct PendingMessage { - - /** - * Iterator to call on data receipt - */ - GNUNET_GNS_LookupIterator iter; - - /** - * Closure for the iterator callback - */ - void *iter_cls; - /** - * Main handle to this GNS api + * This is a doubly-linked list. */ - struct GNUNET_GNS_Handle *gns_handle; + struct PendingMessage *prev; /** - * Key that this get request is for + * This is a doubly-linked list. */ - GNUNET_HashCode key; + struct PendingMessage *next; /** - * Unique identifier for this request (for key collisions). + * Size of the message. */ - uint64_t unique_id; - - struct PendingMessage *message; + size_t size; }; + /** * Connection to the GNS service. */ @@ -161,39 +122,63 @@ struct GNUNET_GNS_Handle * Currently pending transmission request (or NULL). */ struct GNUNET_CLIENT_TransmitHandle *th; - + + uint32_t r_id; + /** - * Head of linked list of messages we would like to transmit. + * Head of linked list of shorten messages we would like to transmit. */ struct PendingMessage *pending_head; /** - * Tail of linked list of messages we would like to transmit. + * Tail of linked list of shorten messages we would like to transmit. */ struct PendingMessage *pending_tail; + + /** + * Head of linked list of shorten messages we would like to transmit. + */ + struct GNUNET_GNS_QueueEntry *shorten_head; /** - * Hash map containing the current outstanding unique requests. + * Tail of linked list of shorten messages we would like to transmit. + */ + struct GNUNET_GNS_QueueEntry *shorten_tail; + + /** + * Head of linked list of lookup messages we would like to transmit. */ - struct GNUNET_CONTAINER_MultiHashMap *active_requests; + struct GNUNET_GNS_QueueEntry *lookup_head; - GNUNET_SCHEDULER_TaskIdentifier reconnect_task; + /** + * Tail of linked list of lookup messages we would like to transmit. + */ + struct GNUNET_GNS_QueueEntry *lookup_tail; + + /** + * Head of linked list of authority lookup messages we would like to transmit. + */ + struct GNUNET_GNS_QueueEntry *get_auth_head; /** - * How quickly should we retry? Used for exponential back-off on - * connect-errors. + * Tail of linked list of authority lookup messages we would like to transmit. */ - struct GNUNET_TIME_Relative retry_time; + struct GNUNET_GNS_QueueEntry *get_auth_tail; /** - * Generator for unique ids. + * Reconnect task */ - uint64_t uid_gen; + GNUNET_SCHEDULER_TaskIdentifier reconnect_task; /** * Did we start our receive loop yet? */ int in_receive; + + /** + * Reconnect necessary + */ + int reconnect; }; /** @@ -203,112 +188,52 @@ struct GNUNET_GNS_Handle static void process_pending_messages (struct GNUNET_GNS_Handle *handle); -/** - * Try to (re)connect to the GNS service. - * - * @return GNUNET_YES on success, GNUNET_NO on failure. - */ -static int -try_connect (struct GNUNET_GNS_Handle *handle) -{ - if (handle->client != NULL) - return GNUNET_OK; - handle->in_receive = GNUNET_NO; - handle->client = GNUNET_CLIENT_connect ("gns", handle->cfg); - if (handle->client == NULL) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - _("Failed to connect to the GNS service!\n")); - return GNUNET_NO; - } - return GNUNET_YES; -} /** - * Add the request corresponding to the given handle - * to the pending queue (if it is not already in there). + * Reconnect to GNS service. * - * @param cls the 'struct GNUNET_GNS_Handle*' - * @param key key for the request (not used) - * @param value the 'struct GNUNET_GNS_LookupHandle*' - * @return GNUNET_YES (always) + * @param h the handle to the namestore service */ -static int -add_request_to_pending (void *cls, const GNUNET_HashCode * key, void *value) +static void +reconnect (struct GNUNET_GNS_Handle *h) { - struct GNUNET_GNS_Handle *handle = cls; - struct GNUNET_GNS_LookupHandle *rh = value; - - if (GNUNET_NO == rh->message->in_pending_queue) - { -#if DEBUG_DHT - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Retransmitting request related to %s to GNS %p\n", GNUNET_h2s(key), - handle); -#endif - GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, - rh->message); - rh->message->in_pending_queue = GNUNET_YES; - } - return GNUNET_YES; + GNUNET_assert (NULL == h->client); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Trying to connect to GNS...\n"); + h->client = GNUNET_CLIENT_connect ("gns", h->cfg); + GNUNET_assert (NULL != h->client); } /** - * Try reconnecting to the GNS service. + * Reconnect to GNS * - * @param cls GNUNET_GNS_Handle - * @param tc scheduler context + * @param cls the handle + * @param tc task context */ static void -try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_GNS_Handle *handle = cls; + struct GNUNET_GNS_Handle *h = cls; -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle); -#endif - handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - if (handle->retry_time.rel_value < GNUNET_CONSTANTS_SERVICE_RETRY.rel_value) - handle->retry_time = GNUNET_CONSTANTS_SERVICE_RETRY; - else - handle->retry_time = GNUNET_TIME_relative_multiply (handle->retry_time, 2); - if (handle->retry_time.rel_value > GNUNET_CONSTANTS_SERVICE_TIMEOUT.rel_value) - handle->retry_time = GNUNET_CONSTANTS_SERVICE_TIMEOUT; - handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - if (GNUNET_YES != try_connect (handle)) - { -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n"); -#endif - return; - } - GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests, - &add_request_to_pending, handle); - process_pending_messages (handle); + h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; + reconnect (h); } /** - * Try reconnecting to the GNS service. + * Disconnect from service and then reconnect. * - * @param handle handle to gns to (possibly) disconnect and reconnect + * @param h our handle */ static void -do_disconnect (struct GNUNET_GNS_Handle *handle) +force_reconnect (struct GNUNET_GNS_Handle *h) { - if (handle->client == NULL) - return; - GNUNET_assert (handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK); - if (NULL != handle->th) - GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); - handle->th = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Disconnecting from GNS service, will try to reconnect in %llu ms\n", - (unsigned long long) handle->retry_time.rel_value); - GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); - handle->client = NULL; - handle->reconnect_task = - GNUNET_SCHEDULER_add_delayed (handle->retry_time, &try_reconnect, handle); + h->reconnect = GNUNET_NO; + GNUNET_CLIENT_disconnect (h->client); + h->client = NULL; + h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, + &reconnect_task, + h); } /** @@ -324,7 +249,7 @@ transmit_pending (void *cls, size_t size, void *buf); * @param msg the incoming message */ static void -message_handler (void *cls, const struct GNUNET_MessageHeader *msg); +process_message (void *cls, const struct GNUNET_MessageHeader *msg); /** * Try to send messages from list of messages to send @@ -332,30 +257,35 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg); static void process_pending_messages (struct GNUNET_GNS_Handle *handle) { - struct PendingMessage *head; + struct PendingMessage *p; if (handle->client == NULL) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "process_pending_messages called, but client is null, reconnecting\n"); - do_disconnect (handle); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "process_pending_messages called, but client is null\n"); return; } + if (handle->th != NULL) return; - if (NULL == (head = handle->pending_head)) + + if (NULL == (p = handle->pending_head)) return; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Trying to transmit %d bytes...\n", p->size); + handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, - ntohs (head->msg->size), + p->size, GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &transmit_pending, + GNUNET_NO, &transmit_pending, handle); if (NULL != handle->th) return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "notify_transmit_ready returned NULL, reconnecting\n"); - do_disconnect (handle); + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "notify_transmit_ready returned NULL!\n"); } @@ -366,51 +296,45 @@ static size_t transmit_pending (void *cls, size_t size, void *buf) { struct GNUNET_GNS_Handle *handle = cls; - struct PendingMessage *head; + struct PendingMessage *p; size_t tsize; + char *cbuf; handle->th = NULL; - if (buf == NULL) + + if ((size == 0) || (buf == NULL)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Transmission to GNS service failed! Reconnecting!\n"); - do_disconnect (handle); + "Transmission to GNS service failed!\n"); + force_reconnect(handle); return 0; } - if (NULL == (head = handle->pending_head)) - return 0; + + tsize = 0; + cbuf = buf; - tsize = ntohs (head->msg->size); - if (size < tsize) - { - process_pending_messages (handle); + if (NULL == (p = handle->pending_head)) return 0; - } - memcpy (buf, head->msg, tsize); - GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, - head); - head->in_pending_queue = GNUNET_NO; - if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (head->timeout_task); - head->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - if (GNUNET_YES == head->free_on_send) - GNUNET_free (head); - process_pending_messages (handle); -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Forwarded request of %u bytes to GNS service\n", (unsigned int) tsize); -#endif - if (GNUNET_NO == handle->in_receive) + + while ((NULL != (p = handle->pending_head)) && (p->size <= size)) { -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting to process replies from GNS\n"); -#endif - handle->in_receive = GNUNET_YES; - GNUNET_CLIENT_receive (handle->client, &message_handler, handle, - GNUNET_TIME_UNIT_FOREVER_REL); + memcpy (&cbuf[tsize], &p[1], p->size); + tsize += p->size; + size -= p->size; + GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, p); + if (GNUNET_YES != handle->in_receive) + { + GNUNET_CLIENT_receive (handle->client, &process_message, handle, + GNUNET_TIME_UNIT_FOREVER_REL); + handle->in_receive = GNUNET_YES; + } + GNUNET_free(p); } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending %d bytes\n", tsize); + + process_pending_messages(handle); return tsize; } @@ -418,54 +342,126 @@ transmit_pending (void *cls, size_t size, void *buf) * Process a given reply that might match the given * request. * - * @param cls the 'struct GNUNET_GNS_ClientResultMessage' - * @param key query of the request - * @param value the 'struct GNUNET_GNS_LookupHandle' of a request matching the same key - * @return GNUNET_YES to continue to iterate over all results, - * GNUNET_NO if the reply is malformed + * @param qe a queue entry + * @param msg the shorten msg received */ -static int -process_reply (void *cls, const GNUNET_HashCode * key, void *value) +static void +process_shorten_reply (struct GNUNET_GNS_QueueEntry *qe, + const struct GNUNET_GNS_ClientShortenResultMessage *msg) { - const struct GNUNET_GNS_ClientResultMessage *gns_msg = cls; - struct GNUNET_GNS_LookupHandle *lookup_handle = value; - const char *name = (const char*) &lookup_handle[1]; - const struct GNUNET_NAMESTORE_RecordData *records; - uint32_t num_records; - size_t meta_length; - size_t msize; + struct GNUNET_GNS_Handle *h = qe->gns_handle; + const char *short_name; + + GNUNET_CONTAINER_DLL_remove(h->shorten_head, h->shorten_tail, qe); - if (gns_msg->unique_id != lookup_handle->unique_id) + short_name = (char*)(&msg[1]); + + if (ntohs (((struct GNUNET_MessageHeader*)msg)->size) < + sizeof (struct GNUNET_GNS_ClientShortenResultMessage)) { - /* UID mismatch */ -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key), - gns_msg->unique_id, lookup_handle->unique_id); -#endif - return GNUNET_YES; + GNUNET_break (0); + force_reconnect (h); + GNUNET_free(qe); + return; } - msize = ntohs (gns_msg->header.size); - num_records = ntohl (gns_msg->num_records); - meta_length = - sizeof (struct GNUNET_GNS_ClientResultMessage) + - sizeof (struct GNUNET_NAMESTORE_RecordData) * (num_records); - if ((msize < meta_length) || - (num_records > - GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_NAMESTORE_RecordData))) + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received shortened reply `%s' from GNS service\n", + short_name); + + GNUNET_CLIENT_receive (h->client, &process_message, h, + GNUNET_TIME_UNIT_FOREVER_REL); + qe->shorten_proc(qe->proc_cls, short_name); + GNUNET_free(qe); + +} + + +/** + * Process a given reply that might match the given + * request. + * + * @param qe the handle to the request + * @param msg the message to process + */ +static void +process_get_auth_reply (struct GNUNET_GNS_QueueEntry *qe, + const struct GNUNET_GNS_ClientGetAuthResultMessage *msg) +{ + struct GNUNET_GNS_Handle *h = qe->gns_handle; + const char *auth_name; + + GNUNET_CONTAINER_DLL_remove(h->get_auth_head, h->get_auth_tail, qe); + + auth_name = (char*)(&msg[1]); + + if (ntohs (((struct GNUNET_MessageHeader*)msg)->size) < + sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage)) { + GNUNET_free(qe); GNUNET_break (0); - return GNUNET_NO; + force_reconnect (h); + return; } -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving %u byte reply for %s to application\n", - (unsigned int) (msize - meta_length), GNUNET_h2s (key)); -#endif - records = (const struct GNUNET_NAMESTORE_RecordData *) &gns_msg[1]; - lookup_handle->iter (lookup_handle->iter_cls, name, records, num_records); - return GNUNET_YES; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received GET_AUTH reply `%s' from GNS service\n", + auth_name); + + GNUNET_CLIENT_receive (h->client, &process_message, h, + GNUNET_TIME_UNIT_FOREVER_REL); + qe->auth_proc(qe->proc_cls, auth_name); + GNUNET_free(qe); + } +/** + * Process a given reply to the lookup request + * + * @param qe a queue entry + * @param msg the lookup message received + */ +static void +process_lookup_reply (struct GNUNET_GNS_QueueEntry *qe, + const struct GNUNET_GNS_ClientLookupResultMessage *msg) +{ + struct GNUNET_GNS_Handle *h = qe->gns_handle; + int rd_count = ntohl(msg->rd_count); + size_t len = ntohs (((struct GNUNET_MessageHeader*)msg)->size); + struct GNUNET_NAMESTORE_RecordData rd[rd_count]; + + GNUNET_CONTAINER_DLL_remove(h->lookup_head, h->lookup_tail, qe); + + if (len < sizeof (struct GNUNET_GNS_ClientLookupResultMessage)) + { + GNUNET_free(qe); + GNUNET_break (0); + force_reconnect (h); + return; + } + + len -= sizeof(struct GNUNET_GNS_ClientLookupResultMessage); + GNUNET_CLIENT_receive (h->client, &process_message, h, + GNUNET_TIME_UNIT_FOREVER_REL); + if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (len, + (char*)&msg[1], + rd_count, + rd)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to serialize lookup reply from GNS service!\n"); + qe->lookup_proc(qe->proc_cls, 0, NULL); + } + else + { + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received lookup reply from GNS service (count=%d)\n", + ntohl(msg->rd_count)); + qe->lookup_proc(qe->proc_cls, rd_count, rd); + } + GNUNET_free(qe); +} /** * Handler for messages received from the GNS service @@ -474,43 +470,112 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value) * @param msg the incoming message */ static void -message_handler (void *cls, const struct GNUNET_MessageHeader *msg) +process_message (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_GNS_Handle *handle = cls; - const struct GNUNET_GNS_ClientResultMessage *gns_msg; - + struct GNUNET_GNS_QueueEntry *qe; + const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg; + const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg; + const struct GNUNET_GNS_ClientGetAuthResultMessage *get_auth_msg; + uint16_t type; + uint32_t r_id; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got message\n"); if (msg == NULL) { -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error receiving data from GNS service, reconnecting\n"); -#endif - do_disconnect (handle); + force_reconnect (handle); return; } - if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT) + + type = ntohs (msg->type); + + if (type == GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT) { - GNUNET_break (0); - do_disconnect (handle); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got lookup msg\n"); + lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg; + r_id = ntohl (lookup_msg->id); + + if (r_id > handle->r_id) + { + /** no request found */ + GNUNET_break_op (0); + GNUNET_CLIENT_receive (handle->client, &process_message, handle, + GNUNET_TIME_UNIT_FOREVER_REL); + return; + } + + for (qe = handle->lookup_head; qe != NULL; qe = qe->next) + { + if (qe->r_id == r_id) + break; + } + if (qe) + process_lookup_reply(qe, lookup_msg); + return; + } - if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientResultMessage)) + else if (type == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT) { - GNUNET_break (0); - do_disconnect (handle); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got SHORTEN_RESULT msg\n"); + shorten_msg = (struct GNUNET_GNS_ClientShortenResultMessage *) msg; + + r_id = ntohl (shorten_msg->id); + + if (r_id > handle->r_id) + { + /** no request found */ + GNUNET_break_op (0); + GNUNET_CLIENT_receive (handle->client, &process_message, handle, + GNUNET_TIME_UNIT_FOREVER_REL); + return; + } + + for (qe = handle->shorten_head; qe != NULL; qe = qe->next) + { + if (qe->r_id == r_id) + break; + } + if (qe) + process_shorten_reply(qe, shorten_msg); return; } - gns_msg = (const struct GNUNET_GNS_ClientResultMessage *) msg; -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Received reply for `%s' from GNS service %p\n", - &gns_msg->name, handle); -#endif - /* TODO uniquely identify requests... maybe hash(name) or uid */ - GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests, - &gns_msg->key, &process_reply, - (void *) gns_msg); - GNUNET_CLIENT_receive (handle->client, &message_handler, handle, - GNUNET_TIME_UNIT_FOREVER_REL); + else if (type == GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got GET_AUTH_RESULT msg\n"); + get_auth_msg = (struct GNUNET_GNS_ClientGetAuthResultMessage *) msg; + + r_id = ntohl (get_auth_msg->id); + + if (r_id > handle->r_id) + { + /** no request found */ + GNUNET_break_op (0); + GNUNET_CLIENT_receive (handle->client, &process_message, handle, + GNUNET_TIME_UNIT_FOREVER_REL); + return; + } + + for (qe = handle->get_auth_head; qe != NULL; qe = qe->next) + { + if (qe->r_id == r_id) + break; + } + if (qe) + process_get_auth_reply(qe, get_auth_msg); + return; + } + + + if (GNUNET_YES == handle->reconnect) + force_reconnect (handle); + } @@ -518,25 +583,21 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg) * Initialize the connection with the GNS service. * * @param cfg configuration to use - * @param ht_len size of the internal hash table to use for parallel requests * @return handle to the GNS service, or NULL on error */ struct GNUNET_GNS_Handle * -GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, - unsigned int ht_len) +GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_GNS_Handle *handle; handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle)); + handle->reconnect = GNUNET_NO; handle->cfg = cfg; - handle->uid_gen = - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); - handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len); - if (GNUNET_NO == try_connect (handle)) - { - GNUNET_GNS_disconnect (handle); - return NULL; - } + reconnect (handle); + //handle->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, handle); + handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; + handle->r_id = 0; + handle->in_receive = GNUNET_NO; return handle; } @@ -549,35 +610,52 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) { + GNUNET_CLIENT_disconnect (handle->client); + if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task) + { + GNUNET_SCHEDULER_cancel (handle->reconnect_task); + handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_free(handle); /* disco from GNS */ } +/* + * Helper function to generate request ids + * + * @param h handle + * @return a new id + */ +static uint32_t +get_request_id (struct GNUNET_GNS_Handle *h) +{ + uint32_t r_id = h->r_id; + h->r_id++; + return r_id; +} /** * Perform an asynchronous Lookup operation on the GNS. - * TODO: - * - Still not sure what we query for... "names" it is for now - * - Do we need such sophisticated message queueing like dht? simplify? * * @param handle handle to the GNS service - * @param timeout how long to wait for transmission of this request to the service * @param name the name to look up - * @param iter function to call on each result - * @param iter_cls closure for iter - * @return handle to stop the async get + * @param zone the zone to start the resolution in + * @param type the record type to look up + * @param proc processor to call on result + * @param proc_cls closure for processor + * @return handle to the get */ -struct GNUNET_GNS_LookupHandle * -GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, - struct GNUNET_TIME_Relative timeout, - const char * name, - enum GNUNET_GNS_RecordType type, - GNUNET_GNS_LookupIterator iter, - void *iter_cls) +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle, + const char * name, + struct GNUNET_CRYPTO_ShortHashCode *zone, + enum GNUNET_GNS_RecordType type, + GNUNET_GNS_LookupResultProcessor proc, + void *proc_cls) { - /* IPC to look for local entries, start dht lookup, return lookup_handle */ + /* IPC to shorten gns names, return shorten_handle */ struct GNUNET_GNS_ClientLookupMessage *lookup_msg; - struct GNUNET_GNS_LookupHandle *lookup_handle; - GNUNET_HashCode key; + struct GNUNET_GNS_QueueEntry *qe; size_t msize; struct PendingMessage *pending; @@ -586,49 +664,210 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, return NULL; } - GNUNET_CRYPTO_hash (name, strlen(name), &key); + msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + strlen(name) + 1; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to lookup %s in GNS\n", name); + + qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry)); + qe->gns_handle = handle; + qe->lookup_proc = proc; + qe->proc_cls = proc_cls; + qe->r_id = get_request_id(handle); + GNUNET_CONTAINER_DLL_insert_tail(handle->lookup_head, + handle->lookup_tail, qe); - msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + strlen(name); -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting lookup for %s in GNS %p\n", - name, handle); -#endif pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); + memset(pending, 0, (sizeof (struct PendingMessage) + msize)); + + pending->size = msize; + lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1]; - pending->msg = &lookup_msg->header; - pending->handle = handle; - pending->free_on_send = GNUNET_NO; + lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP); lookup_msg->header.size = htons (msize); - lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP); - lookup_msg->key = key; + lookup_msg->id = htonl(qe->r_id); + + if (NULL != zone) + { + lookup_msg->use_default_zone = htonl(0); + memcpy(&lookup_msg->zone, zone, sizeof(struct GNUNET_CRYPTO_ShortHashCode)); + } + else + { + lookup_msg->use_default_zone = htonl(1); + memset(&lookup_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode)); + } + + lookup_msg->type = htonl(type); + memcpy(&lookup_msg[1], name, strlen(name)); - handle->uid_gen++; - lookup_msg->unique_id = handle->uid_gen; - GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, + + GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, pending); - pending->in_pending_queue = GNUNET_YES; - lookup_handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupHandle)); - lookup_handle->iter = iter; - lookup_handle->iter_cls = iter_cls; - lookup_handle->message = pending; - lookup_handle->unique_id = lookup_msg->unique_id; - GNUNET_CONTAINER_multihashmap_put (handle->active_requests, &lookup_msg->key, - lookup_handle, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + process_pending_messages (handle); - return lookup_handle; + return qe; } +/** + * Perform an asynchronous Lookup operation on the GNS. + * + * @param handle handle to the GNS service + * @param name the name to look up + * @param type the record type to look up + * @param proc processor to call on result + * @param proc_cls closure for processor + * @return handle to the get + */ +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, + const char * name, + enum GNUNET_GNS_RecordType type, + GNUNET_GNS_LookupResultProcessor proc, + void *proc_cls) +{ + return GNUNET_GNS_lookup_zone (handle, name, NULL, type, proc, proc_cls); +} /** - * Stop async GNS lookup. + * Perform a name shortening operation on the GNS. * - * @param lookup_handle handle to the GNS lookup operation to stop + * @param handle handle to the GNS service + * @param name the name to look up + * @param zone the zone to start the resolution in + * @param proc function to call on result + * @param proc_cls closure for processor + * @return handle to the operation */ -void -GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_shorten_zone (struct GNUNET_GNS_Handle *handle, + const char * name, + struct GNUNET_CRYPTO_ShortHashCode *zone, + GNUNET_GNS_ShortenResultProcessor proc, + void *proc_cls) { - /* TODO Stop dht lookups */ + /* IPC to shorten gns names, return shorten_handle */ + struct GNUNET_GNS_ClientShortenMessage *shorten_msg; + struct GNUNET_GNS_QueueEntry *qe; + size_t msize; + struct PendingMessage *pending; + + if (NULL == name) + { + return NULL; + } + + msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name) + 1; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten %s in GNS\n", name); + + qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry)); + qe->gns_handle = handle; + qe->shorten_proc = proc; + qe->proc_cls = proc_cls; + qe->r_id = get_request_id(handle); + GNUNET_CONTAINER_DLL_insert_tail(handle->shorten_head, + handle->shorten_tail, qe); + + pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); + memset(pending, 0, (sizeof (struct PendingMessage) + msize)); + + pending->size = msize; + + shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1]; + shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN); + shorten_msg->header.size = htons (msize); + shorten_msg->id = htonl(qe->r_id); + + if (NULL != zone) + { + shorten_msg->use_default_zone = htonl(0); + memcpy(&shorten_msg->zone, zone, + sizeof(struct GNUNET_CRYPTO_ShortHashCode)); + } + else + { + shorten_msg->use_default_zone = htonl(1); + memset(&shorten_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode)); + } + + memcpy(&shorten_msg[1], name, strlen(name)); + + GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, + pending); + + process_pending_messages (handle); + return qe; +} + +/** + * Perform a name shortening operation on the GNS. + * + * @param handle handle to the GNS service + * @param name the name to look up + * @param proc function to call on result + * @param proc_cls closure for processor + * @return handle to the operation + */ +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, + const char * name, + GNUNET_GNS_ShortenResultProcessor proc, + void *proc_cls) +{ + return GNUNET_GNS_shorten_zone (handle, name, NULL, proc, proc_cls); +} +/** + * Perform an authority lookup for a given name. + * + * @param handle handle to the GNS service + * @param name the name to look up authority for + * @param proc function to call on result + * @param proc_cls closure for processor + * @return handle to the operation + */ +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle, + const char * name, + GNUNET_GNS_GetAuthResultProcessor proc, + void *proc_cls) +{ + struct GNUNET_GNS_ClientGetAuthMessage *get_auth_msg; + struct GNUNET_GNS_QueueEntry *qe; + size_t msize; + struct PendingMessage *pending; + + if (NULL == name) + { + return NULL; + } + + msize = sizeof (struct GNUNET_GNS_ClientGetAuthMessage) + strlen(name) + 1; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Trying to look up authority for %s in GNS\n", name); + + qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry)); + qe->gns_handle = handle; + qe->auth_proc = proc; + qe->proc_cls = proc_cls; + qe->r_id = get_request_id(handle); + GNUNET_CONTAINER_DLL_insert_tail(handle->get_auth_head, + handle->get_auth_tail, qe); + + pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); + memset(pending, 0, (sizeof (struct PendingMessage) + msize)); + + pending->size = msize; + + get_auth_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) &pending[1]; + get_auth_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_GET_AUTH); + get_auth_msg->header.size = htons (msize); + get_auth_msg->id = htonl(qe->r_id); + + memcpy(&get_auth_msg[1], name, strlen(name)); + + GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, + pending); + + process_pending_messages (handle); + return qe; } diff --git a/src/gns/gns_proxy_proto.h b/src/gns/gns_proxy_proto.h new file mode 100644 index 0000000..ef30d5c --- /dev/null +++ b/src/gns/gns_proxy_proto.h @@ -0,0 +1,49 @@ + +#define SOCKS_VERSION_5 0x05 +#define SOCKS_AUTH_NONE 0 + +/* The socks phases */ +enum +{ + SOCKS5_INIT, + SOCKS5_REQUEST, + SOCKS5_DATA_TRANSFER +}; + +/* Client hello */ +struct socks5_client_hello +{ + uint8_t version; + uint8_t num_auth_methods; + char* auth_methods; +}; + +/* Client socks request */ +struct socks5_client_request +{ + uint8_t version; + uint8_t command; + uint8_t resvd; + uint8_t addr_type; + /* + * followed by either an ip4/ipv6 address + * or a domain name with a length field in front + */ +}; + +/* Server hello */ +struct socks5_server_hello +{ + uint8_t version; + uint8_t auth_method; +}; + +/* Server response to client requests */ +struct socks5_server_response +{ + uint8_t version; + uint8_t reply; + uint8_t reserved; + uint8_t addr_type; + uint8_t add_port[18]; +}; diff --git a/src/gns/gnunet-gns-fcfsd.c b/src/gns/gnunet-gns-fcfsd.c new file mode 100644 index 0000000..cd4e8e7 --- /dev/null +++ b/src/gns/gnunet-gns-fcfsd.c @@ -0,0 +1,811 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gnunet-gns-fcfsd.c + * @brief HTTP daemon that offers first-come-first-serve GNS domain registration + * @author Christian Grothoff + * + * TODO: + * - the code currently contains a 'race' between checking that the + * domain name is available and allocating it to the new public key + * (should this race be solved by namestore or by fcfsd?) + * - nicer error reporting to browser + * - figure out where this binary should go (is gns the right directory!?) + */ +#include "platform.h" +#include +#include +#include + +/** + * Invalid method page. + */ +#define METHOD_ERROR "Illegal requestGo away." + +/** + * Front page. (/) + */ +#define MAIN_PAGE "GNUnet FCFS Authority Name Registration Service

What is your desired domain name?

What is your public key? " + +/** + * Second page (/S) + */ +#define SUBMIT_PAGE "%s%s" + +/** + * Mime type for HTML pages. + */ +#define MIME_HTML "text/html" + +/** + * Name of our cookie. + */ +#define COOKIE_NAME "gns-fcfs" + + +/** + * Phases a request goes through. + */ +enum Phase + { + /** + * Start phase (parsing POST, checking). + */ + RP_START = 0, + + /** + * Lookup to see if the domain name is taken. + */ + RP_LOOKUP, + + /** + * Storing of the record. + */ + RP_PUT, + + /** + * We're done with success. + */ + RP_SUCCESS, + + /** + * Send failure message. + */ + RP_FAIL + }; + + +/** + * Data kept per request. + */ +struct Request +{ + + /** + * Associated session. + */ + struct Session *session; + + /** + * Post processor handling form data (IF this is + * a POST request). + */ + struct MHD_PostProcessor *pp; + + /** + * URL to serve in response to this POST (if this request + * was a 'POST') + */ + const char *post_url; + + /** + * Active request with the namestore. + */ + struct GNUNET_NAMESTORE_QueueEntry *qe; + + /** + * Current processing phase. + */ + enum Phase phase; + + /** + * Domain name submitted via form. + */ + char domain_name[64]; + + /** + * Public key submitted via form. + */ + char public_key[64]; + +}; + + +/** + * MHD deamon reference. + */ +static struct MHD_Daemon *httpd; + +/** + * Main HTTP task. + */ +static GNUNET_SCHEDULER_TaskIdentifier httpd_task; + +/** + * Handle to the namestore. + */ +static struct GNUNET_NAMESTORE_Handle *ns; + +/** + * Hash of the public key of the fcfsd zone. + */ +static struct GNUNET_CRYPTO_ShortHashCode fcfsd_zone; + +/** + * Private key for the fcfsd zone. + */ +static struct GNUNET_CRYPTO_RsaPrivateKey *fcfs_zone_pkey; + + +/** + * Handler that returns a simple static HTTP page. + * + * @param connection connection to use + * @return MHD_YES on success + */ +static int +serve_main_page (struct MHD_Connection *connection) +{ + int ret; + struct MHD_Response *response; + + /* return static form */ + response = MHD_create_response_from_buffer (strlen (MAIN_PAGE), + (void *) MAIN_PAGE, + MHD_RESPMEM_PERSISTENT); + MHD_add_response_header (response, + MHD_HTTP_HEADER_CONTENT_TYPE, + MIME_HTML); + ret = MHD_queue_response (connection, + MHD_HTTP_OK, + response); + MHD_destroy_response (response); + return ret; +} + + +/** + * Send the 'SUBMIT_PAGE'. + * + * @param info information string to send to the user + * @param request request information + * @param connection connection to use + */ +static int +fill_s_reply (const char *info, + struct Request *request, + struct MHD_Connection *connection) +{ + int ret; + char *reply; + struct MHD_Response *response; + + GNUNET_asprintf (&reply, + SUBMIT_PAGE, + info, + info); + /* return static form */ + response = MHD_create_response_from_buffer (strlen (reply), + (void *) reply, + MHD_RESPMEM_MUST_FREE); + MHD_add_response_header (response, + MHD_HTTP_HEADER_CONTENT_TYPE, + MIME_HTML); + ret = MHD_queue_response (connection, + MHD_HTTP_OK, + response); + MHD_destroy_response (response); + return ret; +} + + +/** + * Iterator over key-value pairs where the value + * maybe made available in increments and/or may + * not be zero-terminated. Used for processing + * POST data. + * + * @param cls user-specified closure + * @param kind type of the value + * @param key 0-terminated key for the value + * @param filename name of the uploaded file, NULL if not known + * @param content_type mime-type of the data, NULL if not known + * @param transfer_encoding encoding of the data, NULL if not known + * @param data pointer to size bytes of data at the + * specified offset + * @param off offset of data in the overall value + * @param size number of bytes in data available + * @return MHD_YES to continue iterating, + * MHD_NO to abort the iteration + */ +static int +post_iterator (void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, uint64_t off, size_t size) +{ + struct Request *request = cls; + + if (0 == strcmp ("domain", key)) + { + if (size + off >= sizeof(request->domain_name)) + size = sizeof (request->domain_name) - off - 1; + memcpy (&request->domain_name[off], + data, + size); + request->domain_name[size+off] = '\0'; + return MHD_YES; + } + if (0 == strcmp ("pkey", key)) + { + if (size + off >= sizeof(request->public_key)) + size = sizeof (request->public_key) - off - 1; + memcpy (&request->public_key[off], + data, + size); + request->public_key[size+off] = '\0'; + return MHD_YES; + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Unsupported form value `%s'\n"), + key); + return MHD_YES; +} + + +/** + * Task run whenever HTTP server operations are pending. + * + * @param cls unused + * @param tc scheduler context + */ +static void +do_httpd (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc); + + +/** + * Schedule task to run MHD server now. + */ +static void +run_httpd_now () +{ + if (GNUNET_SCHEDULER_NO_TASK != httpd_task) + { + GNUNET_SCHEDULER_cancel (httpd_task); + httpd_task = GNUNET_SCHEDULER_NO_TASK; + } + httpd_task = GNUNET_SCHEDULER_add_now (&do_httpd, NULL); +} + + +/** + * Continuation called to notify client about result of the + * operation. + * + * @param cls closure + * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate) + * GNUNET_NO if content was already there + * GNUNET_YES (or other positive value) on success + * @param emsg NULL on success, otherwise an error message + */ +static void +put_continuation (void *cls, + int32_t success, + const char *emsg) +{ + struct Request *request = cls; + + request->qe = NULL; + if (0 >= success) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to create record for domain `%s': %s\n"), + request->domain_name, + emsg); + request->phase = RP_FAIL; + } + else + request->phase = RP_SUCCESS; + run_httpd_now (); +} + + +/** + * Test if a name mapping was found, if so, refuse. If not, initiate storing of the record. + * + * @param cls closure + * @param zone_key public key of the zone + * @param expire when does the corresponding block in the DHT expire (until + * when should we never do a DHT lookup for the same name again)?; + * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore, + * or the expiration time of the block in the namestore (even if there are zero + * records matching the desired record type) + * @param name name that is being mapped (at most 255 characters long) + * @param rd_count number of entries in 'rd' array + * @param rd array of records with data to store + * @param signature signature of the record block, NULL if signature is unavailable (i.e. + * because the user queried for a particular record type only) + */ +static void +zone_to_name_cb (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct Request *request = cls; + struct GNUNET_NAMESTORE_RecordData r; + struct GNUNET_CRYPTO_ShortHashCode pub; + + request->qe = NULL; + if (NULL != name) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Found existing name `%s' for the given key\n"), + name); + request->phase = RP_FAIL; + run_httpd_now (); + return; + } + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_short_hash_from_string2 (request->public_key, + strlen (request->public_key), + &pub)); + r.data = &pub; + r.data_size = sizeof (pub); + r.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + r.record_type = GNUNET_NAMESTORE_TYPE_PKEY; + r.flags = GNUNET_NAMESTORE_RF_AUTHORITY; + request->qe = GNUNET_NAMESTORE_record_create (ns, + fcfs_zone_pkey, + request->domain_name, + &r, + &put_continuation, + request); +} + + +/** + * Process a record that was stored in the namestore. Used to check if + * the requested name already exists in the namestore. If not, + * proceed to check if the requested key already exists. + * + * @param cls closure + * @param zone_key public key of the zone + * @param expire when does the corresponding block in the DHT expire (until + * when should we never do a DHT lookup for the same name again)?; + * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore, + * or the expiration time of the block in the namestore (even if there are zero + * records matching the desired record type) + * @param name name that is being mapped (at most 255 characters long) + * @param rd_count number of entries in 'rd' array + * @param rd array of records with data to store + * @param signature signature of the record block, NULL if signature is unavailable (i.e. + * because the user queried for a particular record type only) + */ +static void +lookup_result_processor (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct Request *request = cls; + struct GNUNET_CRYPTO_ShortHashCode pub; + + request->qe = NULL; + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_short_hash_from_string2 (request->public_key, + strlen (request->public_key), + &pub)); + if (0 != rd_count) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Found %u existing records for domain `%s'\n"), + rd_count, + request->domain_name); + request->phase = RP_FAIL; + run_httpd_now (); + return; + } + request->qe = GNUNET_NAMESTORE_zone_to_name (ns, + &fcfsd_zone, + &pub, + &zone_to_name_cb, + request); +} + + +/** + * Main MHD callback for handling requests. + * + * @param cls unused + * @param connection MHD connection handle + * @param url the requested url + * @param method the HTTP method used ("GET", "PUT", etc.) + * @param version the HTTP version string (i.e. "HTTP/1.1") + * @param upload_data the data being uploaded (excluding HEADERS, + * for a POST that fits into memory and that is encoded + * with a supported encoding, the POST data will NOT be + * given in upload_data and is instead available as + * part of MHD_get_connection_values; very large POST + * data *will* be made available incrementally in + * upload_data) + * @param upload_data_size set initially to the size of the + * upload_data provided; the method must update this + * value to the number of bytes NOT processed; + * @param ptr pointer to location where we store the 'struct Request' + * @return MHD_YES if the connection was handled successfully, + * MHD_NO if the socket must be closed due to a serious + * error while handling the request + */ +static int +create_response (void *cls, + struct MHD_Connection *connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, + size_t *upload_data_size, + void **ptr) +{ + struct MHD_Response *response; + struct Request *request; + int ret; + struct GNUNET_CRYPTO_ShortHashCode pub; + + if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) || + (0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) ) + { + ret = serve_main_page (connection); + if (ret != MHD_YES) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to create page for `%s'\n"), + url); + return ret; + } + if (0 == strcmp (method, MHD_HTTP_METHOD_POST)) + { + request = *ptr; + if (NULL == request) + { + request = GNUNET_malloc (sizeof (struct Request)); + *ptr = request; + request->pp = MHD_create_post_processor (connection, 1024, + &post_iterator, request); + if (NULL == request->pp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to setup post processor for `%s'\n"), + url); + return MHD_NO; /* internal error */ + } + return MHD_YES; + } + if (NULL != request->pp) + { + /* evaluate POST data */ + MHD_post_process (request->pp, + upload_data, + *upload_data_size); + if (0 != *upload_data_size) + { + *upload_data_size = 0; + return MHD_YES; + } + /* done with POST data, serve response */ + MHD_destroy_post_processor (request->pp); + request->pp = NULL; + } + if (GNUNET_OK != + GNUNET_CRYPTO_short_hash_from_string2 (request->public_key, + strlen (request->public_key), + &pub)) + { + /* parse error */ + return fill_s_reply ("Failed to parse given public key", + request, connection); + } + switch (request->phase) + { + case RP_START: + request->phase = RP_LOOKUP; + request->qe = GNUNET_NAMESTORE_lookup_record (ns, + &fcfsd_zone, + request->domain_name, + GNUNET_NAMESTORE_TYPE_PKEY, + &lookup_result_processor, + request); + break; + case RP_LOOKUP: + break; + case RP_PUT: + break; + case RP_FAIL: + return fill_s_reply ("Request failed, sorry.", + request, connection); + case RP_SUCCESS: + return fill_s_reply ("Success.", + request, connection); + default: + GNUNET_break (0); + return MHD_NO; + } + return MHD_YES; /* will have a reply later... */ + } + /* unsupported HTTP method */ + response = MHD_create_response_from_buffer (strlen (METHOD_ERROR), + (void *) METHOD_ERROR, + MHD_RESPMEM_PERSISTENT); + ret = MHD_queue_response (connection, + MHD_HTTP_METHOD_NOT_ACCEPTABLE, + response); + MHD_destroy_response (response); + return ret; +} + + +/** + * Callback called upon completion of a request. + * Decrements session reference counter. + * + * @param cls not used + * @param connection connection that completed + * @param con_cls session handle + * @param toe status code + */ +static void +request_completed_callback (void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe) +{ + struct Request *request = *con_cls; + + if (NULL == request) + return; + if (NULL != request->pp) + MHD_destroy_post_processor (request->pp); + if (NULL != request->qe) + GNUNET_NAMESTORE_cancel (request->qe); + GNUNET_free (request); +} + + +/** + * Schedule tasks to run MHD server. + */ +static void +run_httpd () +{ + fd_set rs; + fd_set ws; + fd_set es; + struct GNUNET_NETWORK_FDSet *wrs; + struct GNUNET_NETWORK_FDSet *wws; + struct GNUNET_NETWORK_FDSet *wes; + int max; + int haveto; + unsigned MHD_LONG_LONG timeout; + struct GNUNET_TIME_Relative tv; + + FD_ZERO (&rs); + FD_ZERO (&ws); + FD_ZERO (&es); + wrs = GNUNET_NETWORK_fdset_create (); + wes = GNUNET_NETWORK_fdset_create (); + wws = GNUNET_NETWORK_fdset_create (); + max = -1; + GNUNET_assert (MHD_YES == MHD_get_fdset (httpd, &rs, &ws, &es, &max)); + haveto = MHD_get_timeout (httpd, &timeout); + if (haveto == MHD_YES) + tv.rel_value = (uint64_t) timeout; + else + tv = GNUNET_TIME_UNIT_FOREVER_REL; + GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); + GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); + GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); + httpd_task = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, + tv, wrs, wws, + &do_httpd, NULL); + GNUNET_NETWORK_fdset_destroy (wrs); + GNUNET_NETWORK_fdset_destroy (wws); + GNUNET_NETWORK_fdset_destroy (wes); +} + + +/** + * Task run whenever HTTP server operations are pending. + * + * @param cls unused + * @param tc scheduler context + */ +static void +do_httpd (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + httpd_task = GNUNET_SCHEDULER_NO_TASK; + MHD_run (httpd); + run_httpd (); +} + + +/** + * Task run on shutdown. Cleans up everything. + * + * @param cls unused + * @param tc scheduler context + */ +static void +do_shutdown (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (GNUNET_SCHEDULER_NO_TASK != httpd_task) + { + GNUNET_SCHEDULER_cancel (httpd_task); + httpd_task = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != ns) + { + GNUNET_NAMESTORE_disconnect (ns, GNUNET_NO); + ns = NULL; + } + if (NULL != httpd) + { + MHD_stop_daemon (httpd); + httpd = NULL; + } + if (NULL != fcfs_zone_pkey) + { + GNUNET_CRYPTO_rsa_key_free (fcfs_zone_pkey); + fcfs_zone_pkey = NULL; + } +} + + +/** + * Main function that will be run. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *keyfile; + unsigned long long port; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, + "fcfsd", + "HTTPPORT", + &port)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Option `%s' not specified in configuration section `%s'\n"), + "HTTPPORT", + "fcfsd"); + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + "fcfsd", + "ZONEKEY", + &keyfile)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Option `%s' not specified in configuration section `%s'\n"), + "ZONEKEY", + "fcfsd"); + return; + } + fcfs_zone_pkey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); + GNUNET_free (keyfile); + if (NULL == fcfs_zone_pkey) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to read or create private zone key\n")); + return; + } + GNUNET_CRYPTO_rsa_key_get_public (fcfs_zone_pkey, + &pub); + GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &fcfsd_zone); + ns = GNUNET_NAMESTORE_connect (cfg); + if (NULL == ns) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to namestore\n")); + return; + } + httpd = MHD_start_daemon (MHD_USE_DEBUG, + (uint16_t) port, + NULL, NULL, + &create_response, NULL, + MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128, + MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 1, + MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, + MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (4 * 1024), + MHD_OPTION_NOTIFY_COMPLETED, &request_completed_callback, NULL, + MHD_OPTION_END); + if (NULL == httpd) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to start HTTP server\n")); + GNUNET_NAMESTORE_disconnect (ns, GNUNET_NO); + ns = NULL; + return; + } + run_httpd (); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &do_shutdown, NULL); +} + + +/** + * The main function for the fcfs daemon. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + int ret; + + GNUNET_log_setup ("fcfsd", "WARNING", NULL); + ret = + (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "fcfsd", + _("GNUnet GNS first come first serve registration service"), + options, + &run, NULL)) ? 0 : 1; + + return ret; +} + +/* end of gnunet-gns-fcfsd.c */ diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c new file mode 100644 index 0000000..876f531 --- /dev/null +++ b/src/gns/gnunet-gns-proxy.c @@ -0,0 +1,815 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "platform.h" +#include +#include +#include "gns_proxy_proto.h" +#include "gns.h" + +#define GNUNET_GNS_PROXY_PORT 7777 + +//TODO maybe make this an api call +/** + * Checks if name is in tld + * + * @param name the name to check + * @param tld the TLD to check for + * @return GNUNET_YES or GNUNET_NO + */ +int +is_tld(const char* name, const char* tld) +{ + int offset = 0; + + if (strlen(name) <= strlen(tld)) + { + return GNUNET_NO; + } + + offset = strlen(name)-strlen(tld); + if (strcmp (name+offset, tld) != 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "%s is not in .%s TLD\n", name, tld); + return GNUNET_NO; + } + + return GNUNET_YES; +} + +struct Socks5Request +{ + struct GNUNET_NETWORK_Handle *sock; + struct GNUNET_NETWORK_Handle *remote_sock; + + int state; + + GNUNET_SCHEDULER_TaskIdentifier rtask; + GNUNET_SCHEDULER_TaskIdentifier fwdrtask; + GNUNET_SCHEDULER_TaskIdentifier wtask; + GNUNET_SCHEDULER_TaskIdentifier fwdwtask; + + char rbuf[2048]; + char wbuf[2048]; + unsigned int rbuf_len; + unsigned int wbuf_len; +}; + +unsigned long port = GNUNET_GNS_PROXY_PORT; +static struct GNUNET_NETWORK_Handle *lsock; +GNUNET_SCHEDULER_TaskIdentifier ltask; +static struct MHD_Daemon *httpd; +static GNUNET_SCHEDULER_TaskIdentifier httpd_task; + +static int +con_val_iter (void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *value) +{ + char* buf = (char*)cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s:%s\n", key, value); + + if (0 == strcmp ("Host", key)) + { + strcpy (buf, value); + return MHD_NO; + } + return MHD_YES; +} + +/** + * Main MHD callback for handling requests. + * + * @param cls unused + * @param connection MHD connection handle + * @param method the HTTP method used ("GET", "PUT", etc.) + * @param version the HTTP version string (i.e. "HTTP/1.1") + * @param upload_data the data being uploaded (excluding HEADERS, + * for a POST that fits into memory and that is encoded + * with a supported encoding, the POST data will NOT be + * given in upload_data and is instead available as + * part of MHD_get_connection_values; very large POST + * data *will* be made available incrementally in + * upload_data) + * @param upload_data_size set initially to the size of the + * upload_data provided; the method must update this + * value to the number of bytes NOT processed; + * @param ptr pointer to location where we store the 'struct Request' + * @return MHD_YES if the connection was handled successfully, + * MHD_NO if the socket must be closed due to a serious + * error while handling the request + */ +static int +create_response (void *cls, + struct MHD_Connection *con, + const char *url, + const char *meth, + const char *ver, + const char *upload_data, + size_t *upload_data_size, + void **con_cls) +{ + static int dummy; + const char* page = "gnoxy"\ + "gnoxy demo"; + struct MHD_Response *response; + char host[265]; + int ret; + + if (0 != strcmp (meth, "GET")) + return MHD_NO; + if (&dummy != *con_cls) + { + *con_cls = &dummy; + return MHD_YES; + } + + if (0 != *upload_data_size) + return MHD_NO; + + *con_cls = NULL; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "url %s\n", url); + + MHD_get_connection_values (con, + MHD_HEADER_KIND, + &con_val_iter, host); + + response = MHD_create_response_from_buffer (strlen (page), + (void*)page, + MHD_RESPMEM_PERSISTENT); + ret = MHD_queue_response (con, + MHD_HTTP_OK, + response); + MHD_destroy_response (response); + return ret; +} + +/** + * Task run whenever HTTP server operations are pending. + * + * @param cls unused + * @param tc sched context + */ +static void +do_httpd (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc); + +/** + * Schedule MHD + */ +static void +run_httpd () +{ + fd_set rs; + fd_set ws; + fd_set es; + struct GNUNET_NETWORK_FDSet *wrs; + struct GNUNET_NETWORK_FDSet *wws; + struct GNUNET_NETWORK_FDSet *wes; + int max; + int haveto; + unsigned MHD_LONG_LONG timeout; + struct GNUNET_TIME_Relative tv; + + FD_ZERO (&rs); + FD_ZERO (&ws); + FD_ZERO (&es); + wrs = GNUNET_NETWORK_fdset_create (); + wes = GNUNET_NETWORK_fdset_create (); + wws = GNUNET_NETWORK_fdset_create (); + max = -1; + GNUNET_assert (MHD_YES == MHD_get_fdset (httpd, &rs, &ws, &es, &max)); + haveto = MHD_get_timeout (httpd, &timeout); + + if (haveto == MHD_YES) + tv.rel_value = (uint64_t) timeout; + else + tv = GNUNET_TIME_UNIT_FOREVER_REL; + GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); + GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); + GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); + + if (httpd_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (httpd_task); + httpd_task = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, + tv, wrs, wws, + &do_httpd, NULL); + GNUNET_NETWORK_fdset_destroy (wrs); + GNUNET_NETWORK_fdset_destroy (wws); + GNUNET_NETWORK_fdset_destroy (wes); +} + +/** + * Task run whenever HTTP server operations are pending. + * + * @param cls unused + * @param tc sched context + */ +static void +do_httpd (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + httpd_task = GNUNET_SCHEDULER_NO_TASK; + MHD_run (httpd); + run_httpd (); +} + +/** + * Read data from socket + * + * @param cls the closure + * @param tc scheduler context + */ +static void +do_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + +/** + * Read from remote end + * + * @param cls closure + * @param tc scheduler context + */ +static void +do_read_remote (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + +/** + * Write data to remote socket + * + * @param cls the closure + * @param tc scheduler context + */ +static void +do_write_remote (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Socks5Request *s5r = cls; + unsigned int len; + + s5r->fwdwtask = GNUNET_SCHEDULER_NO_TASK; + + if ((NULL != tc->read_ready) && + (GNUNET_NETWORK_fdset_isset (tc->write_ready, s5r->remote_sock)) && + (len = GNUNET_NETWORK_socket_send (s5r->remote_sock, s5r->rbuf, + s5r->rbuf_len))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Successfully sent %d bytes to remote socket\n", + len); + } + else + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write remote"); + //Really!?!?!? + if (s5r->rtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->rtask); + if (s5r->wtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->wtask); + if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdrtask); + GNUNET_NETWORK_socket_close (s5r->remote_sock); + GNUNET_NETWORK_socket_close (s5r->sock); + GNUNET_free(s5r); + return; + } + + s5r->rtask = + GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_read, s5r); +} + + +/** + * Write data to socket + * + * @param cls the closure + * @param tc scheduler context + */ +static void +do_write (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Socks5Request *s5r = cls; + unsigned int len; + + s5r->wtask = GNUNET_SCHEDULER_NO_TASK; + + if ((NULL != tc->read_ready) && + (GNUNET_NETWORK_fdset_isset (tc->write_ready, s5r->sock)) && + (len = GNUNET_NETWORK_socket_send (s5r->sock, s5r->wbuf, + s5r->wbuf_len))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Successfully sent %d bytes to socket\n", + len); + } + else + { + + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write"); + //Really!?!?!? + if (s5r->rtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->rtask); + if (s5r->fwdwtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdwtask); + if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdrtask); + GNUNET_NETWORK_socket_close (s5r->remote_sock); + GNUNET_NETWORK_socket_close (s5r->sock); + GNUNET_free(s5r); + return; + } + + if ((s5r->state == SOCKS5_DATA_TRANSFER) && + (s5r->fwdrtask == GNUNET_SCHEDULER_NO_TASK)) + s5r->fwdrtask = + GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->remote_sock, + &do_read_remote, s5r); +} + +/** + * Read from remote end + * + * @param cls closure + * @param tc scheduler context + */ +static void +do_read_remote (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Socks5Request *s5r = cls; + + s5r->fwdrtask = GNUNET_SCHEDULER_NO_TASK; + + + if ((NULL != tc->write_ready) && + (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->remote_sock)) && + (s5r->wbuf_len = GNUNET_NETWORK_socket_recv (s5r->remote_sock, s5r->wbuf, + sizeof (s5r->wbuf)))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Successfully read %d bytes from remote socket\n", + s5r->wbuf_len); + } + else + { + if (s5r->wbuf_len == 0) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "0 bytes received from remote... graceful shutdown!\n"); + if (s5r->fwdwtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdwtask); + if (s5r->rtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->rtask); + + GNUNET_NETWORK_socket_close (s5r->remote_sock); + s5r->remote_sock = NULL; + GNUNET_NETWORK_socket_close (s5r->sock); + GNUNET_free(s5r); + + return; + } + + s5r->wtask = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_write, s5r); + +} + + +static int +add_handle_to_mhd (struct GNUNET_NETWORK_Handle *h) +{ + int fd; + struct sockaddr *addr; + socklen_t len; + + fd = GNUNET_NETWORK_get_fd (h); + addr = GNUNET_NETWORK_get_addr (h); + len = GNUNET_NETWORK_get_addrlen (h); + + return MHD_add_connection (httpd, fd, addr, len); +} + +/** + * Read data from incoming connection + * + * @param cls the closure + * @param tc the scheduler context + */ +static void +do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Socks5Request *s5r = cls; + struct socks5_client_hello *c_hello; + struct socks5_server_hello *s_hello; + struct socks5_client_request *c_req; + struct socks5_server_response *s_resp; + + char domain[256]; + uint8_t dom_len; + uint16_t req_port; + struct hostent *phost; + uint32_t remote_ip; + struct sockaddr_in remote_addr; + struct in_addr *r_sin_addr; + + s5r->rtask = GNUNET_SCHEDULER_NO_TASK; + + if ((NULL != tc->write_ready) && + (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->sock)) && + (s5r->rbuf_len = GNUNET_NETWORK_socket_recv (s5r->sock, s5r->rbuf, + sizeof (s5r->rbuf)))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Successfully read %d bytes from socket\n", + s5r->rbuf_len); + } + else + { + if (s5r->rbuf_len != 0) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "read"); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disco!\n"); + + if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdrtask); + if (s5r->wtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->wtask); + if (s5r->fwdwtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdwtask); + GNUNET_NETWORK_socket_close (s5r->remote_sock); + GNUNET_NETWORK_socket_close (s5r->sock); + GNUNET_free(s5r); + return; + } + + if (s5r->state == SOCKS5_INIT) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "SOCKS5 init\n"); + c_hello = (struct socks5_client_hello*)&s5r->rbuf; + + GNUNET_assert (c_hello->version == SOCKS_VERSION_5); + + s_hello = (struct socks5_server_hello*)&s5r->wbuf; + s5r->wbuf_len = sizeof( struct socks5_server_hello ); + + s_hello->version = c_hello->version; + s_hello->auth_method = SOCKS_AUTH_NONE; + + /* Write response to client */ + s5r->wtask = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_write, s5r); + + s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_read, s5r); + + s5r->state = SOCKS5_REQUEST; + return; + } + + if (s5r->state == SOCKS5_REQUEST) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Processing SOCKS5 request\n"); + c_req = (struct socks5_client_request*)&s5r->rbuf; + s_resp = (struct socks5_server_response*)&s5r->wbuf; + //Only 10byte for ipv4 response! + s5r->wbuf_len = 10;//sizeof (struct socks5_server_response); + + GNUNET_assert (c_req->addr_type == 3); + + dom_len = *((uint8_t*)(&(c_req->addr_type) + 1)); + memset(domain, 0, sizeof(domain)); + strncpy(domain, (char*)(&(c_req->addr_type) + 2), dom_len); + req_port = *((uint16_t*)(&(c_req->addr_type) + 2 + dom_len)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Requested connection is %s:%d\n", + domain, + ntohs(req_port)); + + if (is_tld (domain, GNUNET_GNS_TLD) || + is_tld (domain, GNUNET_GNS_TLD_ZKEY)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Requested connection is gnunet tld\n", + domain); + + if (NULL == httpd) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to start HTTP server\n")); + s_resp->version = 0x05; + s_resp->reply = 0x01; + s5r->wtask = + GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_write, s5r); + //ERROR! + //TODO! close socket after the write! schedule task + //GNUNET_NETWORK_socket_close (s5r->sock); + //GNUNET_free(s5r); + return; + } + + if (MHD_YES == add_handle_to_mhd ( s5r->sock )) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sucessfully added client to MHD!\n"); + s_resp->version = 0x05; + s_resp->reply = 0x00; + s_resp->reserved = 0x00; + s_resp->addr_type = 0x01; + + s5r->wtask = + GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_write, s5r); + run_httpd (); + //GNUNET_free ( s5r ); + //FIXME complete socks resp! + return; + } + else + { + phost = (struct hostent*)gethostbyname (domain); + if (phost == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Resolve %s error!\n", domain ); + s_resp->version = 0x05; + s_resp->reply = 0x01; + s5r->wtask = + GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_write, s5r); + //ERROR! + //TODO! close socket after the write! schedule task + //GNUNET_NETWORK_socket_close (s5r->sock); + //GNUNET_free(s5r); + return; + } + + s5r->remote_sock = GNUNET_NETWORK_socket_create (AF_INET, + SOCK_STREAM, + 0); + r_sin_addr = (struct in_addr*)(phost->h_addr); + remote_ip = r_sin_addr->s_addr; + memset(&remote_addr, 0, sizeof(remote_addr)); + remote_addr.sin_family = AF_INET; +#if HAVE_SOCKADDR_IN_SIN_LEN + remote_addr.sin_len = sizeof (remote_addr); +#endif + remote_addr.sin_addr.s_addr = remote_ip; + remote_addr.sin_port = req_port; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "target server: %s:%u\n", inet_ntoa(remote_addr.sin_addr), + ntohs(req_port)); + + if ((GNUNET_OK != + GNUNET_NETWORK_socket_connect ( s5r->remote_sock, + (const struct sockaddr*)&remote_addr, + sizeof (remote_addr))) + && (errno != EINPROGRESS)) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "socket request error...\n"); + s_resp->version = 0x05; + s_resp->reply = 0x01; + s5r->wtask = + GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_write, s5r); + //TODO see above + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "new remote connection\n"); + + s_resp->version = 0x05; + s_resp->reply = 0x00; + s_resp->reserved = 0x00; + s_resp->addr_type = 0x01; + + s5r->state = SOCKS5_DATA_TRANSFER; + + s5r->wtask = + GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_write, s5r); + s5r->rtask = + GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_read, s5r); + + } + return; + } + + if (s5r->state == SOCKS5_DATA_TRANSFER) + { + if ((s5r->remote_sock == NULL) || (s5r->rbuf_len == 0)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Closing connection to client\n"); + if (s5r->rtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->rtask); + if (s5r->fwdwtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdwtask); + if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdrtask); + if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (s5r->fwdrtask); + + if (s5r->remote_sock != NULL) + GNUNET_NETWORK_socket_close (s5r->remote_sock); + GNUNET_NETWORK_socket_close (s5r->sock); + GNUNET_free(s5r); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "forwarding %d bytes from client\n", s5r->rbuf_len); + + s5r->fwdwtask = + GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->remote_sock, + &do_write_remote, s5r); + + if (s5r->fwdrtask == GNUNET_SCHEDULER_NO_TASK) + { + s5r->fwdrtask = + GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->remote_sock, + &do_read_remote, s5r); + } + + + } + + //GNUNET_CONTAINER_DLL_remove (s5conns.head, s5conns.tail, s5r); + +} + +/** + * Accept new incoming connections + * + * @param cls the closure + * @param tc the scheduler context + */ +static void +do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_NETWORK_Handle *s; + struct Socks5Request *s5r; + + ltask = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + + ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + lsock, + &do_accept, NULL); + + s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); + + if (NULL == s) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept"); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got an inbound connection, waiting for data\n"); + + s5r = GNUNET_malloc (sizeof (struct Socks5Request)); + s5r->sock = s; + s5r->state = SOCKS5_INIT; + s5r->wtask = GNUNET_SCHEDULER_NO_TASK; + s5r->fwdwtask = GNUNET_SCHEDULER_NO_TASK; + s5r->fwdrtask = GNUNET_SCHEDULER_NO_TASK; + s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + s5r->sock, + &do_read, s5r); + //GNUNET_CONTAINER_DLL_insert (s5conns.head, s5conns.tail, s5r); +} + +/** + * Main function that will be run + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct sockaddr_in sa; + + memset (&sa, 0, sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons (port); +#if HAVE_SOCKADDR_IN_SIN_LEN + sa.sin_len = sizeof (sa); +#endif + + lsock = GNUNET_NETWORK_socket_create (AF_INET, + SOCK_STREAM, + 0); + + if ((NULL == lsock) || + (GNUNET_OK != + GNUNET_NETWORK_socket_bind (lsock, (const struct sockaddr *) &sa, + sizeof (sa)))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to create listen socket bound to `%s'", + GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa))); + if (NULL != lsock) + GNUNET_NETWORK_socket_close (lsock); + return; + } + + if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock, 5)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to listen on socket bound to `%s'", + GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa))); + return; + } + + ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, + lsock, &do_accept, NULL); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Proxy listens on port %u\n", + port); + + httpd = MHD_start_daemon (MHD_USE_DEBUG, 4444, + NULL, NULL, + &create_response, NULL, + MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128, + MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, + MHD_OPTION_NOTIFY_COMPLETED, + NULL, NULL, + MHD_OPTION_END); + run_httpd (); + +} + +/** + * The main function for gnunet-gns-proxy. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'p', "port", NULL, + gettext_noop ("listen on specified port"), 1, + &GNUNET_GETOPT_set_string, &port}, + GNUNET_GETOPT_OPTION_END + }; + + int ret; + + GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL); + ret = + (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy", + _("GNUnet GNS proxy"), + options, + &run, NULL)) ? 0 : 1; + return ret; +} diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c new file mode 100644 index 0000000..ca3a594 --- /dev/null +++ b/src/gns/gnunet-gns.c @@ -0,0 +1,262 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gnunet-gns.c + * @brief command line tool to access distributed GNS + * @author Christian Grothoff + * + * TODO: + * - everything + */ +#include "platform.h" +#include +#include +#include +#include + +/** + * Handle to GNS service. + */ +static struct GNUNET_GNS_Handle *gns; + +/** + * GNS name to shorten. (-s option) + */ +static char *shorten_name; + +/** + * GNS name to lookup. (-u option) + */ +static char *lookup_name; + + +/** + * record type to look up (-t option) + */ +static char *lookup_type; + +/** + * name to look up authority for (-a option) + */ +static char *auth_name; + +/** + * raw output + */ +static int raw = 0; + +static enum GNUNET_GNS_RecordType rtype; + +/** + * Task run on shutdown. Cleans up everything. + * + * @param cls unused + * @param tc scheduler context + */ +static void +do_shutdown (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (NULL != gns) + { + GNUNET_GNS_disconnect (gns); + gns = NULL; + } +} + + +static void +process_shorten_result(void* cls, const char* nshort) +{ + if (raw) + printf("%s", nshort); + else + printf("%s shortened to %s\n", (char*) cls, nshort); + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); +} + +static void +process_lookup_result(void* cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + int i; + char* name = (char*) cls; + const char* typename; + char* string_val; + + if (!raw) { + if (rd_count == 0) + printf("No results.\n"); + else + printf("%s:\n", name); + } + + + + for (i=0; iget_handle); - rh->get_handle = NULL; - num_records = ntohl(nrb->rd_count); - struct GNUNET_NAMESTORE_RecordData rd[num_records]; - name = (char*)&nrb[1]; - rb = (struct GNSRecordBlock *)&name[strlen(name) + 1]; - - for (i=0; itype); - rd[i].data_size = ntohl(rb->data_length); - rd[i].data = &rb[1]; - rd[i].expiration = GNUNET_TIME_absolute_ntoh(rb->expiration); - rd[i].flags = ntohl(rb->flags); - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got name: %s (wanted %s)\n", name, rh->authority_name); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got type: %d raw %d (wanted %d)\n", - rd[i].record_type, rb->type, GNUNET_GNS_RECORD_PKEY); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got data length: %d\n", rd[i].data_size); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got flag %d\n", rd[i].flags); + nrb->signature = *signature; + + nrb->public_key = *key; - if ((strcmp(name, rh->authority_name) == 0) && - (rd[i].record_type == GNUNET_GNS_RECORD_PKEY)) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Authority found in DHT\n"); - rh->answered = 1; - GNUNET_CRYPTO_hash( - (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *)rd[i].data, - rd[i].data_size, - &rh->authority); - } - rb = (struct GNSRecordBlock*)((char*)&rb[1] + rd[i].data_size); + nrb->rd_count = htonl(rd_count); + + memcpy(&nrb[1], name, namelen); - } + nrb_data = (char*)&nrb[1]; + nrb_data += namelen; - GNUNET_CRYPTO_hash(name, strlen(name), &name_hash); - GNUNET_CRYPTO_hash_xor(key, &name_hash, &zone); + rd_payload_length += sizeof(struct GNSNameRecordBlock) + namelen; - /* Save to namestore */ - if (0 == GNUNET_CRYPTO_hash_cmp(&zone_hash, &zone)) - { - GNUNET_NAMESTORE_record_put (namestore_handle, - &nrb->public_key, - name, - exp, - num_records, - rd, - &nrb->signature, - &on_namestore_record_put_result, //cont - NULL); //cls - } - - if (rh->answered) + if (-1 == GNUNET_NAMESTORE_records_serialize (rd_count, + rd, + rd_payload_length, + nrb_data)) { - rh->answered = 0; - resolve_name(rh); + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Record serialization failed! Skipping...\n"); + GNUNET_free(nrb); + zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_next, + NULL); return; } - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "No authority in records\n"); - reply_to_dns(rh, 0, NULL); + + + /* + * calculate DHT key: H(name) xor H(pubkey) + */ + GNUNET_CRYPTO_short_hash(key, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zhash); + GNUNET_CRYPTO_short_hash(name, strlen(name), &name_hash); + GNUNET_CRYPTO_short_hash_double (&name_hash, &name_hash_double); + GNUNET_CRYPTO_short_hash_double (&zhash, &zone_hash_double); + GNUNET_CRYPTO_hash_xor(&zone_hash_double, &name_hash_double, &xor_hash); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "zone identity: %s\n", GNUNET_h2s (&zone_hash_double)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "putting records for %s under key: %s with size %d\n", + name, GNUNET_h2s (&xor_hash), rd_payload_length); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "DHT req to %d\n", DHT_OPERATION_TIMEOUT.rel_value); + /* FIXME: keep return value to possibly cancel? */ + GNUNET_DHT_put (dht_handle, &xor_hash, + DHT_GNS_REPLICATION_LEVEL, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + rd_payload_length, + (char*)nrb, + expiration, + DHT_OPERATION_TIMEOUT, + &record_dht_put, + NULL); //cls for cont + + num_public_records++; + + /** + * Reschedule periodic put + */ + zone_update_taskid = GNUNET_SCHEDULER_add_delayed (record_put_interval, + &update_zone_dht_next, + NULL); + + GNUNET_free(nrb); + } /** - * Start DHT lookup for a name -> PKEY (compare NS) record in - * query->authority's zone + * Periodically iterate over our zone and store everything in dht * - * @param rh the pending gns query - * @param name the name of the PKEY record + * @param cls NULL + * @param tc task context */ -void -resolve_authority_dht(struct GNUNET_GNS_ResolverHandle *rh) +static void +update_zone_dht_start(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - uint32_t xquery; - struct GNUNET_TIME_Relative timeout; - GNUNET_HashCode name_hash; - GNUNET_HashCode lookup_key; + unsigned long long interval = 0; - GNUNET_CRYPTO_hash(rh->authority_name, - strlen(rh->authority_name), - &name_hash); - GNUNET_CRYPTO_hash_xor(&name_hash, &rh->authority, &lookup_key); + zone_update_taskid = GNUNET_SCHEDULER_NO_TASK; - timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5); - - xquery = htonl(GNUNET_GNS_RECORD_PKEY); - //FIXME how long to wait for results? - rh->get_handle = GNUNET_DHT_get_start(dht_handle, timeout, - GNUNET_BLOCK_TYPE_GNS_NAMERECORD, - &lookup_key, - 5, //Replication level FIXME - GNUNET_DHT_RO_NONE, - &xquery, - sizeof(xquery), - &process_authority_dht_result, - rh); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Scheduling DHT zone update!\n"); + if (0 == num_public_records) + { + /** + * If no records are known (startup) or none present + * we can safely set the interval to 1s + */ + record_put_interval = GNUNET_TIME_relative_multiply( + GNUNET_TIME_UNIT_SECONDS, + 1); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "No records in db. Adjusted record put interval to 1s\n"); + } + else + { + interval = max_record_put_interval/num_public_records; + if (interval == 0) + interval = 1; + record_put_interval = GNUNET_TIME_relative_multiply( + GNUNET_TIME_UNIT_SECONDS, + interval); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Adjusted DHT update interval to %ds!\n", + interval); + } + /* start counting again */ + num_public_records = 0; + namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle, + NULL, //All zones + GNUNET_NAMESTORE_RF_AUTHORITY, + GNUNET_NAMESTORE_RF_PRIVATE, + &put_gns_record, + NULL); } /** - * Function called when we get a result from the dht - * for our query + * Lookup the private key for the zone * - * @param cls the request handle - * @param exp lifetime - * @param key the key the record was stored under - * @param get_path get path - * @param get_path_length get path length - * @param put_path put path - * @param put_path_length put path length - * @param type the block type - * @param size the size of the record - * @param data the record data + * @param zone the zone we want a private key for + * @return NULL of not found else the key */ -void -process_name_dht_result(void* cls, - struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length, - enum GNUNET_BLOCK_Type type, - size_t size, const void *data) +struct GNUNET_CRYPTO_RsaPrivateKey* +lookup_private_key(struct GNUNET_CRYPTO_ShortHashCode *zone) { - struct GNUNET_GNS_ResolverHandle *rh; - struct GNSNameRecordBlock *nrb; - struct GNSRecordBlock *rb; - uint32_t num_records; - char* name = NULL; - int i; - GNUNET_HashCode zone, name_hash; - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "got dht result (size=%d)\n", size); + char* keydir; + struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename; + char* location; + struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL; - if (data == NULL) - return; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Looking for private key\n"); - //FIXME maybe check expiration here, check block type - - rh = (struct GNUNET_GNS_ResolverHandle *)cls; - nrb = (struct GNSNameRecordBlock*)data; + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (GNS_cfg, + "namestore", + "ZONEFILE_DIRECTORY", &keydir)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "No zonefile directory!\n"); + return NULL; + } - GNUNET_DHT_get_stop (rh->get_handle); - rh->get_handle = NULL; - num_records = ntohl(nrb->rd_count); - struct GNUNET_NAMESTORE_RecordData rd[num_records]; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Zonefile directory is %s\n", keydir); - name = (char*)&nrb[1]; - rb = (struct GNSRecordBlock*)&name[strlen(name) + 1]; - - for (i=0; itype); - rd[i].data_size = ntohl(rb->data_length); - rd[i].data = (char*)&rb[1]; - rd[i].expiration = GNUNET_TIME_absolute_ntoh(rb->expiration); - rd[i].flags = ntohl(rb->flags); - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got name: %s (wanted %s)\n", name, rh->name); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got type: %d raw %d (wanted %d)\n", - rd[i].record_type, rb->type, rh->query->type); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got data length: %d\n", rd[i].data_size); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got flag %d\n", rd[i].flags); - - /* FIXME class? */ - if ((strcmp(name, rh->name) == 0) && - (rd[i].record_type == rh->query->type)) - { - rh->answered++; - } + GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename); - rb = (struct GNSRecordBlock*)((char*)&rb[1] + rd[i].data_size); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Zonefile is %s.zkey\n", &zonename); - } + GNUNET_asprintf(&location, "%s%s%s.zkey", keydir, + DIR_SEPARATOR_STR, &zonename); - GNUNET_CRYPTO_hash(name, strlen(name), &name_hash); - GNUNET_CRYPTO_hash_xor(key, &name_hash, &zone); - - /** - * FIXME check pubkey against existing key in namestore? - * https://gnunet.org/bugs/view.php?id=2179 - */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Checking for %s\n", location); - /* Save to namestore */ - GNUNET_NAMESTORE_record_put (namestore_handle, - &nrb->public_key, - name, - exp, - num_records, - rd, - &nrb->signature, - &on_namestore_record_put_result, //cont - NULL); //cls - - if (rh->answered) - reply_to_dns(rh, num_records, rd); - else - reply_to_dns(rh, 0, NULL); + if (GNUNET_YES == GNUNET_DISK_file_test (location)) + key = GNUNET_CRYPTO_rsa_key_create_from_file (location); + + GNUNET_free(location); + GNUNET_free(keydir); + + return key; } +/* END DHT ZONE PROPAGATION */ + /** - * Start DHT lookup for a (name -> query->record_type) record in - * query->authority's zone - * - * @param rh the pending gns query context - * @param name the name to query record + * Send shorten response back to client + * + * @param cls the closure containing a client shorten handle + * @param name the shortened name result or NULL if cannot be shortened */ -void -resolve_name_dht(struct GNUNET_GNS_ResolverHandle *rh, const char* name) +static void +send_shorten_response(void* cls, const char* name) { - uint32_t xquery; - struct GNUNET_TIME_Relative timeout; - GNUNET_HashCode name_hash; - GNUNET_HashCode lookup_key; - struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string; - - GNUNET_CRYPTO_hash(name, strlen(name), &name_hash); - GNUNET_CRYPTO_hash_xor(&name_hash, &rh->authority, &lookup_key); - GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %s\n", + "SHORTEN_RESULT", name); + struct GNUNET_GNS_ClientShortenResultMessage *rmsg; + struct ClientShortenHandle *csh = (struct ClientShortenHandle *)cls; - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "starting dht lookup for %s with key: %s\n", - name, (char*)&lookup_key_string); + if (name == NULL) + { + name = ""; + } - timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5); + rmsg = GNUNET_malloc(sizeof(struct GNUNET_GNS_ClientShortenResultMessage) + + strlen(name) + 1); + + rmsg->id = csh->unique_id; + rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT); + rmsg->header.size = + htons(sizeof(struct GNUNET_GNS_ClientShortenResultMessage) + + strlen(name) + 1); + + strcpy((char*)&rmsg[1], name); + + GNUNET_SERVER_notification_context_unicast (nc, csh->client, + (const struct GNUNET_MessageHeader *) rmsg, + GNUNET_NO); + GNUNET_SERVER_receive_done (csh->client, GNUNET_OK); - xquery = htonl(rh->query->type); - //FIXME how long to wait for results? - rh->get_handle = GNUNET_DHT_get_start(dht_handle, timeout, - GNUNET_BLOCK_TYPE_GNS_NAMERECORD, - &lookup_key, - 5, //Replication level FIXME - GNUNET_DHT_RO_NONE, - &xquery, //xquery FIXME is this bad? - sizeof(xquery), - &process_name_dht_result, - rh); + GNUNET_free(rmsg); + GNUNET_free_non_null(csh->name); + GNUNET_free_non_null(csh->zone_key); + GNUNET_free(csh); } -//Prototype -void -resolve_name(struct GNUNET_GNS_ResolverHandle *rh); - /** - * This is a callback function that should give us only PKEY - * records. Used to query the namestore for the authority (PKEY) - * for 'name' + * Handle a shorten message from the api * - * @param cls the pending query - * @param key the key of the zone we did the lookup - * @param expiration expiration date of the record data set in the namestore - * @param name the name for which we need an authority - * @param rd_count the number of records with 'name' - * @param rd the record data - * @param signature the signature of the authority for the record data + * @param cls the closure + * @param client the client + * @param message the message */ -void -process_authority_lookup(void* cls, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, - struct GNUNET_TIME_Absolute expiration, - const char *name, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) +static void handle_shorten(void *cls, + struct GNUNET_SERVER_Client * client, + const struct GNUNET_MessageHeader * message) { - struct GNUNET_GNS_ResolverHandle *rh; - struct GNUNET_TIME_Relative remaining_time; - GNUNET_HashCode zone; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "SHORTEN"); - rh = (struct GNUNET_GNS_ResolverHandle *)cls; - GNUNET_CRYPTO_hash(key, - sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &zone); - remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); - - /** - * No authority found in namestore. - */ - if (rd_count == 0) + size_t msg_size = 0; + struct ClientShortenHandle *csh; + char name[MAX_DNS_NAME_LENGTH]; + char* nameptr = name; + struct GNUNET_CRYPTO_ShortHashCode zone; + struct GNUNET_CRYPTO_RsaPrivateKey *key; + + if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientShortenMessage)) { - /** - * We did not find an authority in the namestore - * _IF_ the current authoritative zone is us we cannot resolve - * _ELSE_ we can still check the _expired_ dht - */ - if (0 != GNUNET_CRYPTO_hash_cmp(&zone, &zone_hash) && - (remaining_time.rel_value == 0)) - { - resolve_authority_dht(rh); - return; - } - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Authority %s unknown\n", - rh->authority_name); - reply_to_dns(rh, 0, NULL); + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } - //Note only 1 pkey should have been returned.. anything else would be strange - /** - * We found an authority that may be able to help us - * move on with query - */ - int i; - for (i=0; iauthority); - resolve_name(rh); - return; - + msg_size = ntohs(message->size); + + if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; } - - /** - * no answers found - */ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Authority lookup successful but no PKEY... never get here\n"); - reply_to_dns(rh, 0, NULL); -} + csh = GNUNET_malloc(sizeof(struct ClientShortenHandle)); + csh->client = client; + csh->unique_id = sh_msg->id; + csh->zone_key = NULL; + + GNUNET_STRINGS_utf8_tolower((char*)&sh_msg[1], &nameptr); -/** - * Reply to client with the result from our lookup. - * - * @param rh the request handle of the lookup - * @param rd_count the number of records to return - * @param rd the record data - */ -void -reply_to_dns(struct GNUNET_GNS_ResolverHandle *rh, uint32_t rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd) -{ - int i; - size_t len; - int ret; - char *buf; - struct GNUNET_DNSPARSER_Packet *packet = rh->packet; - struct GNUNET_DNSPARSER_Record answer_records[rh->answered]; - struct GNUNET_DNSPARSER_Record additional_records[rd_count-(rh->answered)]; - packet->answers = answer_records; - packet->additional_records = additional_records; + if (strlen (name) < strlen(GNUNET_GNS_TLD)) { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "SHORTEN: %s is too short", name); + csh->name = NULL; + send_shorten_response(csh, name); + return; + } + + if (strlen (name) > MAX_DNS_NAME_LENGTH) { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "SHORTEN: %s is too long", name); + csh->name = NULL; + send_shorten_response(csh, name); + return; + } - /** - * Put records in the DNS packet and modify it - * to a response - */ - len = sizeof(struct GNUNET_DNSPARSER_Record*); - for (i=0; i < rd_count; i++) + if (!is_gnunet_tld(name) && !is_zkey_tld(name)) { - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Adding type %d to DNS response\n", rd[i].record_type); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Name: %s\n", rh->name); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "QName: %s\n", rh->query->name); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Record %d/%d\n", i+1, rd_count); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Record len %d\n", rd[i].data_size); - - if (rd[i].record_type == rh->query->type) - { - answer_records[i].name = rh->query->name; - answer_records[i].type = rd[i].record_type; - answer_records[i].data.raw.data_len = rd[i].data_size; - answer_records[i].data.raw.data = (char*)rd[i].data; - answer_records[i].expiration_time = rd[i].expiration; - answer_records[i].class = GNUNET_DNSPARSER_CLASS_INTERNET;//hmmn - } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s is not our domain. Returning\n", name); + csh->name = NULL; + send_shorten_response(csh, name); + return; + } + + GNUNET_SERVER_notification_context_add (nc, client); + + if (1 == ntohl(sh_msg->use_default_zone)) + zone = zone_hash; //Default zone + else + zone = sh_msg->zone; + + /* Start shortening */ + if (GNUNET_YES == auto_import_pkey) + { + if (1 == ntohl(sh_msg->use_default_zone)) + key = zone_key; else { - additional_records[i].name = rh->query->name; - additional_records[i].type = rd[i].record_type; - additional_records[i].data.raw.data_len = rd[i].data_size; - additional_records[i].data.raw.data = (char*)rd[i].data; - additional_records[i].expiration_time = rd[i].expiration; - additional_records[i].class = GNUNET_DNSPARSER_CLASS_INTERNET;//hmmn + key = lookup_private_key(&sh_msg->zone); + csh->zone_key = key; } + gns_resolver_shorten_name(zone, zone, name, key, + &send_shorten_response, csh); } - - packet->num_answers = rh->answered; - packet->num_additional_records = rd_count-(rh->answered); - - if (0 == GNUNET_CRYPTO_hash_cmp(&rh->authority, &zone_hash)) - packet->flags.authoritative_answer = 1; else - packet->flags.authoritative_answer = 0; - - if (rd == NULL) - packet->flags.return_code = GNUNET_DNSPARSER_RETURN_CODE_NAME_ERROR; - else - packet->flags.return_code = GNUNET_DNSPARSER_RETURN_CODE_NO_ERROR; - - packet->flags.query_or_response = 1; - - - /** - * Reply to DNS - */ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Building DNS response\n"); - ret = GNUNET_DNSPARSER_pack (packet, - 1024, /* FIXME magic from dns redirector */ - &buf, - &len); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Built DNS response! (ret=%d,len=%d)\n", ret, len); - if (ret == GNUNET_OK) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Answering DNS request\n"); - GNUNET_DNS_request_answer(rh->request_handle, - len, - buf); - //GNUNET_free(answer); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Answered DNS request\n"); - } - else - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - "Error building DNS response! (ret=%d)", ret); - } - - GNUNET_free(rh->name); - GNUNET_free(rh); -} + gns_resolver_shorten_name(zone, zone, name, NULL, + &send_shorten_response, csh); +} /** - * Namestore calls this function if we have record for this name. - * (or with rd_count=0 to indicate no matches) - * - * @param cls the pending query - * @param key the key of the zone we did the lookup - * @param expiration expiration date of the namestore entry - * @param name the name for which we need an authority - * @param rd_count the number of records with 'name' - * @param rd the record data - * @param signature the signature of the authority for the record data + * Send get authority response back to client + * + * @param cls the closure containing a client get auth handle + * @param name the shortened name result or NULL if cannot be shortened */ static void -process_authoritative_result(void* cls, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, - struct GNUNET_TIME_Absolute expiration, - const char *name, unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) +send_get_auth_response(void *cls, const char* name) { - struct GNUNET_GNS_ResolverHandle *rh; - struct GNUNET_TIME_Relative remaining_time; - GNUNET_HashCode zone; - - rh = (struct GNUNET_GNS_ResolverHandle *) cls; - GNUNET_CRYPTO_hash(key, - sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &zone); - remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); - - if (rd_count == 0) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %s\n", + "GET_AUTH_RESULT", name); + struct GNUNET_GNS_ClientGetAuthResultMessage *rmsg; + struct ClientGetAuthHandle *cah = (struct ClientGetAuthHandle *)cls; + + if (name == NULL) { - /** - * Lookup terminated and no results - * -> DHT Phase unless data is recent - */ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Namestore lookup for %s terminated without results\n", name); - - /** - * if this is not our zone we cannot rely on the namestore to be - * complete. -> Query DHT - */ - if (GNUNET_CRYPTO_hash_cmp(&zone, &zone_hash)) - { - if (remaining_time.rel_value == 0) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "trying dht...\n"); - resolve_name_dht(rh, name); - return; - } - else - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Record is still recent. No DHT lookup\n"); - } - } - - /** - * Our zone and no result? Cannot resolve TT - */ - GNUNET_assert(rh->answered == 0); - reply_to_dns(rh, 0, NULL); - return; - + name = ""; } - else - { - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Processing additional result %s from namestore\n", name); - int i; - for (i=0; iquery->name) == 0) - && (rd[i].record_type != rh->query->type)) - continue; - - if ((GNUNET_TIME_absolute_get_remaining (rd[i].expiration)).rel_value - == 0) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "This record is expired. Skipping\n"); - continue; - } - - rh->answered++; - - } - - /** - * no answers found - * consult dht if expired - */ - if ((remaining_time.rel_value == 0) && (rh->answered == 0)) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "This dht entry is old. Refreshing.\n"); - resolve_name_dht(rh, name); - return; - } - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Found %d answer(s) to query!\n", - rh->answered); - reply_to_dns(rh, rd_count, rd); - } -} + rmsg = GNUNET_malloc(sizeof(struct GNUNET_GNS_ClientGetAuthResultMessage) + + strlen(name) + 1); + + rmsg->id = cah->unique_id; + rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT); + rmsg->header.size = + htons(sizeof(struct GNUNET_GNS_ClientGetAuthResultMessage) + + strlen(name) + 1); + + strcpy((char*)&rmsg[1], name); + + GNUNET_SERVER_notification_context_unicast (nc, cah->client, + (const struct GNUNET_MessageHeader *) rmsg, + GNUNET_NO); + GNUNET_SERVER_receive_done (cah->client, GNUNET_OK); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up handles...\n"); -/** - * Determine if this name is canonical. - * i.e. - * a.b.gnunet = not canonical - * a = canonical - * - * @param name the name to test - * @return 1 if canonical - */ -int -is_canonical(char* name) -{ - uint32_t len = strlen(name); - int i; + GNUNET_free(rmsg); + GNUNET_free_non_null(cah->name); + GNUNET_free(cah); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done.\n"); - for (i=0; i 0; len--) + if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientGetAuthMessage)) { - if (*(name+len) == '.') - break; + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; } - if (len == 0) - return NULL; - - name[len] = '\0'; - - return (name+len+1); -} + GNUNET_SERVER_notification_context_add (nc, client); + struct GNUNET_GNS_ClientGetAuthMessage *sh_msg = + (struct GNUNET_GNS_ClientGetAuthMessage *) message; + + msg_size = ntohs(message->size); -/** - * The first phase of resolution. - * First check if the name is canonical. - * If it is then try to resolve directly. - * If not then we first have to resolve the authoritative entities. - * - * @param rh the pending lookup - */ -void -resolve_name(struct GNUNET_GNS_ResolverHandle *rh) -{ - if (is_canonical(rh->name)) - { - /* We only need to check the current zone's ns */ - GNUNET_NAMESTORE_lookup_record(namestore_handle, - &rh->authority, - rh->name, - rh->query->type, - &process_authoritative_result, - rh); - } - else + if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) { - /* We have to resolve the authoritative entity first */ - rh->authority_name = pop_tld(rh->name); - GNUNET_NAMESTORE_lookup_record(namestore_handle, - &rh->authority, - rh->authority_name, - GNUNET_GNS_RECORD_PKEY, - &process_authority_lookup, - rh); + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; } -} - -/** - * Entry point for name resolution - * Setup a new query and try to resolve - * - * @param request the request handle of the DNS request from a client - * @param p the DNS query packet we received - * @param q the DNS query we received parsed from p - */ -void -start_resolution(struct GNUNET_DNS_RequestHandle *request, - struct GNUNET_DNSPARSER_Packet *p, - struct GNUNET_DNSPARSER_Query *q) -{ - struct GNUNET_GNS_ResolverHandle *rh; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting resolution for (%s)!\n", - q->name); - rh = GNUNET_malloc(sizeof (struct GNUNET_GNS_ResolverHandle)); - rh->packet = p; - rh->query = q; - rh->authority = zone_hash; - - rh->name = GNUNET_malloc(strlen(q->name) - - strlen(gnunet_tld) + 1); - memset(rh->name, 0, - strlen(q->name)-strlen(gnunet_tld) + 1); - memcpy(rh->name, q->name, - strlen(q->name)-strlen(gnunet_tld)); - - rh->request_handle = request; + GNUNET_STRINGS_utf8_tolower((char*)&sh_msg[1], &nameptr); - /* Start resolution in our zone */ - resolve_name(rh); -} -/** - * The DNS request handler - * Called for every incoming DNS request. - * - * @param cls closure - * @param rh request handle to user for reply - * @param request_length number of bytes in request - * @param request udp payload of the DNS request - */ -void -handle_dns_request(void *cls, - struct GNUNET_DNS_RequestHandle *rh, - size_t request_length, - const char *request) -{ - struct GNUNET_DNSPARSER_Packet *p; - char *tldoffset; + cah = GNUNET_malloc(sizeof(struct ClientGetAuthHandle)); + cah->client = client; + cah->unique_id = sh_msg->id; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hijacked a DNS request...processing\n"); - p = GNUNET_DNSPARSER_parse (request, request_length); - - if (NULL == p) + if (strlen(name) < strlen(GNUNET_GNS_TLD)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Received malformed DNS packet, leaving it untouched\n"); - GNUNET_DNS_request_forward (rh); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GET_AUTH: %s is too short. Returning\n", name); + cah->name = NULL; + send_get_auth_response(cah, name); return; } - /** - * Check tld and decide if we or - * legacy dns is responsible - * - * FIXME now in theory there could be more than 1 query in the request - * but if this is case we get into trouble: - * either we query the GNS or the DNS. We cannot do both! - * So I suggest to either only allow a single query per request or - * only allow GNS or DNS requests. - * The way it is implemented here now is buggy and will lead to erratic - * behaviour (if multiple queries are present). - */ - if (p->num_queries == 0) + if (strlen (name) > MAX_DNS_NAME_LENGTH) { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GET_AUTH: %s is too long", name); + cah->name = NULL; + send_get_auth_response(cah, name); + return; + } + + if (strcmp(name+strlen(name)-strlen(GNUNET_GNS_TLD), + GNUNET_GNS_TLD) != 0) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No Queries in DNS packet... forwarding\n"); - GNUNET_DNS_request_forward (rh); + "GET_AUTH: %s is not our domain. Returning\n", name); + cah->name = NULL; + send_get_auth_response(cah, name); + return; } - if (p->num_queries > 1) + if (strcmp(name, GNUNET_GNS_TLD) == 0) { - /* Note: We could also look for .gnunet */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - ">1 queriy in DNS packet... odd. We only process #1\n"); + "GET_AUTH: %s is us. Returning\n", name); + cah->name = NULL; + send_get_auth_response(cah, name); + return; } - - /** - * Check for .gnunet - */ - tldoffset = p->queries[0].name + strlen(p->queries[0].name); + cah->name = GNUNET_malloc(strlen(name) + - strlen(GNUNET_GNS_TLD) + 1); + memset(cah->name, 0, + strlen(name)-strlen(GNUNET_GNS_TLD) + 1); + memcpy(cah->name, name, + strlen(name)-strlen(GNUNET_GNS_TLD)); + + /* Start delegation resolution in our namestore */ + gns_resolver_get_authority(zone_hash, zone_hash, name, &send_get_auth_response, cah); +} - while ((*tldoffset) != '.') - tldoffset--; - - if (0 == strcmp(tldoffset, gnunet_tld)) - { - start_resolution(rh, p, p->queries); - } - else - { - /** - * This request does not concern us. Forward to real DNS. - */ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Request for %s is forwarded to DNS\n", p->queries[0].name); - GNUNET_DNS_request_forward (rh); - } -} /** - * test function that stores some data in the namestore - * This will also be replaced by a test progrm that - * directl interfaces with the namestore + * Reply to client with the result from our lookup. + * + * @param cls the closure (our client lookup handle) + * @param rd_count the number of records + * @param rd the record data */ -void -put_some_records(void) +static void +send_lookup_response(void* cls, + uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Populating namestore\n"); - /* put an A record into namestore FIXME use gnunet.org */ - char* ipB = "5.6.7.8"; - - struct in_addr *web = GNUNET_malloc(sizeof(struct in_addr)); - struct GNUNET_NAMESTORE_RecordData rdb_web; - - GNUNET_assert(1 == inet_pton (AF_INET, ipB, web)); + struct ClientLookupHandle* clh = (struct ClientLookupHandle*)cls; + struct GNUNET_GNS_ClientLookupResultMessage *rmsg; + size_t len; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %d results\n", + "LOOKUP_RESULT", rd_count); + + len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); + rmsg = GNUNET_malloc(len+sizeof(struct GNUNET_GNS_ClientLookupResultMessage)); + + rmsg->id = clh->unique_id; + rmsg->rd_count = htonl(rd_count); + rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT); + rmsg->header.size = + htons(len+sizeof(struct GNUNET_GNS_ClientLookupResultMessage)); - rdb_web.data_size = sizeof(struct in_addr); - rdb_web.data = web; - rdb_web.record_type = GNUNET_DNSPARSER_TYPE_A; - rdb_web.expiration = GNUNET_TIME_absolute_get_forever (); + GNUNET_NAMESTORE_records_serialize (rd_count, rd, len, (char*)&rmsg[1]); - GNUNET_NAMESTORE_record_create (namestore_handle, - zone_key, - "www", - &rdb_web, - NULL, - NULL); -} + GNUNET_SERVER_notification_context_unicast (nc, clh->client, + (const struct GNUNET_MessageHeader *) rmsg, + GNUNET_NO); + GNUNET_SERVER_receive_done (clh->client, GNUNET_OK); + + GNUNET_free(rmsg); + GNUNET_free(clh->name); + + if (NULL != clh->zone_key) + GNUNET_free(clh->zone_key); -/** - * Method called periodicattluy that triggers - * iteration over root zone - * - * @param cls closure - * @param tc task context - */ -void -update_zone_dht_next(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_NAMESTORE_zone_iterator_next(namestore_iter); -} + GNUNET_free(clh); -/** - * Continuation for DHT put - * - * @param cls closure - * @param tc task context - */ -void -record_dht_put(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "put request transmitted\n"); } -/* prototype */ -static void -update_zone_dht_start(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** - * Function used to put all records successively into the DHT. - * FIXME bug here + * Handle lookup requests from client * - * @param cls the closure (NULL) - * @param key the public key of the authority (ours) - * @param expiration lifetime of the namestore entry - * @param name the name of the records - * @param rd_count the number of records in data - * @param rd the record data - * @param signature the signature for the record data + * @param cls the closure + * @param client the client + * @param message the message */ -void -put_gns_record(void *cls, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, - struct GNUNET_TIME_Absolute expiration, - const char *name, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) +static void +handle_lookup(void *cls, + struct GNUNET_SERVER_Client * client, + const struct GNUNET_MessageHeader * message) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Putting records for %s into the DHT\n", name); - struct GNUNET_TIME_Relative timeout; - struct GNSNameRecordBlock *nrb; - struct GNSRecordBlock *rb; - GNUNET_HashCode name_hash; - GNUNET_HashCode xor_hash; - struct GNUNET_CRYPTO_HashAsciiEncoded xor_hash_string; - int i; - uint32_t rd_payload_length; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "LOOKUP"); - /* we're done */ - if (NULL == name) + size_t msg_size = 0; + size_t namelen; + char name[MAX_DNS_NAME_LENGTH]; + struct ClientLookupHandle *clh; + char* nameptr = name; + struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL; + struct GNUNET_CRYPTO_ShortHashCode zone; + + if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientLookupMessage)) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Zone iteration finished\n"); - GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); - zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_start, - NULL); + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } - - rd_payload_length = rd_count * sizeof(struct GNSRecordBlock); - rd_payload_length += strlen(name) + 1 + sizeof(struct GNSNameRecordBlock); - - /* calculate payload size */ - for (i=0; isignature, signature, - sizeof(struct GNUNET_CRYPTO_RsaSignature)); - //FIXME signature purpose - memcpy(&nrb->public_key, key, - sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); - nrb->rd_count = htonl(rd_count); + GNUNET_SERVER_notification_context_add (nc, client); - memcpy(&nrb[1], name, strlen(name) + 1); //FIXME is this 0 terminated?? - - rb = (struct GNSRecordBlock *)((char*)&nrb[1] + strlen(name) + 1); + struct GNUNET_GNS_ClientLookupMessage *sh_msg = + (struct GNUNET_GNS_ClientLookupMessage *) message; + + msg_size = ntohs(message->size); - for (i=0; i GNUNET_SERVER_MAX_MESSAGE_SIZE) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Read record with type %d\n", - rd[i].record_type); - rb->type = htonl(rd[i].record_type); - rb->expiration = GNUNET_TIME_absolute_hton(rd[i].expiration); - rb->data_length = htonl(rd[i].data_size); - rb->flags = htonl(rd[i].flags); - memcpy(&rb[1], rd[i].data, rd[i].data_size); - rb = &rb[1] + rd[i].data_size; + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; } - - /** - * FIXME magic number 20 move to config file - * DHT_WAIT_TIMEOUT - */ - timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20); - /* - * calculate DHT key: H(name) xor H(pubkey) - */ - GNUNET_CRYPTO_hash(name, strlen(name), &name_hash); - GNUNET_CRYPTO_hash_xor(&zone_hash, &name_hash, &xor_hash); - GNUNET_CRYPTO_hash_to_enc (&xor_hash, &xor_hash_string); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "putting records for %s under key: %s with size %d\n", - name, (char*)&xor_hash_string, rd_payload_length); - - GNUNET_DHT_put (dht_handle, &xor_hash, - 5, //replication level - GNUNET_DHT_RO_NONE, - GNUNET_BLOCK_TYPE_GNS_NAMERECORD, //FIXME todo block plugin - rd_payload_length, - (char*)nrb, - expiration, - timeout, - &record_dht_put, //FIXME continuation needed? success check? yes ofc - NULL); //cls for cont + GNUNET_STRINGS_utf8_tolower((char*)&sh_msg[1], &nameptr); + namelen = strlen(name)+1; + clh = GNUNET_malloc(sizeof(struct ClientLookupHandle)); + clh->client = client; + clh->name = GNUNET_malloc(namelen); + strcpy(clh->name, name); + clh->unique_id = sh_msg->id; + clh->type = ntohl(sh_msg->type); + clh->zone_key = NULL; - num_public_records++; - - /** - * Reschedule periodic put - */ - zone_update_taskid = GNUNET_SCHEDULER_add_delayed (dht_update_interval, - &update_zone_dht_next, - NULL); - -} - -/** - * Puts a single trusted entity into the - * namestore. Will be replaced in a testcase - * that directly interacts with a persistent - * namestore. - * - * @param name name of entity - * @param keyfile keyfile - */ -void -put_trusted(char* name, char* keyfile) -{ - struct GNUNET_NAMESTORE_RecordData rd; - struct GNUNET_CRYPTO_RsaPrivateKey *key; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey; - pkey = GNUNET_malloc(sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); - - key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); - GNUNET_CRYPTO_rsa_key_get_public (key, pkey); - rd.data = pkey; - rd.expiration = GNUNET_TIME_absolute_get_forever (); - rd.data_size = sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded); - rd.record_type = GNUNET_GNS_RECORD_PKEY; - - GNUNET_NAMESTORE_record_create (namestore_handle, - zone_key, - name, - &rd, - NULL, - NULL); -} - - + if (strlen (name) > MAX_DNS_NAME_LENGTH) { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "LOOKUP: %s is too long", name); + clh->name = NULL; + send_lookup_response(clh, 0, NULL); + return; + } -/** - * Periodically iterate over our zone and store everything in dht - * - * @param cls NULL - * @param tc task context - */ -static void -update_zone_dht_start(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Starting DHT zone update!\n"); - if (0 == num_public_records) + if (1 == ntohl(sh_msg->use_default_zone)) + zone = zone_hash; //Default zone + else + zone = sh_msg->zone; + + if (GNUNET_YES == auto_import_pkey) { - dht_update_interval = GNUNET_TIME_relative_multiply( - GNUNET_TIME_UNIT_SECONDS, - 1); + if (1 == ntohl(sh_msg->use_default_zone)) + key = zone_key; + else + { + key = lookup_private_key(&zone); + clh->zone_key = key; + } + + gns_resolver_lookup_record(zone, zone, clh->type, name, + key, + default_lookup_timeout, + &send_lookup_response, clh); } else { - dht_update_interval = GNUNET_TIME_relative_multiply( - GNUNET_TIME_UNIT_SECONDS, - (3600/num_public_records)); + gns_resolver_lookup_record(zone, zone, clh->type, name, + NULL, + default_lookup_timeout, + &send_lookup_response, clh); } - num_public_records = 0; //start counting again - namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle, - &zone_hash, - GNUNET_NAMESTORE_RF_AUTHORITY, - GNUNET_NAMESTORE_RF_PRIVATE, - &put_gns_record, - NULL); } + + /** * Process GNS requests. * - * @param cls closure + * @param cls closure) * @param server the initialized server * @param c configuration to use */ @@ -1250,53 +909,41 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Initializing GNS\n"); - + char* keyfile; - char* trusted_entities; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; + unsigned long long max_parallel_bg_queries = 0; + unsigned long long default_lookup_timeout_secs = 0; + int ignore_pending = GNUNET_NO; - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (c, "gns", + static const struct GNUNET_SERVER_MessageHandler handlers[] = { + {&handle_shorten, NULL, GNUNET_MESSAGE_TYPE_GNS_SHORTEN, 0}, + {&handle_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_LOOKUP, 0}, + {&handle_get_authority, NULL, GNUNET_MESSAGE_TYPE_GNS_GET_AUTH, 0} + }; + + GNS_cfg = c; + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c, "gns", "ZONEKEY", &keyfile)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No private key for root zone specified%s!\n", keyfile); - GNUNET_SCHEDULER_shutdown(0); + "No private key for root zone specified!\n"); + GNUNET_SCHEDULER_shutdown (); return; } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Using keyfile %s for root zone.\n", keyfile); + zone_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); GNUNET_CRYPTO_rsa_key_get_public (zone_key, &pkey); - GNUNET_CRYPTO_hash(&pkey, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + GNUNET_CRYPTO_short_hash(&pkey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_hash); + GNUNET_free(keyfile); - nc = GNUNET_SERVER_notification_context_create (server, 1); - - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, - NULL); - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (c, "gns", - "HIJACK_DNS")) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "DNS hijacking enabled... connecting to service.\n"); - /** - * Do gnunet dns init here - */ - dns_handle = GNUNET_DNS_connect(c, - GNUNET_DNS_FLAG_PRE_RESOLUTION, - &handle_dns_request, /* rh */ - NULL); /* Closure */ - if (NULL == dns_handle) - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - "Failed to connect to the dnsservice!\n"); - } - } - - - /** * handle to our local namestore */ @@ -1307,73 +954,135 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, //FIXME do error handling; GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to the namestore!\n"); - GNUNET_SCHEDULER_shutdown(0); + GNUNET_SCHEDULER_shutdown (); return; } - char* trusted_start; - char* trusted_name; - char *trusted_key; - int trusted_len; - if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (c, "gns", - "TRUSTED", - &trusted_entities)) + + + auto_import_pkey = GNUNET_NO; + + if (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (c, "gns", + "AUTO_IMPORT_PKEY")) { - trusted_start = trusted_entities; - trusted_len = strlen(trusted_entities); GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Found trusted entities in config file, importing\n"); - while ((trusted_entities-trusted_start) < trusted_len) - { - trusted_name = trusted_entities; - while (*trusted_entities != ':') - trusted_entities++; - *trusted_entities = '\0'; - trusted_entities++; - trusted_key = trusted_entities; - while (*trusted_entities != ',' && (*trusted_entities != '\0')) - trusted_entities++; - *trusted_entities = '\0'; - trusted_entities++; - - if (GNUNET_YES == GNUNET_DISK_file_test (trusted_key)) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Adding %s:%s to root zone\n", - trusted_name, - trusted_key); - put_trusted(trusted_name, trusted_key); - } - else - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Keyfile %s does not exist!\n", - trusted_key); - //put_trusted(trusted_name, trusted_key); //FIXME for testing - } - } + "Automatic PKEY import is enabled.\n"); + auto_import_pkey = GNUNET_YES; + + } + + dht_max_update_interval = GNUNET_GNS_DHT_MAX_UPDATE_INTERVAL; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number (c, "gns", + "ZONE_PUT_INTERVAL", + &dht_max_update_interval)) + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + "DHT zone update interval: %d\n", + dht_max_update_interval); + } + + max_record_put_interval = 1; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number (c, "gns", + "RECORD_PUT_INTERVAL", + &max_record_put_interval)) + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + "Record put interval: %d\n", + max_record_put_interval); + } + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number (c, "gns", + "MAX_PARALLEL_BACKGROUND_QUERIES", + &max_parallel_bg_queries)) + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + "Number of allowed parallel background queries: %d\n", + max_parallel_bg_queries); + } + if (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (c, "gns", + "AUTO_IMPORT_CONFIRMATION_REQ")) + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + "Auto import requires user confirmation\n"); + ignore_pending = GNUNET_YES; } + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number(c, "gns", + "DEFAULT_LOOKUP_TIMEOUT", + &default_lookup_timeout_secs)) + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + "Default lookup timeout: %ds\n", default_lookup_timeout_secs); + default_lookup_timeout = GNUNET_TIME_relative_multiply( + GNUNET_TIME_UNIT_SECONDS, + default_lookup_timeout_secs); + } + /** * handle to the dht */ - dht_handle = GNUNET_DHT_connect(c, 1); //FIXME get ht_len from cfg + dht_handle = GNUNET_DHT_connect(c, + //max_parallel_bg_queries); //FIXME get ht_len from cfg + 1024); if (NULL == dht_handle) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not connect to DHT!\n"); } + + if (gns_resolver_init(namestore_handle, dht_handle, zone_hash, + max_parallel_bg_queries, + ignore_pending) + == GNUNET_SYSERR) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Unable to initialize resolver!\n"); + GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + return; + } + + if (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (c, "gns", "HIJACK_DNS")) + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + "DNS hijacking enabled... connecting to service.\n"); - put_some_records(); //FIXME for testing + if (gns_interceptor_init(zone_hash, zone_key, c) == GNUNET_SYSERR) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Failed to enable the dns interceptor!\n"); + } + } /** * Schedule periodic put * for our records * We have roughly an hour for all records; */ - dht_update_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, + record_put_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1); zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_start, NULL); + GNUNET_SERVER_add_handlers (server, handlers); + + //FIXME + //GNUNET_SERVER_disconnect_notify (server, + // &client_disconnect_notification, + // NULL); + + nc = GNUNET_SERVER_notification_context_create (server, 1); + + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, + NULL); } diff --git a/src/gns/gnunet-service-gns_interceptor.c b/src/gns/gnunet-service-gns_interceptor.c new file mode 100644 index 0000000..adb09ca --- /dev/null +++ b/src/gns/gnunet-service-gns_interceptor.c @@ -0,0 +1,394 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * + * @file gns/gnunet-service-gns_interceptor.c + * @brief GNUnet GNS interceptor logic + * @author Martin Schanzenbach + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_transport_service.h" +#include "gnunet_dns_service.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet-service-gns_resolver.h" +#include "gns.h" + +#define MAX_DNS_LABEL_LENGTH 63 + +/** + * Handle to a DNS intercepted + * reslution request + */ +struct InterceptLookupHandle +{ + /* the request handle to reply to */ + struct GNUNET_DNS_RequestHandle *request_handle; + + /* the dns parser packet received */ + struct GNUNET_DNSPARSER_Packet *packet; + + /* the query parsed from the packet */ + struct GNUNET_DNSPARSER_Query *query; +}; + + +/** + * Our handle to the DNS handler library + */ +static struct GNUNET_DNS_Handle *dns_handle; + +/** + * The root zone for this interceptor + */ +static struct GNUNET_CRYPTO_ShortHashCode our_zone; + +/** + * Our priv key + */ +static struct GNUNET_CRYPTO_RsaPrivateKey *our_key; + +/** + * Default timeout + */ +static struct GNUNET_TIME_Relative default_lookup_timeout; + +/** + * Reply to dns request with the result from our lookup. + * + * @param cls the closure to the request (an InterceptLookupHandle) + * @param rd_count the number of records to return + * @param rd the record data + */ +static void +reply_to_dns(void* cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + int i; + size_t len; + int ret; + char *buf; + struct InterceptLookupHandle* ilh = (struct InterceptLookupHandle*)cls; + struct GNUNET_DNSPARSER_Packet *packet = ilh->packet; + unsigned int num_answers = 0; + + + /** + * Put records in the DNS packet and modify it + * to a response + */ + for (i=0; i < rd_count; i++) + { + if (rd[i].record_type == ilh->query->type) + num_answers++; + } + + struct GNUNET_DNSPARSER_Record answer_records[num_answers]; + struct GNUNET_DNSPARSER_Record additional_records[rd_count-(num_answers)]; + packet->answers = answer_records; + packet->additional_records = additional_records; + + for (i=0; i < rd_count; i++) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Adding type %d to DNS response\n", rd[i].record_type); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Name: %s\n", ilh->query->name); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Record %d/%d\n", i+1, rd_count); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Record len %d\n", rd[i].data_size); + + if (rd[i].record_type == ilh->query->type) + { + answer_records[i].name = ilh->query->name; + answer_records[i].type = rd[i].record_type; + switch(rd[i].record_type) + { + case GNUNET_GNS_RECORD_TYPE_NS: + case GNUNET_GNS_RECORD_TYPE_CNAME: + case GNUNET_GNS_RECORD_TYPE_PTR: + answer_records[i].data.hostname = (char*)rd[i].data; + break; + case GNUNET_GNS_RECORD_TYPE_SOA: + answer_records[i].data.soa = + (struct GNUNET_DNSPARSER_SoaRecord *)rd[i].data; + break; + case GNUNET_GNS_RECORD_MX: + answer_records[i].data.mx = + (struct GNUNET_DNSPARSER_MxRecord *)rd[i].data; + break; + default: + answer_records[i].data.raw.data_len = rd[i].data_size; + answer_records[i].data.raw.data = (char*)rd[i].data; + } + answer_records[i].expiration_time = rd[i].expiration; + answer_records[i].class = GNUNET_DNSPARSER_CLASS_INTERNET;//hmmn + } + else + { + additional_records[i].name = ilh->query->name; + additional_records[i].type = rd[i].record_type; + switch(rd[i].record_type) + { + case GNUNET_GNS_RECORD_TYPE_NS: + case GNUNET_GNS_RECORD_TYPE_CNAME: + case GNUNET_GNS_RECORD_TYPE_PTR: + additional_records[i].data.hostname = (char*)rd[i].data; + break; + case GNUNET_GNS_RECORD_TYPE_SOA: + additional_records[i].data.soa = + (struct GNUNET_DNSPARSER_SoaRecord *)rd[i].data; + break; + case GNUNET_GNS_RECORD_MX: + additional_records[i].data.mx = + (struct GNUNET_DNSPARSER_MxRecord *)rd[i].data; + break; + default: + additional_records[i].data.raw.data_len = rd[i].data_size; + additional_records[i].data.raw.data = (char*)rd[i].data; + } + additional_records[i].expiration_time = rd[i].expiration; + additional_records[i].class = GNUNET_DNSPARSER_CLASS_INTERNET;//hmmn + } + } + + packet->num_answers = num_answers; + packet->num_additional_records = rd_count-(num_answers); + + packet->flags.authoritative_answer = 1; + + if (rd == NULL) + packet->flags.return_code = GNUNET_DNSPARSER_RETURN_CODE_NAME_ERROR; + else + packet->flags.return_code = GNUNET_DNSPARSER_RETURN_CODE_NO_ERROR; + + packet->flags.query_or_response = 1; + + + /** + * Reply to DNS + */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Building DNS response\n"); + ret = GNUNET_DNSPARSER_pack (packet, + 1024, /* FIXME magic from dns redirector */ + &buf, + &len); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Built DNS response! (ret=%d,len=%d)\n", ret, len); + if (ret == GNUNET_OK) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Answering DNS request\n"); + GNUNET_DNS_request_answer(ilh->request_handle, + len, + buf); + + GNUNET_free(buf); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Answered DNS request\n"); + } + else + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Error building DNS response! (ret=%d)", ret); + } + + packet->num_answers = 0; + packet->answers = NULL; + packet->num_additional_records = 0; + packet->additional_records = NULL; + GNUNET_DNSPARSER_free_packet(packet); + GNUNET_free(ilh); +} + + +/** + * Entry point for name resolution + * Setup a new query and try to resolve + * + * @param request the request handle of the DNS request from a client + * @param p the DNS query packet we received + * @param q the DNS query we received parsed from p + */ +static void +start_resolution_for_dns(struct GNUNET_DNS_RequestHandle *request, + struct GNUNET_DNSPARSER_Packet *p, + struct GNUNET_DNSPARSER_Query *q) +{ + struct InterceptLookupHandle* ilh; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting resolution for %s (type=%d)!\n", + q->name, q->type); + + ilh = GNUNET_malloc(sizeof(struct InterceptLookupHandle)); + ilh->packet = p; + ilh->query = q; + ilh->request_handle = request; + + /* Start resolution in our zone */ + gns_resolver_lookup_record(our_zone, our_zone, q->type, q->name, + our_key, + default_lookup_timeout, + &reply_to_dns, ilh); +} + + + +/** + * The DNS request handler + * Called for every incoming DNS request. + * + * @param cls closure + * @param rh request handle to user for reply + * @param request_length number of bytes in request + * @param request udp payload of the DNS request + */ +static void +handle_dns_request(void *cls, + struct GNUNET_DNS_RequestHandle *rh, + size_t request_length, + const char *request) +{ + struct GNUNET_DNSPARSER_Packet *p; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hijacked a DNS request...processing\n"); + p = GNUNET_DNSPARSER_parse (request, request_length); + + if (NULL == p) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Received malformed DNS packet, leaving it untouched\n"); + GNUNET_DNS_request_forward (rh); + GNUNET_DNSPARSER_free_packet (p); + return; + } + + /** + * Check tld and decide if we or + * legacy dns is responsible + * + * FIXME now in theory there could be more than 1 query in the request + * but if this is case we get into trouble: + * either we query the GNS or the DNS. We cannot do both! + * So I suggest to either only allow a single query per request or + * only allow GNS or DNS requests. + * The way it is implemented here now is buggy and will lead to erratic + * behaviour (if multiple queries are present). + */ + if (p->num_queries == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No Queries in DNS packet... forwarding\n"); + GNUNET_DNS_request_forward (rh); + GNUNET_DNSPARSER_free_packet(p); + return; + } + + if (p->num_queries > 1) + { + /* Note: We could also look for .gnunet */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + ">1 queriy in DNS packet... odd. We only process #1\n"); + } + + + /** + * Check for .gnunet/.zkey + */ + + if ((is_gnunet_tld(p->queries[0].name) == GNUNET_YES) || + (is_zkey_tld(p->queries[0].name) == GNUNET_YES) || + (strcmp(p->queries[0].name, GNUNET_GNS_TLD) == 0)) + { + start_resolution_for_dns(rh, p, p->queries); + } + else + { + /** + * This request does not concern us. Forward to real DNS. + */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Request for %s is forwarded to DNS\n", p->queries[0].name); + GNUNET_DNS_request_forward (rh); + GNUNET_DNSPARSER_free_packet (p); + } + +} + + +/** + * Initialized the interceptor + * + * @param zone the zone to work in + * @param key the prov key of the zone (can be null, needed for caching) + * @param c the configuration + * @return GNUNET_OK on success + */ +int +gns_interceptor_init(struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_RsaPrivateKey *key, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + unsigned long long default_lookup_timeout_secs = 0; + + GNUNET_log(GNUNET_ERROR_TYPE_INFO, + "DNS hijacking enabled... connecting to service.\n"); + + our_zone = zone; + our_key = key; + /** + * Do gnunet dns init here + */ + dns_handle = GNUNET_DNS_connect(c, + GNUNET_DNS_FLAG_PRE_RESOLUTION, + &handle_dns_request, /* rh */ + NULL); /* Closure */ + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number(c, "gns", + "DEFAULT_LOOKUP_TIMEOUT", + &default_lookup_timeout_secs)) + { + default_lookup_timeout = GNUNET_TIME_relative_multiply( + GNUNET_TIME_UNIT_SECONDS, + default_lookup_timeout_secs); + } + + if (NULL == dns_handle) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Failed to connect to the dnsservice!\n"); + return GNUNET_SYSERR; + } + + return GNUNET_YES; +} + +/** + * Disconnect from interceptor + */ +void +gns_interceptor_stop(void) +{ + if (dns_handle) + GNUNET_DNS_disconnect(dns_handle); +} + +/* end of gns_interceptor.c */ diff --git a/src/gns/gnunet-service-gns_interceptor.h b/src/gns/gnunet-service-gns_interceptor.h new file mode 100644 index 0000000..dc39aec --- /dev/null +++ b/src/gns/gnunet-service-gns_interceptor.h @@ -0,0 +1,23 @@ +#ifndef GNUNET_GNS_INTERCEPTOR_H +#define GNUNET_GNS_INTERCEPTOR_H + +/** + * Initialize dns interceptor + * + * @param zone the zone + * @param key the private key of the local zone + * @param c the configuration + * @return GNUNET_YES on success GNUNET_SYSERR on error + */ +int +gns_interceptor_init(struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_RsaPrivateKey *key, + const struct GNUNET_CONFIGURATION_Handle *c); + +/** + * Stops the interceptor + */ +void +gns_interceptor_stop(void); + +#endif diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c new file mode 100644 index 0000000..cf12e4b --- /dev/null +++ b/src/gns/gnunet-service-gns_resolver.c @@ -0,0 +1,2751 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * + * + * @file gns/gnunet-service-gns_resolver.c + * @brief GNUnet GNS resolver logic + * @author Martin Schanzenbach + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_transport_service.h" +#include "gnunet_dns_service.h" +#include "gnunet_dht_service.h" +#include "gnunet_namestore_service.h" +#include "gnunet_dns_service.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_gns_service.h" +#include "block_gns.h" +#include "gns.h" +#include "gnunet-service-gns_resolver.h" + +#define DHT_LOOKUP_TIMEOUT DHT_OPERATION_TIMEOUT +#define DHT_GNS_REPLICATION_LEVEL 5 +#define MAX_DNS_LABEL_LENGTH 63 + + +/** + * Our handle to the namestore service + */ +static struct GNUNET_NAMESTORE_Handle *namestore_handle; + +/** + * Resolver handle to the dht + */ +static struct GNUNET_DHT_Handle *dht_handle; + +/** + * Heap for parallel DHT lookups + */ +static struct GNUNET_CONTAINER_Heap *dht_lookup_heap; + +/** + * Maximum amount of parallel queries in background + */ +static unsigned long long max_allowed_background_queries; + +/** + * Wheather or not to ignore pending records + */ +static int ignore_pending_records; + +/** + * Our local zone + */ +static struct GNUNET_CRYPTO_ShortHashCode local_zone; + +/** + * a resolution identifier pool variable + * FIXME overflow? + * This is a non critical identifier useful for debugging + */ +static unsigned long long rid = 0; + +/** + * Namestore calls this function if we have record for this name. + * (or with rd_count=0 to indicate no matches) + * + * @param cls the pending query + * @param key the key of the zone we did the lookup + * @param expiration expiration date of the namestore entry + * @param name the name for which we need an authority + * @param rd_count the number of records with 'name' + * @param rd the record data + * @param signature the signature of the authority for the record data + */ +static void +process_pseu_lookup_ns(void* cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, + struct GNUNET_TIME_Absolute expiration, + const char *name, unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; + struct GNUNET_NAMESTORE_RecordData new_pkey; + + if (rd_count > 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_AUTO_PSEU: Name %s already taken in NS!\n", name); + if (0 == strcmp(gph->name, name)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_AUTO_PSEU: Intelligent replacement not implemented\n", + name); + GNUNET_free(gph); + return; + } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_AUTO_PSEU: Trying delegated name %s\n", gph->name); + memcpy(gph->new_name, gph->name, strlen(gph->name)+1); + GNUNET_NAMESTORE_lookup_record(namestore_handle, + &gph->zone, + gph->new_name, + GNUNET_NAMESTORE_TYPE_ANY, + &process_pseu_lookup_ns, + gph); + return; + } + + /** name is free */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_AUTO_PSEU: Name %s not taken in NS! Adding\n", gph->new_name); + + new_pkey.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + new_pkey.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode); + new_pkey.data = &gph->new_zone; + new_pkey.record_type = GNUNET_GNS_RECORD_PKEY; + new_pkey.flags = GNUNET_NAMESTORE_RF_AUTHORITY + | GNUNET_NAMESTORE_RF_PRIVATE + | GNUNET_NAMESTORE_RF_PENDING; + GNUNET_NAMESTORE_record_create (namestore_handle, + gph->key, + gph->new_name, + &new_pkey, + NULL, //cont + NULL); //cls + GNUNET_free(gph); + +} + +/** + * process result of a dht pseu lookup + * + * @param gph the handle + * @param name the pseu result or NULL + */ +static void +process_pseu_result(struct GetPseuAuthorityHandle* gph, char* name) +{ + if (NULL == name) + { + memcpy(gph->new_name, gph->name, strlen(gph->name)+1); + } + else + { + memcpy(gph->new_name, name, strlen(name)+1); + } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_AUTO_PSEU: Checking %s for collision in NS\n", gph->new_name); + + /** + * Check for collision + */ + GNUNET_NAMESTORE_lookup_record(namestore_handle, + &gph->zone, + gph->new_name, + GNUNET_NAMESTORE_TYPE_ANY, + &process_pseu_lookup_ns, + gph); +} + +/** + * Handle timeout for dht request + * + * @param cls the request handle as closure + * @param tc the task context + */ +static void +handle_auth_discovery_timeout(void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_GET_AUTH: dht lookup for query PSEU timed out.\n"); + GNUNET_DHT_get_stop (gph->get_handle); + gph->get_handle = NULL; + process_pseu_result(gph, NULL); +} + +/** + * Function called when we find a PSEU entry in the DHT + * + * @param cls the request handle + * @param exp lifetime + * @param key the key the record was stored under + * @param get_path get path + * @param get_path_length get path length + * @param put_path put path + * @param put_path_length put path length + * @param type the block type + * @param size the size of the record + * @param data the record data + */ +static void +process_auth_discovery_dht_result(void* cls, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, + enum GNUNET_BLOCK_Type type, + size_t size, const void *data) +{ + struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; + struct GNSNameRecordBlock *nrb; + char* rd_data = (char*)data; + char* name; + int num_records; + size_t rd_size; + int i; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_GET_AUTH: got dht result (size=%d)\n", size); + + if (data == NULL) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "GNS_GET_AUTH: got dht result null!\n", size); + GNUNET_break(0); + GNUNET_free(gph); + return; + } + + nrb = (struct GNSNameRecordBlock*)data; + + /* stop lookup and timeout task */ + GNUNET_DHT_get_stop (gph->get_handle); + gph->get_handle = NULL; + GNUNET_SCHEDULER_cancel(gph->timeout); + + gph->get_handle = NULL; + + nrb = (struct GNSNameRecordBlock*)data; + + name = (char*)&nrb[1]; + num_records = ntohl(nrb->rd_count); + { + struct GNUNET_NAMESTORE_RecordData rd[num_records]; + + rd_data += strlen(name) + 1 + sizeof(struct GNSNameRecordBlock); + rd_size = size - strlen(name) - 1 - sizeof(struct GNSNameRecordBlock); + + if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (rd_size, + rd_data, + num_records, + rd)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "GNS_GET_AUTH: Error deserializing data!\n"); + GNUNET_break(0); + GNUNET_free(gph); + return; + } + + for (i=0; inew_zone, &zone_hash_double); + GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &lookup_key); + GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_AUTO_PSEU: starting dht lookup for %s with key: %s\n", + "+", (char*)&lookup_key_string); + + gph->timeout = GNUNET_SCHEDULER_add_delayed(DHT_LOOKUP_TIMEOUT, + &handle_auth_discovery_timeout, gph); + + xquery = htonl(GNUNET_GNS_RECORD_PSEU); + + GNUNET_assert(gph->get_handle == NULL); + gph->get_handle = GNUNET_DHT_get_start(dht_handle, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + &lookup_key, + DHT_GNS_REPLICATION_LEVEL, + GNUNET_DHT_RO_NONE, + &xquery, + sizeof(xquery), + &process_auth_discovery_dht_result, + gph); + return; + } + for (i=0; inew_zone, + "+", + GNUNET_GNS_RECORD_PSEU, + &process_auth_discovery_ns_result, + gph); + } + + +} + + +/** + * Callback for new authories + * + * @param name the name given by delegation + * @param zone the authority + * @param our_zone our local zone + * @param key the private key of our authority + */ +static void process_discovered_authority(char* name, + struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_ShortHashCode our_zone, + struct GNUNET_CRYPTO_RsaPrivateKey *key) +{ + struct GetPseuAuthorityHandle *gph; + size_t namelen; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_AUTO_PSEU: New authority %s discovered\n", + name); + + gph = GNUNET_malloc(sizeof(struct GetPseuAuthorityHandle)); + namelen = strlen(name) + 1; + memcpy(gph->name, name, namelen); + + gph->new_zone = zone; + gph->zone = our_zone; + gph->key = key; + + GNUNET_NAMESTORE_zone_to_name (namestore_handle, + &our_zone, + &gph->new_zone, + &process_zone_to_name_discover, + gph); + +} + +/** + * Initialize the resolver + * + * @param nh the namestore handle + * @param dh the dht handle + * @param lz the local zone's hash + * @param max_bg_queries maximum number of parallel background queries in dht + * @param ignore_pending ignore records that still require user confirmation + * on lookup + * @return GNUNET_OK on success + */ +int +gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh, + struct GNUNET_DHT_Handle *dh, + struct GNUNET_CRYPTO_ShortHashCode lz, + unsigned long long max_bg_queries, + int ignore_pending) +{ + namestore_handle = nh; + dht_handle = dh; + local_zone = lz; + dht_lookup_heap = + GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN); + max_allowed_background_queries = max_bg_queries; + ignore_pending_records = ignore_pending; + + if ((namestore_handle != NULL) && (dht_handle != NULL)) + { + return GNUNET_OK; + } + return GNUNET_SYSERR; +} + +/** + * Cleanup background lookups + * + * @param cls closure to iterator + * @param node heap nodes + * @param element the resolver handle + * @param cost heap cost + * @return always GNUNET_YES + */ +static int +cleanup_pending_background_queries(void* cls, + struct GNUNET_CONTAINER_HeapNode *node, + void *element, + GNUNET_CONTAINER_HeapCostType cost) +{ + struct ResolverHandle *rh = (struct ResolverHandle *)element; + ResolverCleanupContinuation cont = cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_CLEANUP-%llu: Terminating background lookup for %s\n", + rh->id, rh->name); + GNUNET_DHT_get_stop(rh->get_handle); + rh->get_handle = NULL; + rh->proc(rh->proc_cls, rh, 0, NULL); + + GNUNET_CONTAINER_heap_remove_node(node); + + if (GNUNET_CONTAINER_heap_get_size(dht_lookup_heap) == 0) + cont(); + + + return GNUNET_YES; +} + + +/** + * Shutdown resolver + */ +void +gns_resolver_cleanup(ResolverCleanupContinuation cont) +{ + unsigned int s = GNUNET_CONTAINER_heap_get_size(dht_lookup_heap); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_CLEANUP: %d pending background queries to terminate\n", s); + + if (0 != s) + GNUNET_CONTAINER_heap_iterate (dht_lookup_heap, + &cleanup_pending_background_queries, + cont); + else + cont(); +} + + +/** + * Helper function to free resolver handle + * + * @param rh the handle to free + */ +static void +free_resolver_handle(struct ResolverHandle* rh) +{ + struct AuthorityChain *ac; + struct AuthorityChain *ac_next; + + if (NULL == rh) + return; + + ac = rh->authority_chain_head; + + while (NULL != ac) + { + ac_next = ac->next; + GNUNET_free(ac); + ac = ac_next; + } + GNUNET_free(rh); +} + + +/** + * Callback when record data is put into namestore + * + * @param cls the closure + * @param success GNUNET_OK on success + * @param emsg the error message. NULL if SUCCESS==GNUNET_OK + */ +void +on_namestore_record_put_result(void *cls, + int32_t success, + const char *emsg) +{ + if (GNUNET_NO == success) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_NS: records already in namestore\n"); + return; + } + else if (GNUNET_YES == success) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_NS: records successfully put in namestore\n"); + return; + } + + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "GNS_NS: Error putting records into namestore: %s\n", emsg); +} + +static void +handle_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct ResolverHandle *rh = cls; + + if (rh->timeout_cont) + rh->timeout_cont(rh->timeout_cont_cls, tc); +} + +/** + * Processor for background lookups in the DHT + * + * @param cls closure (NULL) + * @param rd_count number of records found (not 0) + * @param rd record data + */ +static void +background_lookup_result_processor(void *cls, + uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + //We could do sth verbose/more useful here but it doesn't make any difference + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_BG: background dht lookup for finished. (%d results)\n", + rd_count); +} + +/** + * Handle timeout for DHT requests + * + * @param cls the request handle as closure + * @param tc the task context + */ +static void +dht_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct ResolverHandle *rh = cls; + struct RecordLookupHandle *rlh = (struct RecordLookupHandle *)rh->proc_cls; + char new_name[MAX_DNS_NAME_LENGTH]; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: dht lookup for query %s (%ds)timed out.\n", + rh->id, rh->name, rh->timeout.rel_value); + /** + * Start resolution in bg + */ + //strcpy(new_name, rh->name); + //memcpy(new_name+strlen(new_name), GNUNET_GNS_TLD, strlen(GNUNET_GNS_TLD)); + GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s", + rh->name, GNUNET_GNS_TLD); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Starting background lookup for %s type %d\n", + rh->id, new_name, rlh->record_type); + + gns_resolver_lookup_record(rh->authority, + rh->private_local_zone, + rlh->record_type, + new_name, + rh->priv_key, + GNUNET_TIME_UNIT_FOREVER_REL, + &background_lookup_result_processor, + NULL); + rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_DHT_get_stop (rh->get_handle); + rh->get_handle = NULL; + rh->proc(rh->proc_cls, rh, 0, NULL); +} + + +/** + * Function called when we get a result from the dht + * for our record query + * + * @param cls the request handle + * @param exp lifetime + * @param key the key the record was stored under + * @param get_path get path + * @param get_path_length get path length + * @param put_path put path + * @param put_path_length put path length + * @param type the block type + * @param size the size of the record + * @param data the record data + */ +static void +process_record_result_dht(void* cls, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, + enum GNUNET_BLOCK_Type type, + size_t size, const void *data) +{ + struct ResolverHandle *rh; + struct RecordLookupHandle *rlh; + struct GNSNameRecordBlock *nrb; + uint32_t num_records; + char* name = NULL; + char* rd_data = (char*)data; + int i; + int rd_size; + + rh = (struct ResolverHandle *)cls; + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: got dht result (size=%d)\n", rh->id, size); + + if (data == NULL) + return; + + //FIXME maybe check expiration here, check block type + + + rlh = (struct RecordLookupHandle *) rh->proc_cls; + nrb = (struct GNSNameRecordBlock*)data; + + /* stop lookup and timeout task */ + GNUNET_DHT_get_stop (rh->get_handle); + rh->get_handle = NULL; + + if (rh->dht_heap_node != NULL) + { + GNUNET_CONTAINER_heap_remove_node(rh->dht_heap_node); + rh->dht_heap_node = NULL; + } + + if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel(rh->timeout_task); + rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + + rh->get_handle = NULL; + name = (char*)&nrb[1]; + num_records = ntohl(nrb->rd_count); + { + struct GNUNET_NAMESTORE_RecordData rd[num_records]; + + rd_data += strlen(name) + 1 + sizeof(struct GNSNameRecordBlock); + rd_size = size - strlen(name) - 1 - sizeof(struct GNSNameRecordBlock); + + if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (rd_size, + rd_data, + num_records, + rd)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "GNS_PHASE_REC-%d: Error deserializing data!\n", rh->id); + return; + } + + for (i=0; iid, name, rh->name); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Got type: %d\n", + rh->id, rd[i].record_type); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Got data length: %d\n", + rh->id, rd[i].data_size); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Got flag %d\n", + rh->id, rd[i].flags); + + if ((strcmp(name, rh->name) == 0) && + (rd[i].record_type == rlh->record_type)) + { + rh->answered++; + } + + } + + /** + * FIXME check pubkey against existing key in namestore? + * https://gnunet.org/bugs/view.php?id=2179 + */ + + /* Save to namestore */ + GNUNET_NAMESTORE_record_put (namestore_handle, + &nrb->public_key, + name, + exp, + num_records, + rd, + &nrb->signature, + &on_namestore_record_put_result, //cont + NULL); //cls + + + if (rh->answered) + rh->proc(rh->proc_cls, rh, num_records, rd); + else + rh->proc(rh->proc_cls, rh, 0, NULL); + } + +} + + +/** + * Start DHT lookup for a (name -> query->record_type) record in + * rh->authority's zone + * + * @param rh the pending gns query context + */ +static void +resolve_record_dht(struct ResolverHandle *rh) +{ + uint32_t xquery; + struct GNUNET_CRYPTO_ShortHashCode name_hash; + GNUNET_HashCode lookup_key; + GNUNET_HashCode name_hash_double; + GNUNET_HashCode zone_hash_double; + struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string; + struct RecordLookupHandle *rlh = (struct RecordLookupHandle *)rh->proc_cls; + struct ResolverHandle *rh_heap_root; + + GNUNET_CRYPTO_short_hash(rh->name, strlen(rh->name), &name_hash); + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_short_hash_double(&rh->authority, &zone_hash_double); + GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &lookup_key); + GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: starting dht lookup for %s with key: %s\n", + rh->id, rh->name, (char*)&lookup_key_string); + + //rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + rh->dht_heap_node = NULL; + + if (rh->timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) + { + /** + * Update timeout if necessary + */ + if (rh->timeout_task == GNUNET_SCHEDULER_NO_TASK) + { + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Adjusting timeout\n", rh->id); + /* + * Set timeout for authority lookup phase to 1/2 + */ + rh->timeout_task = GNUNET_SCHEDULER_add_delayed( + GNUNET_TIME_relative_divide(rh->timeout, 2), + &handle_lookup_timeout, + rh); + } + //rh->timeout_task = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT, + // &dht_lookup_timeout, + // rh); + rh->timeout_cont = &dht_lookup_timeout; + rh->timeout_cont_cls = rh; + } + else + { + if (max_allowed_background_queries <= + GNUNET_CONTAINER_heap_get_size (dht_lookup_heap)) + { + rh_heap_root = GNUNET_CONTAINER_heap_remove_root (dht_lookup_heap); + GNUNET_DHT_get_stop(rh_heap_root->get_handle); + rh_heap_root->get_handle = NULL; + rh_heap_root->dht_heap_node = NULL; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Replacing oldest background query for %s\n", + rh->id, rh_heap_root->name); + rh_heap_root->proc(rh_heap_root->proc_cls, + rh_heap_root, + 0, + NULL); + } + rh->dht_heap_node = GNUNET_CONTAINER_heap_insert (dht_lookup_heap, + rh, + GNUNET_TIME_absolute_get().abs_value); + } + + xquery = htonl(rlh->record_type); + + GNUNET_assert(rh->get_handle == NULL); + rh->get_handle = GNUNET_DHT_get_start(dht_handle, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + &lookup_key, + DHT_GNS_REPLICATION_LEVEL, + GNUNET_DHT_RO_NONE, + &xquery, + sizeof(xquery), + &process_record_result_dht, + rh); + +} + + +/** + * Namestore calls this function if we have record for this name. + * (or with rd_count=0 to indicate no matches) + * + * @param cls the pending query + * @param key the key of the zone we did the lookup + * @param expiration expiration date of the namestore entry + * @param name the name for which we need an authority + * @param rd_count the number of records with 'name' + * @param rd the record data + * @param signature the signature of the authority for the record data + */ +static void +process_record_result_ns(void* cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, + struct GNUNET_TIME_Absolute expiration, + const char *name, unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct ResolverHandle *rh; + struct RecordLookupHandle *rlh; + struct GNUNET_TIME_Relative remaining_time; + struct GNUNET_CRYPTO_ShortHashCode zone; + + rh = (struct ResolverHandle *) cls; + rlh = (struct RecordLookupHandle *)rh->proc_cls; + GNUNET_CRYPTO_short_hash(key, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone); + remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); + + + + rh->status = 0; + + if (name != NULL) + { + rh->status |= RSL_RECORD_EXISTS; + } + + if (remaining_time.rel_value == 0) + { + rh->status |= RSL_RECORD_EXPIRED; + } + + if (rd_count == 0) + { + /** + * Lookup terminated and no results + */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Namestore lookup for %s terminated without results\n", + rh->id, name); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Record %s unknown in namestore\n", + rh->id, rh->name); + /** + * Our zone and no result? Cannot resolve TT + */ + rh->proc(rh->proc_cls, rh, 0, NULL); + return; + + } + else + { + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Processing additional result %s from namestore\n", + rh->id, name); + int i; + for (i=0; irecord_type) + continue; + + if (ignore_pending_records && + (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Record %s is awaiting user confirmation. Skipping\n", + rh->id, name); + continue; + } + + if ((GNUNET_TIME_absolute_get_remaining (rd[i].expiration)).rel_value + == 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: This record is expired. Skipping\n", + rh->id); + continue; + } + + rh->answered++; + + } + + /** + * no answers found + */ + if (rh->answered == 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: No answers found. This is odd!\n", rh->id); + rh->proc(rh->proc_cls, rh, 0, NULL); + return; + } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Found %d answer(s) to query in %d records!\n", + rh->id, rh->answered, rd_count); + + rh->proc(rh->proc_cls, rh, rd_count, rd); + } +} + + +/** + * The final phase of resolution. + * rh->name is a name that is canonical and we do not have a delegation. + * Query namestore for this record + * + * @param rh the pending lookup + */ +static void +resolve_record_ns(struct ResolverHandle *rh) +{ + struct RecordLookupHandle *rlh = (struct RecordLookupHandle *)rh->proc_cls; + + /* We cancel here as to not include the ns lookup in the timeout */ + if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel(rh->timeout_task); + rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + + /** + * Try to resolve this record in our namestore. + * The name to resolve is now in rh->authority_name + * since we tried to resolve it to an authority + * and failed. + **/ + GNUNET_NAMESTORE_lookup_record(namestore_handle, + &rh->authority, + rh->name, + rlh->record_type, + &process_record_result_ns, + rh); +} + + + +/** + * Handle timeout for DHT requests + * + * @param cls the request handle as closure + * @param tc the task context + */ +static void +dht_authority_lookup_timeout(void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct ResolverHandle *rh = cls; + struct RecordLookupHandle *rlh = rh->proc_cls; + char new_name[MAX_DNS_NAME_LENGTH]; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: dht lookup for query %s (%ds)timed out.\n", + rh->id, rh->authority_name, rh->timeout.rel_value); + + rh->status |= RSL_TIMED_OUT; + + rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_DHT_get_stop (rh->get_handle); + rh->get_handle = NULL; + + if (strcmp(rh->name, "") == 0) + { + /* + * promote authority back to name and try to resolve record + */ + strcpy(rh->name, rh->authority_name); + rh->proc(rh->proc_cls, rh, 0, NULL); + return; + } + + /** + * Start resolution in bg + */ + GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, + "%s.%s.%s", rh->name, rh->authority_name, GNUNET_GNS_TLD); + //strcpy(new_name, rh->name); + //strcpy(new_name+strlen(new_name), "."); + //memcpy(new_name+strlen(new_name), GNUNET_GNS_TLD, strlen(GNUNET_GNS_TLD)); + + strcpy(rh->name, new_name); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Starting background query for %s type %d\n", + rh->id, rh->name, rlh->record_type); + + gns_resolver_lookup_record(rh->authority, + rh->private_local_zone, + rlh->record_type, + new_name, + rh->priv_key, + GNUNET_TIME_UNIT_FOREVER_REL, + &background_lookup_result_processor, + NULL); + + rh->proc(rh->proc_cls, rh, 0, NULL); +} + +/* Prototype */ +static void resolve_delegation_dht(struct ResolverHandle *rh); + +/* Prototype */ +static void resolve_delegation_ns(struct ResolverHandle *rh); + + +/** + * Namestore resolution for delegation finished. Processing result. + * + * @param cls the closure + * @param rh resolver handle + * @param rd_count number of results (always 0) + * @param rd record data (always NULL) + */ +static void +handle_delegation_ns(void* cls, struct ResolverHandle *rh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd); + + +/** + * Function called when we get a result from the dht + * for our query. Recursively tries to resolve authorities + * for name in DHT. + * + * @param cls the request handle + * @param exp lifetime + * @param key the key the record was stored under + * @param get_path get path + * @param get_path_length get path length + * @param put_path put path + * @param put_path_length put path length + * @param type the block type + * @param size the size of the record + * @param data the record data + */ +static void +process_delegation_result_dht(void* cls, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, + enum GNUNET_BLOCK_Type type, + size_t size, const void *data) +{ + struct ResolverHandle *rh; + struct GNSNameRecordBlock *nrb; + uint32_t num_records; + char* name = NULL; + char* rd_data = (char*) data; + int i; + int rd_size; + struct GNUNET_CRYPTO_ShortHashCode zone, name_hash; + GNUNET_HashCode zone_hash_double, name_hash_double; + + rh = (struct ResolverHandle *)cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Got DHT result\n", rh->id); + + if (data == NULL) + return; + + nrb = (struct GNSNameRecordBlock*)data; + + /* stop dht lookup and timeout task */ + GNUNET_DHT_get_stop (rh->get_handle); + + rh->get_handle = NULL; + + if (rh->dht_heap_node != NULL) + { + GNUNET_CONTAINER_heap_remove_node(rh->dht_heap_node); + rh->dht_heap_node = NULL; + } + + num_records = ntohl(nrb->rd_count); + name = (char*)&nrb[1]; + { + struct GNUNET_NAMESTORE_RecordData rd[num_records]; + + rd_data += strlen(name) + 1 + sizeof(struct GNSNameRecordBlock); + rd_size = size - strlen(name) - 1 - sizeof(struct GNSNameRecordBlock); + + if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (rd_size, + rd_data, + num_records, + rd)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "GNS_PHASE_DELEGATE_DHT-%llu: Error deserializing data!\n", + rh->id); + return; + } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Got name: %s (wanted %s)\n", + rh->id, name, rh->authority_name); + for (i=0; iid, name, rh->authority_name); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Got type: %d (wanted %d)\n", + rh->id, rd[i].record_type, GNUNET_GNS_RECORD_PKEY); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Got data length: %d\n", + rh->id, rd[i].data_size); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Got flag %d\n", + rh->id, rd[i].flags); + + if ((strcmp(name, rh->authority_name) == 0) && + (rd[i].record_type == GNUNET_GNS_RECORD_PKEY)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Authority found in DHT\n", + rh->id); + rh->answered = 1; + memcpy(&rh->authority, rd[i].data, sizeof(struct GNUNET_CRYPTO_ShortHashCode)); + struct AuthorityChain *auth = + GNUNET_malloc(sizeof(struct AuthorityChain)); + auth->zone = rh->authority; + memset(auth->name, 0, strlen(rh->authority_name)+1); + strcpy(auth->name, rh->authority_name); + GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head, + rh->authority_chain_tail, + auth); + + /** try to import pkey if private key available */ + if (rh->priv_key) + process_discovered_authority(name, auth->zone, + rh->authority_chain_tail->zone, + rh->priv_key); + } + + } + + + GNUNET_CRYPTO_short_hash(name, strlen(name), &name_hash); + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_hash_xor(key, &name_hash_double, &zone_hash_double); + GNUNET_CRYPTO_short_hash_from_truncation (&zone_hash_double, &zone); + + /* Save to namestore */ + if (0 != GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_tail->zone, + &zone)) + { + GNUNET_NAMESTORE_record_put (namestore_handle, + &nrb->public_key, + name, + exp, + num_records, + rd, + &nrb->signature, + &on_namestore_record_put_result, //cont + NULL); //cls + } + } + + if (rh->answered) + { + rh->answered = 0; + /** + * delegate + * FIXME in this case. should we ask namestore again? + */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Answer from DHT for %s. Yet to resolve: %s\n", + rh->id, rh->authority_name, rh->name); + if (strcmp(rh->name, "") == 0) + { + rh->proc(rh->proc_cls, rh, 0, NULL); + } + else + { + rh->proc = &handle_delegation_ns; + resolve_delegation_ns(rh); + } + return; + } + + /** + * No pkey but name exists + * promote back + */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Adding %s back to %s\n", + rh->id, rh->authority_name, rh->name); + if (strcmp(rh->name, "") == 0) + strcpy(rh->name, rh->authority_name); + else + GNUNET_snprintf(rh->name, MAX_DNS_NAME_LENGTH, "%s.%s", + rh->name, rh->authority_name); //FIXME ret + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: %s restored\n", rh->id, rh->name); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: DHT authority lookup found no match!\n", + rh->id); + rh->proc(rh->proc_cls, rh, 0, NULL); +} + +#define MAX_SOA_LENGTH sizeof(uint32_t)+sizeof(uint32_t)+sizeof(uint32_t)+sizeof(uint32_t)\ + +(MAX_DNS_NAME_LENGTH*2) +#define MAX_MX_LENGTH sizeof(uint16_t)+MAX_DNS_NAME_LENGTH + + +static void +expand_plus(char** dest, char* src, char* repl) +{ + char* pos; + unsigned int s_len = strlen(src)+1; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_POSTPROCESS: Got %s to expand with %s\n", src, repl); + + if (s_len < 3) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_POSTPROCESS: %s to short\n", src); + + /* no postprocessing */ + memcpy(*dest, src, s_len+1); + return; + } + + if (0 == strcmp(src+s_len-3, ".+")) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_POSTPROCESS: Expanding .+ in %s\n", src); + memset(*dest, 0, s_len+strlen(repl)+strlen(GNUNET_GNS_TLD)); + strcpy(*dest, src); + pos = *dest+s_len-2; + strcpy(pos, repl); + pos += strlen(repl); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_POSTPROCESS: Expanded to %s\n", *dest); + } + else + { + memcpy(*dest, src, s_len+1); + } +} + +/** + * finish lookup + */ +static void +finish_lookup(struct ResolverHandle *rh, + struct RecordLookupHandle* rlh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + int i; + char new_rr_data[MAX_DNS_NAME_LENGTH]; + char new_mx_data[MAX_MX_LENGTH]; + char new_soa_data[MAX_SOA_LENGTH]; + struct GNUNET_NAMESTORE_RecordData p_rd[rd_count]; + char* repl_string; + char* pos; + unsigned int offset; + + if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel(rh->timeout_task); + rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (rd_count > 0) + memcpy(p_rd, rd, rd_count*sizeof(struct GNUNET_NAMESTORE_RecordData)); + + for (i = 0; i < rd_count; i++) + { + + if (rd[i].record_type != GNUNET_GNS_RECORD_TYPE_NS && + rd[i].record_type != GNUNET_GNS_RECORD_TYPE_CNAME && + rd[i].record_type != GNUNET_GNS_RECORD_MX && + rd[i].record_type != GNUNET_GNS_RECORD_TYPE_SOA) + { + p_rd[i].data = rd[i].data; + continue; + } + + /** + * for all those records we 'should' + * also try to resolve the A/AAAA records (RFC1035) + * This is a feature and not important + */ + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_POSTPROCESS: Postprocessing\n"); + + if (strcmp(rh->name, "+") == 0) + repl_string = rlh->name; + else + repl_string = rlh->name+strlen(rh->name)+1; + + offset = 0; + if (rd[i].record_type == GNUNET_GNS_RECORD_MX) + { + memcpy(new_mx_data, (char*)rd[i].data, sizeof(uint16_t)); + offset = sizeof(uint16_t); + pos = new_mx_data+offset; + expand_plus(&pos, (char*)rd[i].data+sizeof(uint16_t), + repl_string); + offset += strlen(new_mx_data+sizeof(uint16_t))+1; + p_rd[i].data = new_mx_data; + p_rd[i].data_size = offset; + } + else if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SOA) + { + /* expand mname and rname */ + pos = new_soa_data; + expand_plus(&pos, (char*)rd[i].data, repl_string); + offset = strlen(new_soa_data)+1; + pos = new_soa_data+offset; + expand_plus(&pos, (char*)rd[i].data+offset, repl_string); + offset += strlen(new_soa_data+offset)+1; + /* cpy the 4 numbers serial refresh retry and expire */ + memcpy(new_soa_data+offset, (char*)rd[i].data+offset, sizeof(uint32_t)*5); + offset += sizeof(uint32_t)*5; + p_rd[i].data_size = offset; + p_rd[i].data = new_soa_data; + } + else + { + pos = new_rr_data; + expand_plus(&pos, (char*)rd[i].data, repl_string); + p_rd[i].data_size = strlen(new_rr_data)+1; + p_rd[i].data = new_rr_data; + } + + } + + rlh->proc(rlh->proc_cls, rd_count, p_rd); + GNUNET_free(rlh); + +} + +/** + * Process DHT lookup result for record. + * + * @param cls the closure + * @param rh resolver handle + * @param rd_count number of results + * @param rd record data + */ +static void +handle_record_dht(void* cls, struct ResolverHandle *rh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct RecordLookupHandle* rlh; + + rlh = (struct RecordLookupHandle*)cls; + if (rd_count == 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: No records for %s found in DHT. Aborting\n", + rh->id, rh->name); + /* give up, cannot resolve */ + finish_lookup(rh, rlh, 0, NULL); + free_resolver_handle(rh); + return; + } + + /* results found yay */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Record resolved from DHT!", rh->id); + + finish_lookup(rh, rlh, rd_count, rd); + free_resolver_handle(rh); + +} + + +/** + * Process namestore lookup result for record. + * + * @param cls the closure + * @param rh resolver handle + * @param rd_count number of results + * @param rd record data + */ +static void +handle_record_ns(void* cls, struct ResolverHandle *rh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct RecordLookupHandle* rlh; + rlh = (struct RecordLookupHandle*) cls; + if (rd_count == 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: NS returned no records. (status: %d)!\n", + rh->id, + rh->status); + + /** + * There are 4 conditions that have to met for us to consult the DHT: + * 1. The entry in the DHT is RSL_RECORD_EXPIRED AND + * 2. No entry in the NS existed AND + * 3. The zone queried is not the local resolver's zone AND + * 4. The name that was looked up is '+' + * because if it was any other canonical name we either already queried + * the DHT for the authority in the authority lookup phase (and thus + * would already have an entry in the NS for the record) + */ + if (rh->status & (RSL_RECORD_EXPIRED | !RSL_RECORD_EXISTS) && + GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, + &rh->private_local_zone) && + (strcmp(rh->name, "+") == 0)) + { + rh->proc = &handle_record_dht; + resolve_record_dht(rh); + return; + } + /* give up, cannot resolve */ + finish_lookup(rh, rlh, 0, NULL); + free_resolver_handle(rh); + return; + } + + /* results found yay */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%d: Record resolved from namestore!", rh->id); + + finish_lookup(rh, rlh, rd_count, rd); + + free_resolver_handle(rh); + +} + + +/** + * Determine if this name is canonical. + * i.e. + * a.b.gnunet = not canonical + * a = canonical + * + * @param name the name to test + * @return 1 if canonical + */ +static int +is_canonical(char* name) +{ + uint32_t len = strlen(name); + int i; + + for (i=0; i 0; len--) + { + if (*(name+len) == '.') + break; + } + + //Was canonical? + if (len == 0) + return; + + name[len] = '\0'; + + strcpy(dest, (name+len+1)); +} + +/** + * Checks if name is in tld + * + * @param name the name to check + * @param tld the TLD to check for + * @return GNUNET_YES or GNUNET_NO + */ +int +is_tld(const char* name, const char* tld) +{ + int offset = 0; + + if (strlen(name) <= strlen(tld)) + { + return GNUNET_NO; + } + + offset = strlen(name)-strlen(tld); + if (strcmp(name+offset, tld) != 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "%s is not in .%s TLD\n", name, tld); + return GNUNET_NO; + } + return GNUNET_YES; +} + +/** + * DHT resolution for delegation finished. Processing result. + * + * @param cls the closure + * @param rh resolver handle + * @param rd_count number of results (always 0) + * @param rd record data (always NULL) + */ +static void +handle_delegation_dht(void* cls, struct ResolverHandle *rh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct RecordLookupHandle* rlh; + rlh = (struct RecordLookupHandle*) cls; + + + if (strcmp(rh->name, "") == 0) + { + if ((rlh->record_type == GNUNET_GNS_RECORD_PKEY)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Resolved queried PKEY via DHT.\n", + rh->id); + finish_lookup(rh, rlh, rd_count, rd); + free_resolver_handle(rh); + return; + } + /* We resolved full name for delegation. resolving record */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Resolved full name for delegation via DHT.\n", + rh->id); + strcpy(rh->name, "+\0"); + rh->proc = &handle_record_ns; + resolve_record_ns(rh); + return; + } + + /** + * we still have some left + **/ + if (is_canonical(rh->name)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Resolving canonical record %s in ns\n", + rh->id, + rh->name); + rh->proc = &handle_record_ns; + resolve_record_ns(rh); + return; + } + /* give up, cannot resolve */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Cannot fully resolve delegation for %s via DHT!\n", + rh->id, rh->name); + finish_lookup(rh, rlh, 0, NULL); + free_resolver_handle(rh); +} + + +/** + * Start DHT lookup for a name -> PKEY (compare NS) record in + * rh->authority's zone + * + * @param rh the pending gns query + */ +static void +resolve_delegation_dht(struct ResolverHandle *rh) +{ + uint32_t xquery; + struct GNUNET_CRYPTO_ShortHashCode name_hash; + GNUNET_HashCode name_hash_double; + GNUNET_HashCode zone_hash_double; + GNUNET_HashCode lookup_key; + struct ResolverHandle *rh_heap_root; + + pop_tld(rh->name, rh->authority_name); + GNUNET_CRYPTO_short_hash(rh->authority_name, + strlen(rh->authority_name), + &name_hash); + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_short_hash_double(&rh->authority, &zone_hash_double); + GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &lookup_key); + + rh->dht_heap_node = NULL; + + if (rh->timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) + { + //rh->timeout_task = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT, + // &dht_authority_lookup_timeout, + // rh); + rh->timeout_cont = &dht_authority_lookup_timeout; + rh->timeout_cont_cls = rh; + } + else + { + if (max_allowed_background_queries <= + GNUNET_CONTAINER_heap_get_size (dht_lookup_heap)) + { + /* terminate oldest lookup */ + rh_heap_root = GNUNET_CONTAINER_heap_remove_root (dht_lookup_heap); + GNUNET_DHT_get_stop(rh_heap_root->get_handle); + rh_heap_root->dht_heap_node = NULL; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_DHT-%llu: Replacing oldest background query for %s\n", + rh->id, rh_heap_root->authority_name); + + rh_heap_root->proc(rh_heap_root->proc_cls, + rh_heap_root, + 0, + NULL); + } + rh->dht_heap_node = GNUNET_CONTAINER_heap_insert (dht_lookup_heap, + rh, + GNUNET_TIME_absolute_get().abs_value); + } + + xquery = htonl(GNUNET_GNS_RECORD_PKEY); + + GNUNET_assert(rh->get_handle == NULL); + rh->get_handle = GNUNET_DHT_get_start(dht_handle, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + &lookup_key, + DHT_GNS_REPLICATION_LEVEL, + GNUNET_DHT_RO_NONE, + &xquery, + sizeof(xquery), + &process_delegation_result_dht, + rh); + +} + + +/** + * Namestore resolution for delegation finished. Processing result. + * + * @param cls the closure + * @param rh resolver handle + * @param rd_count number of results (always 0) + * @param rd record data (always NULL) + */ +static void +handle_delegation_ns(void* cls, struct ResolverHandle *rh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct RecordLookupHandle* rlh; + rlh = (struct RecordLookupHandle*) cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Resolution status: %d.\n", + rh->id, rh->status); + + if (strcmp(rh->name, "") == 0) + { + if ((rlh->record_type == GNUNET_GNS_RECORD_PKEY)) + { + GNUNET_assert(rd_count == 1); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried PKEY in NS.\n", + rh->id); + finish_lookup(rh, rlh, rd_count, rd); + free_resolver_handle(rh); + return; + } + /* We resolved full name for delegation. resolving record */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Resolved full name for delegation.\n", + rh->id); + strcpy(rh->name, "+\0"); + rh->proc = &handle_record_ns; + resolve_record_ns(rh); + return; + } + + /** + * we still have some left + * check if authority in ns is fresh + * and exists + * or we are authority + **/ + if (((rh->status & RSL_RECORD_EXISTS) && (!(rh->status & RSL_RECORD_EXPIRED))) + || !GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, + &rh->private_local_zone)) + { + if (is_canonical(rh->name)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Resolving canonical record %s\n", + rh->id, + rh->name); + rh->proc = &handle_record_ns; + resolve_record_ns(rh); + } + else + { + /* give up, cannot resolve */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Cannot fully resolve delegation for %s!\n", + rh->id, + rh->name); + finish_lookup(rh, rlh, rd_count, rd); + //rlh->proc(rlh->proc_cls, 0, NULL); + } + return; + } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Trying to resolve delegation for %s via DHT\n", + rh->id, rh->name); + rh->proc = &handle_delegation_dht; + resolve_delegation_dht(rh); +} + + + +/** + * This is a callback function that should give us only PKEY + * records. Used to query the namestore for the authority (PKEY) + * for 'name'. It will recursively try to resolve the + * authority for a given name from the namestore. + * + * @param cls the pending query + * @param key the key of the zone we did the lookup + * @param expiration expiration date of the record data set in the namestore + * @param name the name for which we need an authority + * @param rd_count the number of records with 'name' + * @param rd the record data + * @param signature the signature of the authority for the record data + */ +static void +process_delegation_result_ns(void* cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, + struct GNUNET_TIME_Absolute expiration, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct ResolverHandle *rh; + struct GNUNET_TIME_Relative remaining_time; + struct GNUNET_CRYPTO_ShortHashCode zone; + char new_name[MAX_DNS_NAME_LENGTH]; + + rh = (struct ResolverHandle *)cls; + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Got %d records from authority lookup\n", + rh->id, rd_count); + + GNUNET_CRYPTO_short_hash(key, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone); + remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); + + rh->status = 0; + + if (name != NULL) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Records with name %s exist.\n", + rh->id, name); + rh->status |= RSL_RECORD_EXISTS; + } + + if (remaining_time.rel_value == 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Record set %s expired.\n", + rh->id, name); + rh->status |= RSL_RECORD_EXPIRED; + } + + /** + * No authority found in namestore. + */ + if (rd_count == 0) + { + /** + * We did not find an authority in the namestore + */ + + /** + * No PKEY in zone. + * Promote this authority back to a name maybe it is + * our record. + */ + if (strcmp(rh->name, "") == 0) + { + /* simply promote back */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n", + rh->id, rh->authority_name); + strcpy(rh->name, rh->authority_name); + } + else + { + /* add back to existing name */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Adding %s back to %s\n", + rh->id, rh->authority_name, rh->name); + //memset(new_name, 0, strlen(rh->name) + strlen(rh->authority_name) + 2); + GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s", + rh->name, rh->authority_name); + //strcpy(new_name, rh->name); + //strcpy(new_name+strlen(new_name), "."); + //strcpy(new_name+strlen(new_name), rh->authority_name); + strcpy(rh->name, new_name); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: %s restored\n", rh->id, rh->name); + } + rh->proc(rh->proc_cls, rh, 0, NULL); + return; + } + + /** + * We found an authority that may be able to help us + * move on with query + * Note only 1 pkey should have been returned.. anything else would be strange + */ + int i; + for (i=0; iid); + continue; + } + + if ((GNUNET_TIME_absolute_get_remaining (rd[i].expiration)).rel_value + == 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: This pkey is expired.\n", + rh->id); + if (remaining_time.rel_value == 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: This dht entry is expired.\n", + rh->id); + rh->authority_chain_head->fresh = 0; + rh->proc(rh->proc_cls, rh, 0, NULL); + return; + } + + continue; + } + + /** + * Resolve rest of query with new authority + */ + GNUNET_assert(rd[i].record_type == GNUNET_GNS_RECORD_PKEY); + memcpy(&rh->authority, rd[i].data, + sizeof(struct GNUNET_CRYPTO_ShortHashCode)); + struct AuthorityChain *auth = GNUNET_malloc(sizeof(struct AuthorityChain)); + auth->zone = rh->authority; + memset(auth->name, 0, strlen(rh->authority_name)+1); + strcpy(auth->name, rh->authority_name); + GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head, + rh->authority_chain_tail, + auth); + + /** try to import pkey if private key available + * TODO: Only import last one? + */ + if (rh->priv_key && (name != NULL)) + process_discovered_authority((char*)name, auth->zone, + rh->authority_chain_tail->zone, + rh->priv_key); + /** + * We are done with PKEY resolution if name is empty + * else resolve again with new authority + */ + if (strcmp(rh->name, "") == 0) + rh->proc(rh->proc_cls, rh, rd_count, rd); + else + resolve_delegation_ns(rh); + return; + } + + /** + * no answers found + */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Authority lookup and no PKEY...\n", rh->id); + /** + * If we have found some records for the LAST label + * we return the results. Else null. + */ + if (strcmp(rh->name, "") == 0) + { + /* simply promote back */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n", + rh->id, rh->authority_name); + strcpy(rh->name, rh->authority_name); + rh->proc(rh->proc_cls, rh, rd_count, rd); + } + else + { + rh->proc(rh->proc_cls, rh, 0, NULL); + } +} + + +/** + * Resolve the delegation chain for the request in our namestore + * + * @param rh the resolver handle + */ +static void +resolve_delegation_ns(struct ResolverHandle *rh) +{ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Resolving delegation for %s\n", + rh->id, rh->name); + pop_tld(rh->name, rh->authority_name); + GNUNET_NAMESTORE_lookup_record(namestore_handle, + &rh->authority, + rh->authority_name, + GNUNET_GNS_RECORD_ANY, + &process_delegation_result_ns, + rh); + +} + + +/** + * Lookup of a record in a specific zone + * calls lookup result processor on result + * + * @param zone the root zone + * @param pzone the private local zone + * @param record_type the record type to look up + * @param name the name to look up + * @param key a private key for use with PSEU import (can be NULL) + * @param timeout timeout for resolution + * @param proc the processor to call on result + * @param cls the closure to pass to proc + */ +void +gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_ShortHashCode pzone, + uint32_t record_type, + const char* name, + struct GNUNET_CRYPTO_RsaPrivateKey *key, + struct GNUNET_TIME_Relative timeout, + RecordLookupProcessor proc, + void* cls) +{ + struct ResolverHandle *rh; + struct RecordLookupHandle* rlh; + char string_hash[MAX_DNS_LABEL_LENGTH]; + char nzkey[MAX_DNS_LABEL_LENGTH]; + char* nzkey_ptr = nzkey; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting resolution for %s (type=%d)!\n", + name, record_type); + + + if (is_canonical((char*)name) && (strcmp(GNUNET_GNS_TLD, name) != 0)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s is canonical and not gnunet -> cannot resolve!\n", name); + proc(cls, 0, NULL); + return; + } + + rlh = GNUNET_malloc(sizeof(struct RecordLookupHandle)); + rh = GNUNET_malloc(sizeof (struct ResolverHandle)); + + rh->authority = zone; + rh->id = rid++; + rh->proc_cls = rlh; + rh->priv_key = key; + rh->timeout = timeout; + rh->get_handle = NULL; + rh->private_local_zone = pzone; + + if (timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) + { + /* + * Set timeout for authority lookup phase to 1/2 + */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Timeout for lookup set to %ds\n", rh->timeout.rel_value); + rh->timeout_task = GNUNET_SCHEDULER_add_delayed( + GNUNET_TIME_relative_divide(timeout, 2), + &handle_lookup_timeout, + rh); + rh->timeout_cont = &dht_authority_lookup_timeout; + rh->timeout_cont_cls = rh; + } + else + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "No timeout for query!\n"); + rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (strcmp(GNUNET_GNS_TLD, name) == 0) + { + /** + * Only 'gnunet' given + */ + strcpy(rh->name, "\0"); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Checking for TLD...\n"); + if (is_zkey_tld(name) == GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "TLD is zkey\n"); + /** + * This is a zkey tld + * build hash and use as initial authority + */ + memset(rh->name, 0, + strlen(name)-strlen(GNUNET_GNS_TLD_ZKEY)); + memcpy(rh->name, name, + strlen(name)-strlen(GNUNET_GNS_TLD_ZKEY) - 1); + pop_tld(rh->name, string_hash); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "ZKEY is %s!\n", string_hash); + + GNUNET_STRINGS_utf8_toupper(string_hash, &nzkey_ptr); + + if (GNUNET_OK != GNUNET_CRYPTO_short_hash_from_string(nzkey, + &rh->authority)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Cannot convert ZKEY %s to hash!\n", string_hash); + GNUNET_free(rh); + GNUNET_free(rlh); + proc(cls, 0, NULL); + return; + } + + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "TLD is gnunet\n"); + /** + * Presumably GNUNET tld + */ + memset(rh->name, 0, + strlen(name)-strlen(GNUNET_GNS_TLD)); + memcpy(rh->name, name, + strlen(name)-strlen(GNUNET_GNS_TLD) - 1); + } + } + + /** + * Initialize authority chain + */ + rh->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain)); + rh->authority_chain_head->prev = NULL; + rh->authority_chain_head->next = NULL; + rh->authority_chain_tail = rh->authority_chain_head; + rh->authority_chain_head->zone = rh->authority; + + /** + * Copy original query into lookup handle + */ + rlh->record_type = record_type; + memset(rlh->name, 0, strlen(name) + 1); + strcpy(rlh->name, name); + rlh->proc = proc; + rlh->proc_cls = cls; + + rh->proc = &handle_delegation_ns; + resolve_delegation_ns(rh); +} + +/******** END Record Resolver ***********/ + + +/** + * Callback calles by namestore for a zone to name + * result + * + * @param cls the closure + * @param zone_key the zone we queried + * @param expire the expiration time of the name + * @param name the name found or NULL + * @param rd_len number of records for the name + * @param rd the record data (PKEY) for the name + * @param signature the signature for the record data + */ +static void +process_zone_to_name_shorten(void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_len, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct ResolverHandle *rh = (struct ResolverHandle *)cls; + struct NameShortenHandle* nsh = (struct NameShortenHandle*)rh->proc_cls; + struct AuthorityChain *next_authority; + + char result[MAX_DNS_NAME_LENGTH]; + char tmp_name[MAX_DNS_NAME_LENGTH]; + size_t answer_len; + + /* we found a match in our own zone */ + if (rd_len != 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "result strlen %d\n", strlen(name)); + answer_len = strlen(rh->name) + strlen(name) + strlen(GNUNET_GNS_TLD) + 3; + memset(result, 0, answer_len); + if (strlen(rh->name) > 0) + { + strcpy(result, rh->name); + strcpy(result+strlen(rh->name), "."); + } + + strcpy(result+strlen(result), name); + strcpy(result+strlen(result), "."); + strcpy(result+strlen(result), GNUNET_GNS_TLD); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Sending shorten result %s\n", result); + + nsh->proc(nsh->proc_cls, result); + GNUNET_free(nsh); + free_resolver_handle(rh); + } + else if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, + &rh->private_local_zone) == 0) + { + /* our zone, just append .gnunet */ + answer_len = strlen(rh->name) + strlen(GNUNET_GNS_TLD) + 2; + memset(result, 0, answer_len); + strcpy(result, rh->name); + strcpy(result+strlen(rh->name), "."); + strcpy(result+strlen(rh->name)+1, GNUNET_GNS_TLD); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Our zone: Sending name as shorten result %s\n", rh->name); + + nsh->proc(nsh->proc_cls, result); + GNUNET_free(nsh); + free_resolver_handle(rh); + } + else + { + /** + * No PSEU found. + * continue with next authority + */ + next_authority = rh->authority_chain_head; + + GNUNET_snprintf(tmp_name, MAX_DNS_NAME_LENGTH, + "%s.%s", rh->name, next_authority->name); + + strcpy(rh->name, tmp_name); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "No PSEU found for authority %s. Promoting back: %s\n", + next_authority->name, rh->name); + + GNUNET_CONTAINER_DLL_remove(rh->authority_chain_head, + rh->authority_chain_tail, + next_authority); + + GNUNET_NAMESTORE_zone_to_name (namestore_handle, + &rh->authority_chain_tail->zone, + &rh->authority_chain_head->zone, + &process_zone_to_name_shorten, + rh); + } +} + +/** + * DHT resolution for delegation. Processing result. + * + * @param cls the closure + * @param rh resolver handle + * @param rd_count number of results + * @param rd record data + */ +static void +handle_delegation_dht_bg_shorten(void* cls, struct ResolverHandle *rh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + + /* We resolved full name for delegation. resolving record */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_SHORTEN: Resolved up to %s for delegation via DHT in background.\n", + rh->name); + free_resolver_handle(rh); +} + +/** + * Process result from namestore delegation lookup + * for shorten operation + * + * @param cls the client shorten handle + * @param rh the resolver handle + * @param rd_count number of results (0) + * @param rd data (NULL) + */ +void +handle_delegation_ns_shorten(void* cls, + struct ResolverHandle *rh, + uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct NameShortenHandle *nsh; + char result[MAX_DNS_NAME_LENGTH]; + size_t answer_len; + struct ResolverHandle *rh_bg; + + nsh = (struct NameShortenHandle *)cls; + + /** + * At this point rh->name contains the part of the name + * that we do not have a PKEY in our namestore to resolve. + * The authority chain in the resolver handle is now + * useful to backtrack if needed + */ + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "PKEY resolved as far as possible in ns up to %s!\n", rh->name); + + if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, + &rh->private_local_zone) == 0) + { + /** + * This is our zone append .gnunet unless name is empty + * (it shouldn't be, usually FIXME what happens if we + * shorten to our zone to a "" record??) + */ + + answer_len = strlen(rh->name) + strlen(GNUNET_GNS_TLD) + 2; + memset(result, 0, answer_len); + strcpy(result, rh->name); + strcpy(result+strlen(rh->name), "."); + strcpy(result+strlen(rh->name)+1, GNUNET_GNS_TLD); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Our zone: Sending name as shorten result %s\n", rh->name); + + nsh->proc(nsh->proc_cls, result); + GNUNET_free(nsh); + free_resolver_handle(rh); + return; + } + + /** + * we have to this before zone to name for rh might + * be freed by then + */ + rh_bg = NULL; + if (!is_canonical(rh->name)) + { + rh_bg = GNUNET_malloc(sizeof(struct ResolverHandle)); + memcpy(rh_bg, rh, sizeof(struct ResolverHandle)); + rh_bg->id = rid++; + } + + /* backtrack authorities for names */ + GNUNET_NAMESTORE_zone_to_name (namestore_handle, + &rh->authority_chain_tail->zone, //ours + &rh->authority_chain_head->zone, + &process_zone_to_name_shorten, + rh); + + if (rh_bg == NULL) + { + return; + } + + /** + * If authority resolution is incomplete we can do a background lookup + * of the full name so that next time we can (likely) fully or at least + * further shorten the name + */ + rh_bg->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain)); + rh_bg->authority_chain_tail = rh_bg->authority_chain_head; + rh_bg->authority_chain_head->zone = rh_bg->authority; + + rh_bg->proc = &handle_delegation_dht_bg_shorten; + rh_bg->proc_cls = NULL; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_SHORTEN: Starting background lookup for %s\n", + rh_bg->name); + + resolve_delegation_dht(rh_bg); + +} + + +/** + * Callback calles by namestore for a zone to name + * result + * + * @param cls the closure + * @param zone_key the zone we queried + * @param expire the expiration time of the name + * @param name the name found or NULL + * @param rd_len number of records for the name + * @param rd the record data (PKEY) for the name + * @param signature the signature for the record data + */ +static void +process_zone_to_name_zkey(void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_len, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct ResolverHandle *rh = cls; + struct NameShortenHandle *nsh = rh->proc_cls; + struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc; + char new_name[MAX_DNS_NAME_LENGTH]; + + /* zkey not in our zone */ + if (name == NULL) + { + /** + * In this case we have not given this PKEY a name (yet) + * It is either just not in our zone or not even cached + * Since we do not know at this point we will not try to shorten + * because PKEY import will happen if the user follows the zkey + * link. + */ + GNUNET_CRYPTO_short_hash_to_enc ((struct GNUNET_CRYPTO_ShortHashCode*)rd, + &enc); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "No name found for zkey %s returning verbatim!\n", enc); + if (strcmp(rh->name, "") != 0) + GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s.%s", + rh->name, enc, GNUNET_GNS_TLD_ZKEY); + else + GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s", + enc, GNUNET_GNS_TLD_ZKEY); + nsh->proc(nsh->proc_cls, new_name); + GNUNET_free(nsh); + free_resolver_handle(rh); + return; + } + + if (strcmp(rh->name, "") != 0) + GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s", + rh->name, name); + else + strcpy(new_name, name); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Continue shorten for %s!\n", new_name); + + strcpy(rh->name, new_name); + + rh->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain)); + rh->authority_chain_tail = rh->authority_chain_head; + rh->authority_chain_head->zone = rh->authority; + + + /* Start delegation resolution in our namestore */ + resolve_delegation_ns(rh); +} + + +/** + * Shorten api from resolver + * + * @param zone the zone to use + * @param pzone the private local zone + * @param name the name to shorten + * @param key optional private key for background lookups and PSEU import + * @param proc the processor to call with result + * @param proc_cls closure to pass to proc + */ +void +gns_resolver_shorten_name(struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_ShortHashCode pzone, + const char* name, + struct GNUNET_CRYPTO_RsaPrivateKey *key, + ShortenResultProcessor proc, + void* proc_cls) +{ + struct ResolverHandle *rh; + struct NameShortenHandle *nsh; + char string_hash[MAX_DNS_LABEL_LENGTH]; + struct GNUNET_CRYPTO_ShortHashCode zkey; + char nzkey[MAX_DNS_LABEL_LENGTH]; + char* nzkey_ptr = nzkey; + + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting shorten for %s!\n", name); + + if (is_canonical((char*)name)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s is canonical. Returning verbatim\n", name); + proc(proc_cls, name); + return; + } + + nsh = GNUNET_malloc(sizeof (struct NameShortenHandle)); + + nsh->proc = proc; + nsh->proc_cls = proc_cls; + + rh = GNUNET_malloc(sizeof (struct ResolverHandle)); + rh->authority = zone; + rh->id = rid++; + rh->priv_key = key; + rh->proc = &handle_delegation_ns_shorten; + rh->proc_cls = nsh; + rh->id = rid++; + rh->private_local_zone = pzone; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Checking for TLD...\n"); + if (is_zkey_tld(name) == GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "TLD is zkey\n"); + /** + * This is a zkey tld + * build hash and use as initial authority + * FIXME sscanf + */ + memset(rh->name, 0, + strlen(name)-strlen(GNUNET_GNS_TLD_ZKEY)); + memcpy(rh->name, name, + strlen(name)-strlen(GNUNET_GNS_TLD_ZKEY) - 1); + pop_tld(rh->name, string_hash); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "ZKEY is %s!\n", string_hash); + + GNUNET_STRINGS_utf8_toupper(string_hash, &nzkey_ptr); + + if (GNUNET_OK != GNUNET_CRYPTO_short_hash_from_string(nzkey, + &zkey)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Cannot convert ZKEY %s to hash!\n", nzkey); + GNUNET_free(rh); + GNUNET_free(nsh); + proc(proc_cls, name); + return; + } + + GNUNET_NAMESTORE_zone_to_name (namestore_handle, + &zone, //ours + &zkey, + &process_zone_to_name_zkey, + rh); + return; + + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "TLD is gnunet\n"); + /** + * Presumably GNUNET tld + */ + memset(rh->name, 0, + strlen(name)-strlen(GNUNET_GNS_TLD)); + memcpy(rh->name, name, + strlen(name)-strlen(GNUNET_GNS_TLD) - 1); + } + + rh->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain)); + rh->authority_chain_tail = rh->authority_chain_head; + rh->authority_chain_head->zone = zone; + + + /* Start delegation resolution in our namestore */ + resolve_delegation_ns(rh); +} + +/*********** END NAME SHORTEN ********************/ + + +/** + * Process result from namestore delegation lookup + * for get authority operation + * + * @param cls the client get auth handle + * @param rh the resolver handle + * @param rd_count number of results (0) + * @param rd data (NULL) + */ +void +handle_delegation_result_ns_get_auth(void* cls, + struct ResolverHandle *rh, + uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct GetNameAuthorityHandle* nah; + char result[MAX_DNS_NAME_LENGTH]; + size_t answer_len; + + nah = (struct GetNameAuthorityHandle*) rh->proc_cls; + + /** + * At this point rh->name contains the part of the name + * that we do not have a PKEY in our namestore to resolve. + * The authority chain in the resolver handle is now + * useful to backtrack if needed + */ + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "PKEY resolved as far as possible in ns up to %s!\n", rh->name); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Building response!\n"); + if (is_canonical(rh->name)) + { + /** + * We successfully resolved the authority in the ns + * FIXME for our purposes this is fine + * but maybe we want to have an api that also looks + * into the dht (i.e. option in message) + **/ + if (strlen(rh->name) > strlen(nah->name)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Record name longer than original lookup name... odd!\n"); + //FIXME to sth here + } + + answer_len = strlen(nah->name) - strlen(rh->name) + + strlen(GNUNET_GNS_TLD) + 1; + memset(result, 0, answer_len); + strcpy(result, nah->name + strlen(rh->name) + 1); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Got authority result %s\n", result); + + nah->proc(nah->proc_cls, result); + GNUNET_free(nah); + free_resolver_handle(rh); + } + else + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Unable to resolve authority for remaining %s!\n", rh->name); + nah->proc(nah->proc_cls, ""); + GNUNET_free(nah); + free_resolver_handle(rh); + } + + +} + + +/** + * Tries to resolve the authority for name + * in our namestore + * + * @param zone the root zone to look up for + * @param pzone the private local zone + * @param name the name to lookup up + * @param proc the processor to call when finished + * @param proc_cls the closure to pass to the processor + */ +void +gns_resolver_get_authority(struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_ShortHashCode pzone, + const char* name, + GetAuthorityResultProcessor proc, + void* proc_cls) +{ + struct ResolverHandle *rh; + struct GetNameAuthorityHandle *nah; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting authority resolution for %s!\n", name); + + nah = GNUNET_malloc(sizeof (struct GetNameAuthorityHandle)); + rh = GNUNET_malloc(sizeof (struct ResolverHandle)); + rh->authority = zone; + rh->id = rid++; + rh->private_local_zone = pzone; + + if (strcmp(GNUNET_GNS_TLD, name) == 0) + { + strcpy(rh->name, "\0"); + } + else + { + memset(rh->name, 0, + strlen(name)-strlen(GNUNET_GNS_TLD)); + memcpy(rh->name, name, + strlen(name)-strlen(GNUNET_GNS_TLD) - 1); + } + + memset(nah->name, 0, + strlen(name)+1); + strcpy(nah->name, name); + + rh->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain)); + rh->authority_chain_tail = rh->authority_chain_head; + rh->authority_chain_head->zone = zone; + rh->proc = &handle_delegation_result_ns_get_auth; + rh->proc_cls = (void*)nah; + + nah->proc = proc; + nah->proc_cls = proc_cls; + + /* Start delegation resolution in our namestore */ + resolve_delegation_ns(rh); + +} + +/******** END GET AUTHORITY *************/ + +/* end of gnunet-service-gns_resolver.c */ diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h new file mode 100644 index 0000000..8222397 --- /dev/null +++ b/src/gns/gnunet-service-gns_resolver.h @@ -0,0 +1,356 @@ +#ifndef GNS_RESOLVER_H +#define GNS_RESOLVER_H + +#include "gns.h" +#include "gnunet_dht_service.h" + +#define DHT_OPERATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) +#define GNUNET_GNS_DEFAULT_LOOKUP_TIMEOUT \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) +#define DHT_LOOKUP_TIMEOUT DHT_OPERATION_TIMEOUT +#define DHT_GNS_REPLICATION_LEVEL 5 + +#define GNUNET_GNS_MAX_PARALLEL_LOOKUPS 500 + +/* + * DLL to hold the authority chain + * we had to pass in the resolution process + */ +struct AuthorityChain +{ + struct AuthorityChain *prev; + + struct AuthorityChain *next; + + /* the zone hash of the authority */ + struct GNUNET_CRYPTO_ShortHashCode zone; + + /* (local) name of the authority */ + char name[MAX_DNS_LABEL_LENGTH]; + + /* was the ns entry fresh */ + int fresh; +}; + +/* handle to a resolution process */ +struct ResolverHandle; + +/** + * continuation called when cleanup of resolver finishes + */ +typedef void (*ResolverCleanupContinuation) (void); + +/** + * processor for a record lookup result + * + * @param cls the closure + * @param rd_count number of results + * @param rd result data + */ +typedef void (*RecordLookupProcessor) (void *cls, + uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd); + + +/** + * processor for a shorten result + * + * @param cls the closure + * @param name shortened name + */ +typedef void (*ShortenResultProcessor) (void *cls, const char* name); + + +/** + * processor for an authority result + * + * @param cls the closure + * @param name name + */ +typedef void (*GetAuthorityResultProcessor) (void *cls, const char* name); + +/** + * processor for a resolution result + * + * @param cls the closure + * @param rh the resolution handle + * @param rd_count number of results + * @param rd result data + */ +typedef void (*ResolutionResultProcessor) (void *cls, + struct ResolverHandle *rh, + uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd); + + +/** + * Resolution status indicator + * RSL_RECORD_EXISTS: the name to lookup exists + * RSL_RECORD_EXPIRED: the name in the record expired + * RSL_TIMED_OUT: resolution timed out + */ +enum ResolutionStatus +{ + RSL_RECORD_EXISTS = 1, + RSL_RECORD_EXPIRED = 2, + RSL_TIMED_OUT = 4 +}; + +/** + * Handle to a currenty pending resolution + * a ResolverHandle is passed to, for example + * resolve_record_ns to resolve a record in the namestore. + * On result (positive or negative) the ResolutionResultProcessor + * is called. + * If a timeout is set timeout_cont will be called. + * If no timeout is set (ie timeout forever) then background resolutions + * might be triggered. + */ +struct ResolverHandle +{ + /* The name to resolve */ + char name[MAX_DNS_NAME_LENGTH]; + + /* has this query been answered? how many matches */ + int answered; + + /* the authoritative zone to query */ + struct GNUNET_CRYPTO_ShortHashCode authority; + + /* the name of the authoritative zone to query */ + char authority_name[MAX_DNS_LABEL_LENGTH]; + + /* a handle for dht lookups. should be NULL if no lookups are in progress */ + struct GNUNET_DHT_GetHandle *get_handle; + + /* timeout set for this lookup task */ + struct GNUNET_TIME_Relative timeout; + + /* timeout task for the lookup */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + + /* continuation to call on timeout */ + GNUNET_SCHEDULER_Task timeout_cont; + + /* closure for timeout cont */ + void* timeout_cont_cls; + + /* called when resolution phase finishes */ + ResolutionResultProcessor proc; + + /* closure passed to proc */ + void* proc_cls; + + /* DLL to store the authority chain */ + struct AuthorityChain *authority_chain_head; + + /* DLL to store the authority chain */ + struct AuthorityChain *authority_chain_tail; + + /* status of the resolution result */ + enum ResolutionStatus status; + + /* The provate local zone of this request */ + struct GNUNET_CRYPTO_ShortHashCode private_local_zone; + + /** + * private key of an/our authoritative zone + * can be NULL but automatical PKEY import will not work + */ + struct GNUNET_CRYPTO_RsaPrivateKey *priv_key; + + /** + * the heap node associated with this lookup, null if timeout is set + * used for DHT background lookups. + */ + struct GNUNET_CONTAINER_HeapNode *dht_heap_node; + + /** + * Id for resolution process + */ + unsigned long long id; + +}; + + +/** + * Handle to a record lookup + */ +struct RecordLookupHandle +{ + /* the record type to look up */ + enum GNUNET_GNS_RecordType record_type; + + /* the name to look up */ + char name[MAX_DNS_NAME_LENGTH]; + + /* Method to call on record resolution result */ + RecordLookupProcessor proc; + + /* closure to pass to proc */ + void* proc_cls; + +}; + + +/** + * Handle to a shorten context + */ +struct NameShortenHandle +{ + /* Method to call on shorten result */ + ShortenResultProcessor proc; + + /* closure to pass to proc */ + void* proc_cls; +}; + +/** + * Handle to a get authority context + */ +struct GetNameAuthorityHandle +{ + /* the name to look up authority for */ + char name[MAX_DNS_NAME_LENGTH]; + + /* Method to call on result */ + GetAuthorityResultProcessor proc; + + /* closure to pass to proc */ + void* proc_cls; +}; + +/** + * Handle to a pseu lookup + */ +struct GetPseuAuthorityHandle +{ + /* the name given from delegation */ + char name[MAX_DNS_LABEL_LENGTH]; + + /* name to store the pseu under */ + char new_name[MAX_DNS_LABEL_LENGTH]; + + /* the zone of discovered authority */ + struct GNUNET_CRYPTO_ShortHashCode new_zone; + + /* the zone of our authority */ + struct GNUNET_CRYPTO_ShortHashCode zone; + + /* the private key of the zone to store the pseu in */ + struct GNUNET_CRYPTO_RsaPrivateKey *key; + + /* a handle for dht lookups. should be NULL if no lookups are in progress */ + struct GNUNET_DHT_GetHandle *get_handle; + + /* timeout task for lookup */ + GNUNET_SCHEDULER_TaskIdentifier timeout; +}; + +/** + * Initialize the resolver + * MUST be called before other gns_resolver_* methods + * + * @param nh handle to the namestore + * @param dh handle to the dht + * @param lz the local zone + * @param max_bg_queries maximum amount of background queries + * @param ignore_pending ignore records that still require user confirmation + * on lookup + * @returns GNUNET_OK on success + */ +int +gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh, + struct GNUNET_DHT_Handle *dh, + struct GNUNET_CRYPTO_ShortHashCode lz, + unsigned long long max_bg_queries, + int ignore_pending); + +/** + * Cleanup resolver: Terminate pending lookups + * + * @param cont continuation to call when finished + */ +void +gns_resolver_cleanup(ResolverCleanupContinuation cont); + +/** + * Lookup of a record in a specific zone + * calls RecordLookupProcessor on result or timeout + * + * @param zone the root zone + * @param pzone the private local zone + * @param record_type the record type to look up + * @param name the name to look up + * @param key optional private key for authority caching + * @param timeout timeout for the resolution + * @param proc the processor to call + * @param cls the closure to pass to proc + */ +void +gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_ShortHashCode pzone, + uint32_t record_type, + const char* name, + struct GNUNET_CRYPTO_RsaPrivateKey *key, + struct GNUNET_TIME_Relative timeout, + RecordLookupProcessor proc, + void* cls); + +/** + * Shortens a name if possible. If the shortening fails + * name will be returned as shortened string. Else + * a shorter version of the name will be returned. + * There is no guarantee that the shortened name will + * actually be canonical/short etc. + * + * @param zone the zone to perform the operation in + * @param pzone the private local zone + * @param name name to shorten + * @param key optional private key for background lookups and PSEU import + * @param proc the processor to call on shorten result + * @param proc_cls the closure to pass to proc + */ +void +gns_resolver_shorten_name(struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_ShortHashCode pzone, + const char* name, + struct GNUNET_CRYPTO_RsaPrivateKey *key, + ShortenResultProcessor proc, + void* proc_cls); + +/** + * Tries to resolve the authority for name + * in our namestore + * + * @param zone the root zone to look up for + * @param pzone the private local zone + * @param name the name to lookup up + * @param proc the processor to call when finished + * @param proc_cls the closure to pass to the processor + */ +void +gns_resolver_get_authority(struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_ShortHashCode pzone, + const char* name, + GetAuthorityResultProcessor proc, + void* proc_cls); + +/** + * Generic function to check for TLDs + * + * @param name the name to check + * @param tld the tld to check + * @return GNUNET_YES or GNUNET_NO + */ +int +is_tld(const char* name, const char* tld); + +/** + * Checks for gnunet/zkey + */ +#define is_gnunet_tld(name) is_tld(name, GNUNET_GNS_TLD) +#define is_zkey_tld(name) is_tld(name, GNUNET_GNS_TLD_ZKEY) + + +#endif diff --git a/src/gns/namestore_stub_api.c b/src/gns/namestore_stub_api.c deleted file mode 100644 index d067bca..0000000 --- a/src/gns/namestore_stub_api.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2009, 2010 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -/** - * @file gns/namestore_stub_api.c - * @brief stub library to access the NAMESTORE service - * @author Martin Schanzenbach - */ - -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_constants.h" -#include "gnunet_arm_service.h" -#include "gnunet_namestore_service.h" - -#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING - -#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) - -/** - * A QueueEntry. - */ -struct GNUNET_NAMESTORE_QueueEntry -{ - char *data; /*stub data pointer*/ -}; - -/** - * Connection to the NAMESTORE service. - */ -struct GNUNET_NAMESTORE_Handle -{ - - /** - * Configuration to use. - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Socket (if available). - */ - struct GNUNET_CLIENT_Connection *client; - - /** - * Currently pending transmission request (or NULL). - */ - struct GNUNET_CLIENT_TransmitHandle *th; - - /* dll to use for records */ - struct GNUNET_NAMESTORE_SimpleRecord * records_head; - struct GNUNET_NAMESTORE_SimpleRecord * records_tail; - - uint32_t locked; - -}; - -struct GNUNET_NAMESTORE_ZoneIterator -{ - struct GNUNET_NAMESTORE_Handle *handle; - GNUNET_NAMESTORE_RecordProcessor proc; - void* proc_cls; - const GNUNET_HashCode * zone; - uint32_t no_flags; - uint32_t flags; - struct GNUNET_NAMESTORE_Handle *h; - struct GNUNET_NAMESTORE_SimpleRecord *sr; -}; - -struct GNUNET_NAMESTORE_SimpleRecord -{ - /** - * DLL - */ - struct GNUNET_NAMESTORE_SimpleRecord *next; - - /** - * DLL - */ - struct GNUNET_NAMESTORE_SimpleRecord *prev; - - const char *name; - const GNUNET_HashCode *zone; - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; - uint32_t rd_count; - struct GNUNET_NAMESTORE_RecordData rd[100]; -}; - - -/** - * Initialize the connection with the NAMESTORE service. - * - * @param cfg configuration to use - * @return handle to the GNS service, or NULL on error - */ -struct GNUNET_NAMESTORE_Handle * -GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct GNUNET_NAMESTORE_Handle *handle; - - handle = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle)); - handle->cfg = cfg; - handle->records_head = NULL; - handle->records_tail = NULL; - return handle; -} - -/** - * Shutdown connection with the NAMESTORE service. - * - * @param handle handle of the NAMESTORE connection to stop - */ -void -GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *handle, int drop) -{ - GNUNET_free(handle); -} - -/** - * Store an item in the namestore. If the item is already present, - * the expiration time is updated to the max of the existing time and - * the new time. The operation must fail if there is no matching - * entry in the signature tree. - * - * @param h handle to the namestore - * @param zone hash of the public key of the zone - * @param name name that is being mapped (at most 255 characters long) - * @param record_type type of the record (A, AAAA, PKEY, etc.) - * @param expiration expiration time for the content - * @param flags flags for the content - * @param data_size number of bytes in data - * @param data value, semantics depend on 'record_type' (see RFCs for DNS and - * GNS specification for GNS extensions) - * @param cont continuation to call when done - * @param cont_cls closure for cont - * @return handle to abort the request - */ -struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key, - const char *name, - struct GNUNET_TIME_Absolute expiration, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature, - GNUNET_NAMESTORE_ContinuationWithStatus cont, - void *cont_cls) -{ - struct GNUNET_NAMESTORE_QueueEntry *qe; - qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); - struct GNUNET_NAMESTORE_SimpleRecord* sr; - GNUNET_HashCode *zone; - int i; - - zone = GNUNET_malloc(sizeof(GNUNET_HashCode)); - GNUNET_CRYPTO_hash(public_key, - sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - zone); - - sr = h->records_head; - for (; sr != NULL; sr = sr->next) - { - if (GNUNET_CRYPTO_hash_cmp(zone, sr->zone) == 0) - { - sr->rd_count = rd_count; - for (i=0; ird[i] = rd[i]; - } - //Expiration, Signature etc - return qe; - } - } - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "new records for %s\n", name); - // Not present - sr = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_SimpleRecord)); - sr->rd_count = rd_count; - sr->name = GNUNET_malloc(strlen(name)); - sr->zone = zone; - sr->zone_key = public_key; //pkey FIXME; - sr->next = NULL; - sr->prev = NULL; - strcpy((char*)sr->name, name); - - for (i=0; ird[i] = rd[i]; - - if (h->records_head == NULL && h->records_tail == NULL) - { - h->records_head = sr; - h->records_tail = sr; - } - else - { - GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr); - } - - return qe; -} - -int -GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key, - const char *name, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) -{ - return GNUNET_OK; -} - -struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_RsaPrivateKey *key, - const char *name, - const struct GNUNET_NAMESTORE_RecordData *rd, - GNUNET_NAMESTORE_ContinuationWithStatus cont, - void *cont_cls) -{ - struct GNUNET_NAMESTORE_QueueEntry *qe; - qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); - struct GNUNET_NAMESTORE_SimpleRecord* sr; - - GNUNET_HashCode *zone_hash; - - //memleakage.. but only stub so w/e - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey; - pkey = GNUNET_malloc(sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); - GNUNET_CRYPTO_rsa_key_get_public (key, pkey); - - zone_hash = GNUNET_malloc(sizeof(GNUNET_HashCode)); - - GNUNET_CRYPTO_hash(pkey, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - zone_hash); - - sr = h->records_head; - for (; sr != NULL; sr = sr->next) - { - if ((strcmp(sr->name, name) == 0) && - (0 == GNUNET_CRYPTO_hash_cmp(sr->zone, zone_hash))) - { - //Dangerous - memcpy (&(sr->rd[sr->rd_count-1]), rd, - sizeof(struct GNUNET_NAMESTORE_RecordData)); - - sr->rd_count++; - return qe; - } - } - - sr = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_SimpleRecord)); - - sr->rd_count = 1; - sr->name = GNUNET_malloc(strlen(name)); - sr->zone = zone_hash; - sr->zone_key = pkey; - sr->next = NULL; - sr->prev = NULL; - strcpy((char*)sr->name, name); - - memcpy (&(sr->rd), rd, - sizeof(struct GNUNET_NAMESTORE_RecordData)); - if (h->records_head == NULL && h->records_tail == NULL) - { - h->records_head = sr; - h->records_tail = sr; - } - else - { - GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr); - } - - return qe; -} - -/** - * Explicitly remove some content from the database. The - * "cont"inuation will be called with status "GNUNET_OK" if content - * was removed, "GNUNET_NO" if no matching entry was found and - * "GNUNET_SYSERR" on all other types of errors. - * - * @param h handle to the namestore - * @param zone hash of the public key of the zone - * @param name name that is being mapped (at most 255 characters long) - * @param record_type type of the record (A, AAAA, PKEY, etc.) - * @param size number of bytes in data - * @param data content stored - * @param cont continuation to call when done - * @param cont_cls closure for cont - * @return handle to abort the request - */ -struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_RsaPrivateKey *pkey, - const char *name, - const struct GNUNET_NAMESTORE_RecordData *rd, - GNUNET_NAMESTORE_ContinuationWithStatus cont, - void *cont_cls) -{ - struct GNUNET_NAMESTORE_QueueEntry *qe; - qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); - - //FIXME - return qe; -} - -/** - * Get a result for a particular key from the namestore. The processor - * will only be called once. - * - * @param h handle to the namestore - * @param zone zone to look up a record from - * @param name name to look up - * @param record_type desired record type - * @param proc function to call on each matching value; - * will be called once with a NULL value at the end - * @param proc_cls closure for proc - * @return a handle that can be used to - * cancel - */ -struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, - const GNUNET_HashCode *zone, - const char *name, - uint32_t record_type, - GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls) -{ - struct GNUNET_NAMESTORE_QueueEntry *qe; - qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); - struct GNUNET_NAMESTORE_SimpleRecord *sr; - struct GNUNET_CRYPTO_HashAsciiEncoded zone_string, zone_string_ex; - - GNUNET_CRYPTO_hash_to_enc (zone, &zone_string); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Looking up %s in %s\n", name, (char*)&zone_string); - sr = h->records_head; - for (; sr != NULL; sr = sr->next) - { - GNUNET_CRYPTO_hash_to_enc (sr->zone, &zone_string_ex); - if ((strcmp(sr->name, name) == 0) && - (0 == (GNUNET_CRYPTO_hash_cmp(sr->zone, zone)))) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Found match for %s in %s with %d entries\n", - sr->name, (char*)&zone_string_ex, sr->rd_count); - //Simply always return all records - proc(proc_cls, sr->zone_key, GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME - name, sr->rd_count, sr->rd, NULL); - return qe; - } - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "No match\n"); - } - proc(proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, name, 0, NULL, NULL); - //FIXME - return qe; -} - -struct GNUNET_NAMESTORE_ZoneIterator * -GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h, - const GNUNET_HashCode *zone, - enum GNUNET_NAMESTORE_RecordFlags must_have_flags, - enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags, - GNUNET_NAMESTORE_RecordProcessor proc, - void *proc_cls) -{ - struct GNUNET_NAMESTORE_ZoneIterator *it; - h->locked = 1; - it = GNUNET_malloc(sizeof(struct GNUNET_NAMESTORE_ZoneIterator)); - it->h = h; - it->sr = h->records_head; - it->proc = proc; - it->proc_cls = proc_cls; - it->zone = zone; - it->no_flags = must_not_have_flags; - it->flags = must_have_flags; - GNUNET_NAMESTORE_zone_iterator_next(it); - return it; -} - -void -GNUNET_NAMESTORE_zone_iterator_next(struct GNUNET_NAMESTORE_ZoneIterator *it) -{ - - if (it->h->locked == 0) - return; - if (it->sr == NULL) - { - it->proc(it->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, - NULL, 0, NULL, NULL); - return; - } - if (GNUNET_CRYPTO_hash_cmp(it->sr->zone, it->zone) == 0) - { - //Simply always return all records - //check flags - it->proc(it->proc_cls, it->sr->zone_key, GNUNET_TIME_UNIT_FOREVER_ABS, - it->sr->name, it->sr->rd_count, it->sr->rd, NULL); - } - it->sr = it->sr->next; -} - -void -GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it) -{ - //it->h->locked = 0; -} - -/** - * Cancel a namestore operation. The final callback from the - * operation must not have been done yet. - * - * @param qe operation to cancel - */ -void -GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe) -{ - if (qe) - GNUNET_free(qe); -} - - - - -/* end of namestore_stub_api.c */ diff --git a/src/gns/nss/Makefile.am b/src/gns/nss/Makefile.am new file mode 100644 index 0000000..5e8ab5a --- /dev/null +++ b/src/gns/nss/Makefile.am @@ -0,0 +1,59 @@ +# $Id$ +# +# This file taken and modified from nss-gns. +# +# nss-gns is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# nss-gns is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with nss-gns; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. + +EXTRA_DIST = map-file + +AM_LDFLAGS=-avoid-version -module -export-dynamic + +if HAVE_SUDO +nssdir = /lib/ +else +nssdir = $(libdir) +endif + +LIBTOOL = $(SUDO_BINARY) $(SHELL) $(top_builddir)/libtool + +if !MINGW +nss_LTLIBRARIES = \ + libnss_gns.la \ + libnss_gns4.la \ + libnss_gns6.la +endif + +sources = nss_gns_query.h nss_gns_query.c + +# GNU Libc +libnss_gns_la_SOURCES= $(sources) nss_gns.c +libnss_gns_la_CFLAGS=$(AM_CFLAGS) -D_GNU_SOURCE +libnss_gns_la_LDFLAGS=$(AM_LDFLAGS) -shrext .so.2 -Wl,-version-script=$(srcdir)/map-file + +libnss_gns4_la_SOURCES=$(libnss_gns_la_SOURCES) +libnss_gns4_la_CFLAGS=$(libnss_gns_la_CFLAGS) -DNSS_IPV4_ONLY=1 +libnss_gns4_la_LDFLAGS=$(libnss_gns_la_LDFLAGS) + +libnss_gns6_la_SOURCES=$(libnss_gns_la_SOURCES) +libnss_gns6_la_CFLAGS=$(libnss_gns_la_CFLAGS) -DNSS_IPV6_ONLY=1 +libnss_gns6_la_LDFLAGS=$(libnss_gns_la_LDFLAGS) + +install-data-hook: + $(SUDO_BINARY) $(SHELL) $(top_builddir)/libtool --finish $(nssdir) + $(SUDO_BINARY) rm -f $(nssdir)/libnss_gns.la $(nssdir)/libnss_gns4.la $(nssdir)/libnss_gns6.la + +uninstall-hook: + $(SUDO_BINARY) rm -f $(nssdir)/libnss_gns.so.2 $(nssdir)/libnss_gns4.so.2 $(nssdir)/libnss_gns6.so.2 diff --git a/src/gns/nss/Makefile.in b/src/gns/nss/Makefile.in new file mode 100644 index 0000000..6b3b3df --- /dev/null +++ b/src/gns/nss/Makefile.in @@ -0,0 +1,769 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# $Id$ +# +# This file taken and modified from nss-gns. +# +# nss-gns is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# nss-gns is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with nss-gns; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/gns/nss +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ + $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ + $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/gnunet_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(nssdir)" +LTLIBRARIES = $(nss_LTLIBRARIES) +libnss_gns_la_LIBADD = +am__objects_1 = libnss_gns_la-nss_gns_query.lo +am_libnss_gns_la_OBJECTS = $(am__objects_1) libnss_gns_la-nss_gns.lo +libnss_gns_la_OBJECTS = $(am_libnss_gns_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libnss_gns_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libnss_gns_la_CFLAGS) \ + $(CFLAGS) $(libnss_gns_la_LDFLAGS) $(LDFLAGS) -o $@ +@MINGW_FALSE@am_libnss_gns_la_rpath = -rpath $(nssdir) +libnss_gns4_la_LIBADD = +am__objects_2 = libnss_gns4_la-nss_gns_query.lo +am__objects_3 = $(am__objects_2) libnss_gns4_la-nss_gns.lo +am_libnss_gns4_la_OBJECTS = $(am__objects_3) +libnss_gns4_la_OBJECTS = $(am_libnss_gns4_la_OBJECTS) +libnss_gns4_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libnss_gns4_la_CFLAGS) $(CFLAGS) $(libnss_gns4_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MINGW_FALSE@am_libnss_gns4_la_rpath = -rpath $(nssdir) +libnss_gns6_la_LIBADD = +am__objects_4 = libnss_gns6_la-nss_gns_query.lo +am__objects_5 = $(am__objects_4) libnss_gns6_la-nss_gns.lo +am_libnss_gns6_la_OBJECTS = $(am__objects_5) +libnss_gns6_la_OBJECTS = $(am_libnss_gns6_la_OBJECTS) +libnss_gns6_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libnss_gns6_la_CFLAGS) $(CFLAGS) $(libnss_gns6_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MINGW_FALSE@am_libnss_gns6_la_rpath = -rpath $(nssdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libnss_gns_la_SOURCES) $(libnss_gns4_la_SOURCES) \ + $(libnss_gns6_la_SOURCES) +DIST_SOURCES = $(libnss_gns_la_SOURCES) $(libnss_gns4_la_SOURCES) \ + $(libnss_gns6_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_INTERFACE = @DEFAULT_INTERFACE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLDIR = @DLLDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXT_LIBS = @EXT_LIBS@ +EXT_LIB_PATH = @EXT_LIB_PATH@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ +GN_DAEMON_CONFIG_DIR = @GN_DAEMON_CONFIG_DIR@ +GN_DAEMON_HOME_DIR = @GN_DAEMON_HOME_DIR@ +GN_INTLINCL = @GN_INTLINCL@ +GN_LIBINTL = @GN_LIBINTL@ +GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ +GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ +GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GREP = @GREP@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBPREFIX = @LIBPREFIX@ +LIBS = @LIBS@ +LIBTOOL = $(SUDO_BINARY) $(SHELL) $(top_builddir)/libtool +LIBUNISTRING = @LIBUNISTRING@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ +POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CPPFLAGS = @SQLITE_CPPFLAGS@ +SQLITE_LDFLAGS = @SQLITE_LDFLAGS@ +STRIP = @STRIP@ +SUDO_BINARY = @SUDO_BINARY@ +UNIXONLY = @UNIXONLY@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_OBJC = @ac_ct_OBJC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_target = @build_target@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = map-file +AM_LDFLAGS = -avoid-version -module -export-dynamic +@HAVE_SUDO_FALSE@nssdir = $(libdir) +@HAVE_SUDO_TRUE@nssdir = /lib/ +@MINGW_FALSE@nss_LTLIBRARIES = \ +@MINGW_FALSE@ libnss_gns.la \ +@MINGW_FALSE@ libnss_gns4.la \ +@MINGW_FALSE@ libnss_gns6.la + +sources = nss_gns_query.h nss_gns_query.c + +# GNU Libc +libnss_gns_la_SOURCES = $(sources) nss_gns.c +libnss_gns_la_CFLAGS = $(AM_CFLAGS) -D_GNU_SOURCE +libnss_gns_la_LDFLAGS = $(AM_LDFLAGS) -shrext .so.2 -Wl,-version-script=$(srcdir)/map-file +libnss_gns4_la_SOURCES = $(libnss_gns_la_SOURCES) +libnss_gns4_la_CFLAGS = $(libnss_gns_la_CFLAGS) -DNSS_IPV4_ONLY=1 +libnss_gns4_la_LDFLAGS = $(libnss_gns_la_LDFLAGS) +libnss_gns6_la_SOURCES = $(libnss_gns_la_SOURCES) +libnss_gns6_la_CFLAGS = $(libnss_gns_la_CFLAGS) -DNSS_IPV6_ONLY=1 +libnss_gns6_la_LDFLAGS = $(libnss_gns_la_LDFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/gns/nss/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/gns/nss/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-nssLTLIBRARIES: $(nss_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(nssdir)" || $(MKDIR_P) "$(DESTDIR)$(nssdir)" + @list='$(nss_LTLIBRARIES)'; test -n "$(nssdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(nssdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(nssdir)"; \ + } + +uninstall-nssLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(nss_LTLIBRARIES)'; test -n "$(nssdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(nssdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(nssdir)/$$f"; \ + done + +clean-nssLTLIBRARIES: + -test -z "$(nss_LTLIBRARIES)" || rm -f $(nss_LTLIBRARIES) + @list='$(nss_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libnss_gns.la: $(libnss_gns_la_OBJECTS) $(libnss_gns_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnss_gns_la_LINK) $(am_libnss_gns_la_rpath) $(libnss_gns_la_OBJECTS) $(libnss_gns_la_LIBADD) $(LIBS) +libnss_gns4.la: $(libnss_gns4_la_OBJECTS) $(libnss_gns4_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnss_gns4_la_LINK) $(am_libnss_gns4_la_rpath) $(libnss_gns4_la_OBJECTS) $(libnss_gns4_la_LIBADD) $(LIBS) +libnss_gns6.la: $(libnss_gns6_la_OBJECTS) $(libnss_gns6_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnss_gns6_la_LINK) $(am_libnss_gns6_la_rpath) $(libnss_gns6_la_OBJECTS) $(libnss_gns6_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnss_gns4_la-nss_gns.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnss_gns4_la-nss_gns_query.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnss_gns6_la-nss_gns.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnss_gns6_la-nss_gns_query.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnss_gns_la-nss_gns.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnss_gns_la-nss_gns_query.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libnss_gns_la-nss_gns_query.lo: nss_gns_query.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns_la_CFLAGS) $(CFLAGS) -MT libnss_gns_la-nss_gns_query.lo -MD -MP -MF $(DEPDIR)/libnss_gns_la-nss_gns_query.Tpo -c -o libnss_gns_la-nss_gns_query.lo `test -f 'nss_gns_query.c' || echo '$(srcdir)/'`nss_gns_query.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnss_gns_la-nss_gns_query.Tpo $(DEPDIR)/libnss_gns_la-nss_gns_query.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nss_gns_query.c' object='libnss_gns_la-nss_gns_query.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns_la_CFLAGS) $(CFLAGS) -c -o libnss_gns_la-nss_gns_query.lo `test -f 'nss_gns_query.c' || echo '$(srcdir)/'`nss_gns_query.c + +libnss_gns_la-nss_gns.lo: nss_gns.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns_la_CFLAGS) $(CFLAGS) -MT libnss_gns_la-nss_gns.lo -MD -MP -MF $(DEPDIR)/libnss_gns_la-nss_gns.Tpo -c -o libnss_gns_la-nss_gns.lo `test -f 'nss_gns.c' || echo '$(srcdir)/'`nss_gns.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnss_gns_la-nss_gns.Tpo $(DEPDIR)/libnss_gns_la-nss_gns.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nss_gns.c' object='libnss_gns_la-nss_gns.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns_la_CFLAGS) $(CFLAGS) -c -o libnss_gns_la-nss_gns.lo `test -f 'nss_gns.c' || echo '$(srcdir)/'`nss_gns.c + +libnss_gns4_la-nss_gns_query.lo: nss_gns_query.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns4_la_CFLAGS) $(CFLAGS) -MT libnss_gns4_la-nss_gns_query.lo -MD -MP -MF $(DEPDIR)/libnss_gns4_la-nss_gns_query.Tpo -c -o libnss_gns4_la-nss_gns_query.lo `test -f 'nss_gns_query.c' || echo '$(srcdir)/'`nss_gns_query.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnss_gns4_la-nss_gns_query.Tpo $(DEPDIR)/libnss_gns4_la-nss_gns_query.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nss_gns_query.c' object='libnss_gns4_la-nss_gns_query.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns4_la_CFLAGS) $(CFLAGS) -c -o libnss_gns4_la-nss_gns_query.lo `test -f 'nss_gns_query.c' || echo '$(srcdir)/'`nss_gns_query.c + +libnss_gns4_la-nss_gns.lo: nss_gns.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns4_la_CFLAGS) $(CFLAGS) -MT libnss_gns4_la-nss_gns.lo -MD -MP -MF $(DEPDIR)/libnss_gns4_la-nss_gns.Tpo -c -o libnss_gns4_la-nss_gns.lo `test -f 'nss_gns.c' || echo '$(srcdir)/'`nss_gns.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnss_gns4_la-nss_gns.Tpo $(DEPDIR)/libnss_gns4_la-nss_gns.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nss_gns.c' object='libnss_gns4_la-nss_gns.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns4_la_CFLAGS) $(CFLAGS) -c -o libnss_gns4_la-nss_gns.lo `test -f 'nss_gns.c' || echo '$(srcdir)/'`nss_gns.c + +libnss_gns6_la-nss_gns_query.lo: nss_gns_query.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns6_la_CFLAGS) $(CFLAGS) -MT libnss_gns6_la-nss_gns_query.lo -MD -MP -MF $(DEPDIR)/libnss_gns6_la-nss_gns_query.Tpo -c -o libnss_gns6_la-nss_gns_query.lo `test -f 'nss_gns_query.c' || echo '$(srcdir)/'`nss_gns_query.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnss_gns6_la-nss_gns_query.Tpo $(DEPDIR)/libnss_gns6_la-nss_gns_query.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nss_gns_query.c' object='libnss_gns6_la-nss_gns_query.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns6_la_CFLAGS) $(CFLAGS) -c -o libnss_gns6_la-nss_gns_query.lo `test -f 'nss_gns_query.c' || echo '$(srcdir)/'`nss_gns_query.c + +libnss_gns6_la-nss_gns.lo: nss_gns.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns6_la_CFLAGS) $(CFLAGS) -MT libnss_gns6_la-nss_gns.lo -MD -MP -MF $(DEPDIR)/libnss_gns6_la-nss_gns.Tpo -c -o libnss_gns6_la-nss_gns.lo `test -f 'nss_gns.c' || echo '$(srcdir)/'`nss_gns.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnss_gns6_la-nss_gns.Tpo $(DEPDIR)/libnss_gns6_la-nss_gns.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nss_gns.c' object='libnss_gns6_la-nss_gns.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnss_gns6_la_CFLAGS) $(CFLAGS) -c -o libnss_gns6_la-nss_gns.lo `test -f 'nss_gns.c' || echo '$(srcdir)/'`nss_gns.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(nssdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-nssLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-nssLTLIBRARIES + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-nssLTLIBRARIES + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: install-am install-data-am install-strip uninstall-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-nssLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-hook install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-nssLTLIBRARIES install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-hook \ + uninstall-nssLTLIBRARIES + + +install-data-hook: + $(SUDO_BINARY) $(SHELL) $(top_builddir)/libtool --finish $(nssdir) + $(SUDO_BINARY) rm -f $(nssdir)/libnss_gns.la $(nssdir)/libnss_gns4.la $(nssdir)/libnss_gns6.la + +uninstall-hook: + $(SUDO_BINARY) rm -f $(nssdir)/libnss_gns.so.2 $(nssdir)/libnss_gns4.so.2 $(nssdir)/libnss_gns6.so.2 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/gns/nss/map-file b/src/gns/nss/map-file new file mode 100644 index 0000000..476d0ac --- /dev/null +++ b/src/gns/nss/map-file @@ -0,0 +1,14 @@ +NSSGNS_0 { +global: +_nss_gns_gethostbyaddr_r; +_nss_gns4_gethostbyaddr_r; +_nss_gns6_gethostbyaddr_r; +_nss_gns_gethostbyname_r; +_nss_gns4_gethostbyname_r; +_nss_gns6_gethostbyname_r; +_nss_gns_gethostbyname2_r; +_nss_gns4_gethostbyname2_r; +_nss_gns6_gethostbyname2_r; +local: +*; +}; diff --git a/src/gns/nss/nss_gns.c b/src/gns/nss/nss_gns.c new file mode 100644 index 0000000..3bb45a1 --- /dev/null +++ b/src/gns/nss/nss_gns.c @@ -0,0 +1,264 @@ +/*** + This file is part of nss-gns. + + Parts taken from: nss.c in nss-mdns + + nss-mdns is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + nss-mdns is distributed in the hope that it will be useful, but1 + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with nss-mdns; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nss_gns_query.h" + +#include + +/** macro to align idx to 32bit boundary */ +#define ALIGN(idx) do { \ + if (idx % sizeof(void*)) \ + idx += (sizeof(void*) - idx % sizeof(void*)); /* Align on 32 bit boundary */ \ +} while(0) + + +/** + * function to check if name ends with a specific suffix + * + * @param name the name to check + * @param suffix the suffix to check for + * @return 1 if true + */ +static int ends_with(const char *name, const char* suffix) { + size_t ln, ls; + assert(name); + assert(suffix); + + if ((ls = strlen(suffix)) > (ln = strlen(name))) + return 0; + + return strcasecmp(name+ln-ls, suffix) == 0; +} + + +/** + * Check if name is inside .gnunet or .zkey TLD + * + * @param name name to check + * @return 1 if true + */ +static int verify_name_allowed(const char *name) { + return ends_with(name, ".gnunet") || ends_with(name, ".zkey"); +} + +/** + * The gethostbyname hook executed by nsswitch + * + * @param name the name to resolve + * @param af the address family to resolve + * @param result the result hostent + * @param buffer the result buffer + * @param buflen length of the buffer + * @param errnop idk + * @param h_errnop idk + * @return a nss_status code + */ +enum nss_status _nss_gns_gethostbyname2_r( + const char *name, + int af, + struct hostent * result, + char *buffer, + size_t buflen, + int *errnop, + int *h_errnop) { + + struct userdata u; + enum nss_status status = NSS_STATUS_UNAVAIL; + int i; + size_t address_length, l, idx, astart; + int name_allowed; + + if (af == AF_UNSPEC) +#ifdef NSS_IPV6_ONLY + af = AF_INET6; +#else + af = AF_INET; +#endif + +#ifdef NSS_IPV4_ONLY + if (af != AF_INET) +#elif NSS_IPV6_ONLY + if (af != AF_INET6) +#else + if (af != AF_INET && af != AF_INET6) +#endif + { + *errnop = EINVAL; + *h_errnop = NO_RECOVERY; + + goto finish; + } + + address_length = af == AF_INET ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t); + if (buflen < + sizeof(char*)+ /* alias names */ + strlen(name)+1) { /* official name */ + + *errnop = ERANGE; + *h_errnop = NO_RECOVERY; + status = NSS_STATUS_TRYAGAIN; + + goto finish; + } + + u.count = 0; + u.data_len = 0; + + name_allowed = verify_name_allowed(name); + + if (name_allowed) { + + if (!gns_resolve_name(af, name, &u) == 0) + { + status = NSS_STATUS_NOTFOUND; + } + } + + if (u.count == 0) { + *errnop = ETIMEDOUT; + *h_errnop = HOST_NOT_FOUND; + printf("not found\n"); + goto finish; + } + + + /* Alias names */ + *((char**) buffer) = NULL; + result->h_aliases = (char**) buffer; + idx = sizeof(char*); + + /* Official name */ + strcpy(buffer+idx, name); + result->h_name = buffer+idx; + idx += strlen(name)+1; + + ALIGN(idx); + + result->h_addrtype = af; + result->h_length = address_length; + + /* Check if there's enough space for the addresses */ + if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1)) { + *errnop = ERANGE; + *h_errnop = NO_RECOVERY; + status = NSS_STATUS_TRYAGAIN; + goto finish; + } + + /* Addresses */ + astart = idx; + l = u.count*address_length; + memcpy(buffer+astart, &u.data, l); + /* address_length is a multiple of 32bits, so idx is still aligned + * correctly */ + idx += l; + + /* Address array address_lenght is always a multiple of 32bits */ + for (i = 0; i < u.count; i++) + ((char**) (buffer+idx))[i] = buffer+astart+address_length*i; + ((char**) (buffer+idx))[i] = NULL; + result->h_addr_list = (char**) (buffer+idx); + + status = NSS_STATUS_SUCCESS; + +finish: + return status; +} + +/** + * The gethostbyname hook executed by nsswitch + * + * @param name the name to resolve + * @param result the result hostent + * @param buffer the result buffer + * @param buflen length of the buffer + * @param errnop idk + * @param h_errnop idk + * @return a nss_status code + */ +enum nss_status _nss_gns_gethostbyname_r ( + const char *name, + struct hostent *result, + char *buffer, + size_t buflen, + int *errnop, + int *h_errnop) { + + return _nss_gns_gethostbyname2_r( + name, + AF_UNSPEC, + result, + buffer, + buflen, + errnop, + h_errnop); +} + +/** + * The gethostbyaddr hook executed by nsswitch + * We can't do this so we always return NSS_STATUS_UNAVAIL + * + * @param addr the address to resolve + * @param len the length of the address + * @param af the address family of the address + * @param result the result hostent + * @param buffer the result buffer + * @param buflen length of the buffer + * @param errnop idk + * @param h_errnop idk + * @return NSS_STATUS_UNAVAIL + */ +enum nss_status _nss_gns_gethostbyaddr_r( + const void* addr, + int len, + int af, + struct hostent *result, + char *buffer, + size_t buflen, + int *errnop, + int *h_errnop) { + + /* we dont do this */ + + enum nss_status status = NSS_STATUS_UNAVAIL; + + *errnop = EINVAL; + *h_errnop = NO_RECOVERY; + + /* Check for address types */ + + *h_errnop = NO_RECOVERY; + + status = NSS_STATUS_NOTFOUND; + return status; +} + diff --git a/src/gns/nss/nss_gns_query.c b/src/gns/nss/nss_gns_query.c new file mode 100644 index 0000000..ab88d22 --- /dev/null +++ b/src/gns/nss/nss_gns_query.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include "nss_gns_query.h" +#include + + +/** + * Wrapper function that uses gnunet-gns cli tool to resolve + * an IPv4/6 address. + * + * @param af address family + * @param name the name to resolve + * @param u the userdata (result struct) + * @return -1 on error else 0 + */ +int gns_resolve_name(int af, const char *name, struct userdata *u) +{ + FILE *p; + char *cmd; + char line[128]; + + if (af == AF_INET6) + { + if (-1 == asprintf(&cmd, "%s -t AAAA -u %s\n", "gnunet-gns -r", name)) + return -1; + } + else + { + if (-1 == asprintf(&cmd, "%s %s\n", "gnunet-gns -r -u", name)) + return -1; + } + + p = popen(cmd,"r"); + + if (p != NULL ) + { + while (fgets( line, sizeof(line), p ) != NULL) + { + + if (u->count >= MAX_ENTRIES) + break; + + if (line[strlen(line)-1] == '\n') + { + line[strlen(line)-1] = '\0'; + if (af == AF_INET) + { + inet_pton(af, line, &(u->data.ipv4[u->count++])); + u->data_len += sizeof(ipv4_address_t); + } + else if ((af == AF_INET6)) + { + inet_pton(af, line, &(u->data.ipv6[u->count++])); + u->data_len += sizeof(ipv6_address_t); + } + } + } + } + fclose(p); + free(cmd); + + return 0; + +} diff --git a/src/gns/nss/nss_gns_query.h b/src/gns/nss/nss_gns_query.h new file mode 100644 index 0000000..0b4dae5 --- /dev/null +++ b/src/gns/nss/nss_gns_query.h @@ -0,0 +1,66 @@ +#ifndef NSS_GNS_QUERY_H +#define NSS_GNS_QUERY_H + +/** + * Parts taken from nss-mdns. Original license statement follows + */ + +/* $Id$ */ + +/*** + This file is part of nss-mdns. + + nss-mdns is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + nss-mdns is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with nss-mdns; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include + +/* Maximum number of entries to return */ +#define MAX_ENTRIES 16 + +typedef struct { + uint32_t address; +} ipv4_address_t; + +typedef struct { + uint8_t address[16]; +} ipv6_address_t; + + +struct userdata { + int count; + int data_len; /* only valid when doing reverse lookup */ + union { + ipv4_address_t ipv4[MAX_ENTRIES]; + ipv6_address_t ipv6[MAX_ENTRIES]; + char *name[MAX_ENTRIES]; + } data; +}; + +/** + * Wrapper function that uses gnunet-gns cli tool to resolve + * an IPv4/6 address. + * + * @param af address family + * @param name the name to resolve + * @param u the userdata (result struct) + * @return -1 on error else 0 + */ +int gns_resolve_name(int af, + const char *name, + struct userdata *userdata); + +#endif diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c index a4d6ad9..5d986ce 100644 --- a/src/gns/plugin_block_gns.c +++ b/src/gns/plugin_block_gns.c @@ -62,86 +62,135 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, size_t xquery_size, const void *reply_block, size_t reply_block_size) { - if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) - return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; - if (reply_block_size == 0) - return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - char* name; - GNUNET_HashCode pkey_hash; + GNUNET_HashCode pkey_hash_double; GNUNET_HashCode query_key; - GNUNET_HashCode name_hash; + GNUNET_HashCode name_hash_double; GNUNET_HashCode mhash; GNUNET_HashCode chash; + struct GNUNET_CRYPTO_ShortHashCode pkey_hash; + struct GNUNET_CRYPTO_ShortHashCode name_hash; struct GNSNameRecordBlock *nrb; - struct GNSRecordBlock *rb; uint32_t rd_count; + char* rd_data = NULL; + int rd_len; + uint32_t record_xquery; + unsigned int record_match; + //GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "RB SIZE %d\n", reply_block_size); + + if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) + return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; + if (reply_block == NULL) + { + /** + * check if request is valid + * FIXME we could check for the record types here + **/ + if (xquery_size < sizeof(uint32_t)) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; + } + return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; + } + + /* this is a reply */ + nrb = (struct GNSNameRecordBlock *)reply_block; name = (char*)&nrb[1]; - GNUNET_CRYPTO_hash(&nrb->public_key, + GNUNET_CRYPTO_short_hash(&nrb->public_key, sizeof(nrb->public_key), &pkey_hash); - GNUNET_CRYPTO_hash(name, strlen(name), &name_hash); + GNUNET_CRYPTO_short_hash(name, strlen(name), &name_hash); + + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_short_hash_double(&pkey_hash, &pkey_hash_double); - GNUNET_CRYPTO_hash_xor(&pkey_hash, &name_hash, &query_key); + GNUNET_CRYPTO_hash_xor(&pkey_hash_double, &name_hash_double, &query_key); + struct GNUNET_CRYPTO_HashAsciiEncoded xor_exp; + struct GNUNET_CRYPTO_HashAsciiEncoded xor_got; + GNUNET_CRYPTO_hash_to_enc (&query_key, &xor_exp); + GNUNET_CRYPTO_hash_to_enc (query, &xor_got); + + //GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + // "BLOCK_TEST for %s got %s expected %s\n", + // name, (char*) &xor_got, (char*) &xor_exp); + /* Check query key against public key */ if (0 != GNUNET_CRYPTO_hash_cmp(query, &query_key)) - return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; + { + GNUNET_break_op (0); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + record_match = 0; rd_count = ntohl(nrb->rd_count); - - struct GNUNET_NAMESTORE_RecordData rd[rd_count]; - int i = 0; - int record_match = 0; - uint32_t record_xquery = ntohl(*((uint32_t*)xquery)); - rb = (struct GNSRecordBlock*)(&name[strlen(name) + 1]); - - for (i=0; itype); - rd[i].expiration = - GNUNET_TIME_absolute_ntoh(rb->expiration); - rd[i].data_size = ntohl(rb->data_length); - rd[i].flags = ntohl(rb->flags); - rd[i].data = (char*)&rb[1]; - rb = (struct GNSRecordBlock *)((char*)&rb[1] + rd[i].data_size); + struct GNUNET_NAMESTORE_RecordData rd[rd_count]; + unsigned int i; + struct GNUNET_TIME_Absolute exp = GNUNET_TIME_UNIT_FOREVER_ABS; - if (xquery_size == 0) - continue; + if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (rd_len, + rd_data, + rd_count, + rd)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Data invalid (%d bytes, %d records)\n", rd_len, rd_count); + GNUNET_break_op (0); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + + if (xquery_size < sizeof(uint32_t)) + record_xquery = 0; + else + record_xquery = ntohl(*((uint32_t*)xquery)); - if (rd[i].record_type == record_xquery) + for (i=0; ipublic_key, - name, - rd_count, - rd, - NULL)) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Signature invalid\n"); - return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; - }*/ + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature (&nrb->public_key, + exp, + name, + rd_count, + rd, + &nrb->signature)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Signature invalid for name %s\n"); + GNUNET_break_op (0); + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + } + } - //No record matches query - if ((xquery_size > 0) && (record_match == 0)) - return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - - GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Records match\n"); - //FIXME do bf check before or after crypto?? if (NULL != bf) { GNUNET_CRYPTO_hash(reply_block, reply_block_size, &chash); GNUNET_BLOCK_mingle_hash(&chash, bf_mutator, &mhash); if (NULL != *bf) { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Check BF\n"); if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test(*bf, &mhash)) return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; } @@ -151,7 +200,6 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, } GNUNET_CONTAINER_bloomfilter_add(*bf, &mhash); } - GNUNET_log(GNUNET_ERROR_TYPE_INFO, "No dup\n"); return GNUNET_BLOCK_EVALUATION_OK_MORE; } @@ -174,18 +222,23 @@ block_plugin_gns_get_key (void *cls, enum GNUNET_BLOCK_Type type, { if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) return GNUNET_SYSERR; - GNUNET_HashCode name_hash; - GNUNET_HashCode pkey_hash; + struct GNUNET_CRYPTO_ShortHashCode name_hash; + struct GNUNET_CRYPTO_ShortHashCode pkey_hash; + GNUNET_HashCode name_hash_double; + GNUNET_HashCode pkey_hash_double; + struct GNSNameRecordBlock *nrb = (struct GNSNameRecordBlock *)block; - GNUNET_CRYPTO_hash(&nrb[1], strlen((char*)&nrb[1]), &name_hash); - GNUNET_CRYPTO_hash(&nrb->public_key, + GNUNET_CRYPTO_short_hash(&nrb[1], strlen((char*)&nrb[1]), &name_hash); + GNUNET_CRYPTO_short_hash(&nrb->public_key, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pkey_hash); + + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_short_hash_double(&pkey_hash, &pkey_hash_double); - GNUNET_CRYPTO_hash_xor(&name_hash, &pkey_hash, key); + GNUNET_CRYPTO_hash_xor(&name_hash_double, &pkey_hash_double, key); - //FIXME calculate key from name and hash(pkey) here return GNUNET_OK; } diff --git a/src/gns/test_gns_defaults.conf b/src/gns/test_gns_defaults.conf new file mode 100644 index 0000000..b7e68ff --- /dev/null +++ b/src/gns/test_gns_defaults.conf @@ -0,0 +1,69 @@ +[PATHS] +SERVICEHOME = /tmp/test-gnunet-testing/ +DEFAULTCONFIG = test_testing_defaults.conf + +[resolver] +PORT = 2564 + +[transport] +PORT = 2565 +PLUGINS = tcp + +[arm] +PORT = 2566 +DEFAULTSERVICES = + +[statistics] +PORT = 2567 + +[transport-tcp] +PORT = 2568 +BINDTO = 127.0.0.1 + +[peerinfo] +PORT = 2569 + +[core] +PORT = 2570 + +[testing] +NUM_PEERS = 5 +WEAKRANDOM = YES +F2F = YES +HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat + +[dht] +AUTOSTART = NO + +[nat] +DISABLEV6 = YES +ENABLE_UPNP = NO +BEHIND_NAT = NO +ALLOW_NAT = NO +INTERNAL_ADDRESS = 127.0.0.1 +EXTERNAL_ADDRESS = 127.0.0.1 +USE_LOCALADDR = NO + +[dns] +AUTOSTART = NO + +[nse] +AUTOSTART = NO + +[mesh] +AUTOSTART = NO + +[datastore] +AUTOSTART = NO + +[fs] +AUTOSTART = NO + +[dv] +AUTOSTART = NO + +[chat] +AUTOSTART = NO + +[vpn] +AUTOSTART = NO diff --git a/src/gns/test_gns_dht_default.conf b/src/gns/test_gns_dht_default.conf new file mode 100644 index 0000000..1b37373 --- /dev/null +++ b/src/gns/test_gns_dht_default.conf @@ -0,0 +1,94 @@ +@INLINE@ test_gns_defaults.conf +[PATHS] +SERVICEHOME = /tmp/test-gnunet-gns-dht/ +DEFAULTCONFIG = test_gns_dht_default.conf + +[transport-tcp] +PORT = 22568 + +[dht] +UNIXPATH = /tmp/gnunet-service-dht.sock +DEBUG = NO +AUTOSTART = YES +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +HOSTNAME = localhost +PORT = 2102 +BINARY = gnunet-service-dht + +[block] +plugins = dht test gns + +[dhtcache] +QUOTA = 1 MB +DATABASE = sqlite + +[arm] +PORT = 22566 +DEFAULTSERVICES = core namestore dht gns +UNIXPATH = /tmp/gnunet-default-service-arm.sock + +[statistics] +PORT = 22567 +UNIXPATH = /tmp/gnunet-default-service-statistics.sock + +[resolver] +PORT = 22564 +UNIXPATH = /tmp/gnunet-default-service-resolver.sock + +[peerinfo] +PORT = 22569 +UNIXPATH = /tmp/gnunet-default-service-peerinfo.sock + +[transport] +PORT = 22565 +UNIXPATH = /tmp/gnunet-default-service-transport.sock + +[core] +PORT = 22570 +UNIXPATH = /tmp/gnunet-default-service-core.sock + +[ats] +PORT = 22571 +UNIXPATH = /tmp/gnunet-default-service-ats.sock + +[dns] +UNIXPATH = /tmp/gnunet-default-service-dns.sock +PORT = 22369 +AUTOSTART = YES +DNS_EXIT = 8.8.8.8 + +[gns] +PORT = 22370 +#PREFIX = valgrind -v --leak-check=full --track-origins=yes. +AUTOSTART = YES +BINARY = gnunet-service-gns +ZONEKEY = $SERVICEHOME/zonekey.zkey +HIJACK_DNS = NO +UNIXPATH = /tmp/gnunet-service-gns-default.sock +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +AUTO_IMPORT_PKEY = NO +MAX_PARALLEL_BACKGROUND_QUERIES = 10 +DEFAULT_LOOKUP_TIMEOUT = 60 +RECORD_PUT_INTERVAL = 1 +ZONE_PUT_INTERVAL = 5 + +[namestore] +PORT = 22371 +AUTOSTART = YES +UNIXPATH = /tmp/gnunet-service-namestore-default.sock +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-namestore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DATABASE = sqlite +ZONEFILE_DIRECTORY = $SERVICEHOME + +[namestore-sqlite] +FILENAME = $SERVICEHOME/sqlite-default.db + diff --git a/src/gns/test_gns_dht_delegated_lookup.c b/src/gns/test_gns_dht_delegated_lookup.c new file mode 100644 index 0000000..882bb7e --- /dev/null +++ b/src/gns/test_gns_dht_delegated_lookup.c @@ -0,0 +1,411 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gns/test_gns_dht_delegated_lookup.c + * @brief test for record lookup via DHT + * + */ +#include "platform.h" +#include "gnunet_testing_lib.h" +#include "gnunet_core_service.h" +#include "block_gns.h" +#include "gnunet_signatures.h" +#include "gnunet_namestore_service.h" +#include "../namestore/namestore.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_dht_service.h" +#include "gnunet_gns_service.h" + +/* DEFINES */ +#define VERBOSE GNUNET_YES + +/* Timeout for entire testcase */ +#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20) + +/* If number of peers not in config file, use this number */ +#define DEFAULT_NUM_PEERS 2 + +/* test records to resolve */ +#define TEST_DOMAIN "www.bob.gnunet" +#define TEST_IP "127.0.0.1" +#define TEST_RECORD_NAME "www" + +#define TEST_AUTHORITY_NAME "bob" + +#define DHT_OPERATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) + +#define KEYFILE_BOB "../namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey" + +/* Globals */ + +/** + * Directory to store temp data in, defined in config file + */ +static char *test_directory; + +static struct GNUNET_TESTING_PeerGroup *pg; + +/* Task handle to use to schedule test failure */ +GNUNET_SCHEDULER_TaskIdentifier die_task; + +/* Global return value (0 for success, anything else for failure) */ +static int ok; + +static struct GNUNET_NAMESTORE_Handle *namestore_handle; + +static struct GNUNET_GNS_Handle *gns_handle; + +static struct GNUNET_DHT_Handle *dht_handle; + +const struct GNUNET_CONFIGURATION_Handle *cfg; + +struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded alice_pkey; +struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded bob_pkey; +struct GNUNET_CRYPTO_RsaPrivateKey *alice_key; +struct GNUNET_CRYPTO_RsaPrivateKey *bob_key; + +/** + * Check whether peers successfully shut down. + */ +void +shutdown_callback (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error on shutdown! ret=%d\n", ok); + if (ok == 0) + ok = 2; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "done(ret=%d)!\n", ok); +} + + +static void +on_lookup_result(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct in_addr a; + int i; + char* addr; + + if (rd_count == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup failed, rp_filtering?\n"); + ok = 2; + } + else + { + ok = 1; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls); + for (i=0; isignature = *sig; + nrb->public_key = bob_pkey; + nrb->rd_count = htonl(1); + memset(&nrb[1], 0, strlen(TEST_RECORD_NAME) + 1); + strcpy((char*)&nrb[1], TEST_RECORD_NAME); + nrb_data = (char*)&nrb[1]; + nrb_data += strlen(TEST_RECORD_NAME) + 1; + + if (-1 == GNUNET_NAMESTORE_records_serialize (1, + &rd, + rd_payload_length, + nrb_data)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Record serialization failed!\n"); + ok = 3; + GNUNET_free (nrb); + return; + } + GNUNET_CRYPTO_short_hash(TEST_RECORD_NAME, strlen(TEST_RECORD_NAME), &name_hash); + GNUNET_CRYPTO_short_hash(&bob_pkey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone_hash); + GNUNET_CRYPTO_short_hash_double(&zone_hash, &zone_hash_double); + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_hash_xor(&zone_hash_double, &name_hash_double, &xor_hash); + + rd_payload_length += sizeof(struct GNSNameRecordBlock) + + strlen(TEST_RECORD_NAME) + 1; + GNUNET_DHT_put (dht_handle, &xor_hash, + 0, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + rd_payload_length, + (char*)nrb, + rd.expiration, + DHT_OPERATION_TIMEOUT, + NULL, + NULL); + GNUNET_free (nrb); + GNUNET_SCHEDULER_add_delayed(TIMEOUT, &commence_testing, NULL); +} + +static void +do_lookup(void *cls, const struct GNUNET_PeerIdentity *id, + const struct GNUNET_CONFIGURATION_Handle *_cfg, + struct GNUNET_TESTING_Daemon *d, const char *emsg) +{ + + + char* alice_keyfile; + struct GNUNET_CRYPTO_ShortHashCode bob_hash; + + cfg = _cfg; + + GNUNET_SCHEDULER_cancel (die_task); + + /* put records into namestore */ + namestore_handle = GNUNET_NAMESTORE_connect(cfg); + if (NULL == namestore_handle) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n"); + ok = -1; + return; + } + + /* dht */ + dht_handle = GNUNET_DHT_connect(cfg, 1); + if (NULL == dht_handle) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to dht\n"); + ok = -1; + return; + } + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", + "ZONEKEY", + &alice_keyfile)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n"); + ok = -1; + return; + } + + alice_key = GNUNET_CRYPTO_rsa_key_create_from_file (alice_keyfile); + bob_key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE_BOB); + + GNUNET_free(alice_keyfile); + + GNUNET_CRYPTO_rsa_key_get_public (alice_key, &alice_pkey); + GNUNET_CRYPTO_rsa_key_get_public (bob_key, &bob_pkey); + GNUNET_CRYPTO_short_hash(&bob_pkey, sizeof(bob_pkey), &bob_hash); + + struct GNUNET_NAMESTORE_RecordData rd; + rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode); + rd.data = &bob_hash; + rd.record_type = GNUNET_GNS_RECORD_PKEY; + + GNUNET_NAMESTORE_record_create (namestore_handle, + alice_key, + TEST_AUTHORITY_NAME, + &rd, + &put_dht, + NULL); + + + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + cfg = c; + /* Get path from configuration file */ + if (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", + &test_directory)) + { + ok = 404; + return; + } + + + /* Set up a task to end testing if peer start fails */ + die_task = + GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, + "didn't start all daemons in reasonable amount of time!!!"); + + /* Start alice */ + //d1 = GNUNET_TESTING_daemon_start(cfg, TIMEOUT, GNUNET_NO, NULL, NULL, 0, + // NULL, NULL, NULL, &do_lookup, NULL); + pg = GNUNET_TESTING_daemons_start(cfg, 1, 1, 1, TIMEOUT, + NULL, NULL, &do_lookup, NULL, NULL, NULL, NULL); +} + +static int +check () +{ + int ret; + + /* Arguments for GNUNET_PROGRAM_run */ + char *const argv[] = { "test-gns-dht-delegated-lookup", /* Name to give running binary */ + "-c", + "test_gns_simple_lookup.conf", /* Config file to use */ +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + /* Run the run function as a new program */ + ret = + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, + "test-gns-dht-delegated-lookup", "nohelp", options, &run, + &ok); + if (ret != GNUNET_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "`test-gns-dht-delegated-lookup': Failed with error code %d\n", ret); + } + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_log_setup ("test-gns-simple-lookup", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + /** + * Need to remove base directory, subdirectories taken care + * of by the testing framework. + */ + return ret; +} + +/* end of test_gns_twopeer.c */ diff --git a/src/gns/test_gns_dht_threepeer.c b/src/gns/test_gns_dht_threepeer.c new file mode 100644 index 0000000..ed9600f --- /dev/null +++ b/src/gns/test_gns_dht_threepeer.c @@ -0,0 +1,524 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gns/test_gns_dht_threepeer.c + * @brief tests dht lookup over 3 peers + * + * topology: + * alice <----> bob <-----> dave + * + * alice queries for www.buddy.bob.gnunet + * + */ +#include "platform.h" +#include "gnunet_disk_lib.h" +#include "gnunet_testing_lib.h" +#include "gnunet_core_service.h" +#include "gnunet_dht_service.h" +#include "block_dns.h" +#include "gnunet_signatures.h" +#include "gnunet_namestore_service.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_gns_service.h" + +/* DEFINES */ +#define VERBOSE GNUNET_YES + +/* Timeout for entire testcase */ +#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 180) +#define ZONE_PUT_WAIT_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30) + +/* If number of peers not in config file, use this number */ +#define DEFAULT_NUM_PEERS 2 + +#define TEST_DOMAIN "www.buddy.bob.gnunet" +#define TEST_IP "1.1.1.1" +#define TEST_DAVE_PSEU "hagbard" +#define TEST_NUM_PEERS 3 +#define TEST_NUM_CON 3 + +/* Globals */ + +/** + * Directory to store temp data in, defined in config file + */ +static char *test_directory; + +/** + * Variable used to store the number of connections we should wait for. + */ +static unsigned int expected_connections; + +/** + * Variable used to keep track of how many peers aren't yet started. + */ +static unsigned long long peers_left; + +struct GNUNET_TESTING_Daemon *d1; +struct GNUNET_TESTING_Daemon *d2; +struct GNUNET_TESTING_Daemon *d3; + + +/** + * Total number of peers to run, set based on config file. + */ +static unsigned long long num_peers; + +/** + * Global used to count how many connections we have currently + * been notified about (how many times has topology_callback been called + * with success?) + */ +static unsigned int total_connections; + +/** + * Global used to count how many failed connections we have + * been notified about (how many times has topology_callback + * been called with failure?) + */ +static unsigned int failed_connections; + +/* Task handle to use to schedule test failure */ +GNUNET_SCHEDULER_TaskIdentifier die_task; + +GNUNET_SCHEDULER_TaskIdentifier bob_task; + +/* Global return value (0 for success, anything else for failure) */ +static int ok; + +int bob_online, alice_online, dave_online; + +const struct GNUNET_CONFIGURATION_Handle *alice_cfg; +struct GNUNET_CONFIGURATION_Handle *cfg_bob; +struct GNUNET_CONFIGURATION_Handle *cfg_dave; + +struct GNUNET_CRYPTO_ShortHashCode bob_hash; +struct GNUNET_CRYPTO_ShortHashCode dave_hash; +struct GNUNET_TESTING_Daemon *alice_daemon; +struct GNUNET_TESTING_Daemon *bob_daemon; +struct GNUNET_TESTING_Daemon *dave_daemon; + +struct GNUNET_TESTING_PeerGroup *pg; +struct GNUNET_GNS_Handle *gh; + +/** + * Function scheduled to be run on the successful completion of this + * testcase. Specifically, called when our get request completes. + */ +static void +finish_testing (void *cls, const char *emsg) +{ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test finished! (ret=%d)\n", ok); +} + +/** + * Continuation for the GNUNET_DHT_get_stop call, so that we don't shut + * down the peers without freeing memory associated with GET request. + */ +static void +end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + die_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &finish_testing, NULL); +} + +/** + * Check if the get_handle is being used, if so stop the request. Either + * way, schedule the end_badly_cont function which actually shuts down the + * test. + */ +static void +end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + die_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failing test with error: `%s'!\n", + (char *) cls); + die_task = GNUNET_SCHEDULER_add_now (&end_badly_cont, NULL); + ok = 1; +} + + +static void +on_lookup_result(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + int i; + char* string_val; + const char* typename; + + if (rd_count == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup failed!\n"); + ok = 2; + } + else + { + ok = 1; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls); + for (i=0; ishortname, second_daemon->shortname, distance); +#endif + } +#if VERBOSE + else + { + failed_connections++; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to connect peer %s to peer %s with error :\n%s\n", + first_daemon->shortname, second_daemon->shortname, emsg); + } +#endif + + if (total_connections == expected_connections) + { +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Created %d total connections, which is our target number! Starting next phase of testing.\n", + total_connections); +#endif + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + //die_task = + // GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from connect"); + + //commence_testing(); + + } + else if (total_connections + failed_connections == expected_connections) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = + GNUNET_SCHEDULER_add_now (&end_badly, + "from topology_callback (too many failed connections)"); + } +} + +void +all_connected(void *cls, const char *emsg) +{ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Created all connections! Starting next phase of testing.\n"); + GNUNET_SCHEDULER_add_delayed (ZONE_PUT_WAIT_TIME, &commence_testing, NULL); +} + +void +ns_create_cont(void *cls, int32_t s, const char *emsg) +{ + GNUNET_NAMESTORE_disconnect((struct GNUNET_NAMESTORE_Handle *)cls, 0); +} + +static void +daemon_started (void *cls, const struct GNUNET_PeerIdentity *id, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Daemon *d, const char *emsg) +{ + struct GNUNET_NAMESTORE_Handle *ns; + char* keyfile; + struct GNUNET_CRYPTO_RsaPrivateKey *key; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; + struct in_addr *web; + struct GNUNET_NAMESTORE_RecordData rd; + + rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_NONE; + rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + + if (NULL == dave_daemon) + { + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", + "ZONEKEY", + &keyfile)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n"); + ok = -1; + return; + } + dave_daemon = d; + + key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "This is now dave\n"); + ns = GNUNET_NAMESTORE_connect(cfg); + + GNUNET_CRYPTO_rsa_key_get_public (key, &pkey); + GNUNET_CRYPTO_short_hash(&pkey, sizeof(pkey), &dave_hash); + + web = GNUNET_malloc(sizeof(struct in_addr)); + GNUNET_assert(1 == inet_pton (AF_INET, TEST_IP, web)); + rd.data_size = sizeof(struct in_addr); + rd.data = web; + rd.record_type = GNUNET_GNS_RECORD_TYPE_A; + + GNUNET_NAMESTORE_record_create (ns, key, "www", &rd, NULL, NULL); + + rd.data_size = strlen(TEST_DAVE_PSEU); + rd.data = TEST_DAVE_PSEU; + rd.record_type = GNUNET_GNS_RECORD_PSEU; + + GNUNET_NAMESTORE_record_create (ns, key, "+", &rd, ns_create_cont, ns); + + GNUNET_CRYPTO_rsa_key_free(key); + GNUNET_free(keyfile); + GNUNET_free(web); + + return; + } + + + if (NULL == bob_daemon) + { + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", + "ZONEKEY", + &keyfile)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n"); + ok = -1; + return; + } + bob_daemon = d; + + key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "This is now bob\n"); + ns = GNUNET_NAMESTORE_connect(cfg); + + GNUNET_CRYPTO_rsa_key_get_public (key, &pkey); + GNUNET_CRYPTO_short_hash(&pkey, sizeof(pkey), &bob_hash); + + rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode); + rd.data = &dave_hash; + rd.record_type = GNUNET_GNS_RECORD_PKEY; + + GNUNET_NAMESTORE_record_create (ns, key, "buddy", &rd, ns_create_cont, ns); + + GNUNET_CRYPTO_rsa_key_free(key); + GNUNET_free(keyfile); + + return; + } + + + + if (NULL == alice_daemon) + { + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", + "ZONEKEY", + &keyfile)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n"); + ok = -1; + return; + } + alice_daemon = d; + alice_cfg = cfg; + + key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "This is now alice\n"); + ns = GNUNET_NAMESTORE_connect(cfg); + + rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode); + rd.data = &bob_hash; + rd.record_type = GNUNET_GNS_RECORD_PKEY; + + GNUNET_NAMESTORE_record_create (ns, key, "bob", &rd, ns_create_cont, ns); + + GNUNET_CRYPTO_rsa_key_free(key); + GNUNET_free(keyfile); + + GNUNET_TESTING_connect_topology (pg, GNUNET_TESTING_TOPOLOGY_CLIQUE, + GNUNET_TESTING_TOPOLOGY_OPTION_ALL, + 0, + TIMEOUT, + 3, + &all_connected, NULL); + return; + + } + + + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "This is a random guy\n"); +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + + /* Get path from configuration file */ + if (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", + &test_directory)) + { + ok = 404; + return; + } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "starting\n"); + + /* Get number of peers to start from configuration (should be two) */ + if (GNUNET_SYSERR == + GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", + &num_peers)) + num_peers = DEFAULT_NUM_PEERS; + + /* Set peers_left so we know when all peers started */ + peers_left = num_peers; + + bob_daemon = NULL; + dave_daemon = NULL; + alice_daemon = NULL; + + pg = GNUNET_TESTING_daemons_start (cfg, TEST_NUM_PEERS, TEST_NUM_CON, + TEST_NUM_CON, TIMEOUT, NULL, NULL, &daemon_started, NULL, + &daemon_connected, NULL, NULL); + + /* Set up a task to end testing if peer start fails */ + die_task = + GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, + "didn't start all daemons in reasonable amount of time!!!"); + + alice_online = 0; + bob_online = 0; + dave_online = 0; + expected_connections = 2; + + /* Start alice */ + //d1 = GNUNET_TESTING_daemon_start(cfg_alice, TIMEOUT, GNUNET_NO, NULL, NULL, 0, + // NULL, NULL, NULL, &alice_started, NULL); + + + + +} + +static int +check () +{ + int ret; + + /* Arguments for GNUNET_PROGRAM_run */ + char *const argv[] = { "test-gns-twopeer", /* Name to give running binary */ + "-c", + "test_gns_dht_default.conf", /* Config file to use */ +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + /* Run the run function as a new program */ + ret = + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, + "test-gns-threepeer", "nohelp", options, &run, + &ok); + if (ret != GNUNET_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "`test-gns-threepeer': Failed with error code %d\n", ret); + } + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_log_setup ("test-gns-threepeer", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + /** + * Need to remove base directory, subdirectories taken care + * of by the testing framework. + */ + return ret; +} + +/* end of test_gns_threepeer.c */ diff --git a/src/gns/test_gns_max_queries.c b/src/gns/test_gns_max_queries.c new file mode 100644 index 0000000..ad1743c --- /dev/null +++ b/src/gns/test_gns_max_queries.c @@ -0,0 +1,381 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gns/test_gns_max_queries.c + * @brief base testcase for testing GNS background queries + * in particular query replacement and clean shutdown + */ +#include "platform.h" +#include "gnunet_testing_lib.h" +#include "gnunet_core_service.h" +#include "block_dns.h" +#include "gns.h" +#include "gnunet_signatures.h" +#include "gnunet_namestore_service.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_gns_service.h" + +/* DEFINES */ +#define VERBOSE GNUNET_YES + +/* Timeout for entire testcase */ +#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20) + +/* If number of peers not in config file, use this number */ +#define DEFAULT_NUM_PEERS 2 + +/* test records to resolve */ +#define TEST_DOMAIN "www.gnunet" +#define TEST_DOMAIN_NACK "doesnotexist.bob.gnunet" +#define TEST_IP "127.0.0.1" +#define TEST_RECORD_NAME "www" +#define TEST_ADDITIONAL_LOOKUPS 5 +#define TEST_AUTHORITY_NAME "bob" + +#define KEYFILE_BOB "../namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey" + +/* Globals */ + +/** + * Directory to store temp data in, defined in config file + */ +static char *test_directory; + +static struct GNUNET_TESTING_PeerGroup *pg; + +/* Task handle to use to schedule test failure */ +GNUNET_SCHEDULER_TaskIdentifier die_task; + +/* Global return value (0 for success, anything else for failure) */ +static int ok; + +static struct GNUNET_NAMESTORE_Handle *namestore_handle; + +static struct GNUNET_GNS_Handle *gns_handle; + +const struct GNUNET_CONFIGURATION_Handle *cfg; + +static unsigned long long max_parallel_lookups; + +/** + * Check whether peers successfully shut down. + */ +void +shutdown_callback (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error on shutdown! ret=%d\n", ok); + if (ok == 0) + ok = 2; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "done(ret=%d)!\n", ok); +} + +static void +on_lookup_result_dummy(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + if (rd_count != 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Got %d results from dummy lookup! Wanted: 0\n", + rd_count); + ok = -1; + } +} + +static void +on_lookup_result(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct in_addr a; + int i; + char* addr; + + if (rd_count == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup failed, rp_filtering?\n"); + ok = 2; + } + else + { + ok = 1; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls); + for (i=0; isignature = *sig; + nrb->public_key = alice_pkey; + nrb->rd_count = htonl(1); + memset(&nrb[1], 0, strlen("+") + 1); + strcpy((char*)&nrb[1], "+"); + nrb_data = (char*)&nrb[1]; + nrb_data += strlen("+") + 1; + + if (-1 == GNUNET_NAMESTORE_records_serialize (1, + &rd, + rd_payload_length, + nrb_data)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Record serialization failed!\n"); + ok = 3; + GNUNET_DHT_disconnect(dht_handle); + + + GNUNET_CRYPTO_rsa_key_free(our_key); + GNUNET_CRYPTO_rsa_key_free(bob_key); + GNUNET_CRYPTO_rsa_key_free(alice_key); + GNUNET_free(sig); + GNUNET_free (nrb); + return; + } + GNUNET_CRYPTO_short_hash("+", strlen("+"), &name_hash); + GNUNET_CRYPTO_short_hash(&alice_pkey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone_hash); + + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_short_hash_double(&zone_hash, &zone_hash_double); + GNUNET_CRYPTO_hash_xor(&zone_hash_double, &name_hash_double, &xor_hash); + + rd_payload_length += sizeof(struct GNSNameRecordBlock) + + strlen("+") + 1; + + GNUNET_DHT_put (dht_handle, &xor_hash, + 0, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + rd_payload_length, + (char*)nrb, + rd.expiration, + DHT_OPERATION_TIMEOUT, + &commence_testing, + NULL); + + GNUNET_free(sig); + GNUNET_free (nrb); +} + +static void +put_www_dht(void *cls, int success) +{ + struct GNSNameRecordBlock *nrb; + struct GNUNET_CRYPTO_ShortHashCode name_hash; + struct GNUNET_CRYPTO_ShortHashCode zone_hash; + GNUNET_HashCode xor_hash; + GNUNET_HashCode name_hash_double; + GNUNET_HashCode zone_hash_double; + uint32_t rd_payload_length; + char* nrb_data = NULL; + struct GNUNET_CRYPTO_RsaSignature *sig; + struct GNUNET_NAMESTORE_RecordData rd; + char* ip = TEST_IP; + struct in_addr *web = GNUNET_malloc(sizeof(struct in_addr)); + + rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + GNUNET_assert(1 == inet_pton (AF_INET, ip, web)); + rd.data_size = sizeof(struct in_addr); + rd.data = web; + rd.record_type = GNUNET_DNSPARSER_TYPE_A; + + sig = GNUNET_NAMESTORE_create_signature(alice_key, + GNUNET_TIME_UNIT_FOREVER_ABS, + TEST_RECORD_NAME, + &rd, 1); + rd_payload_length = GNUNET_NAMESTORE_records_get_size (1, &rd); + nrb = GNUNET_malloc(rd_payload_length + strlen(TEST_RECORD_NAME) + 1 + + sizeof(struct GNSNameRecordBlock)); + nrb->signature = *sig; + nrb->public_key = alice_pkey; + nrb->rd_count = htonl(1); + memset(&nrb[1], 0, strlen(TEST_RECORD_NAME) + 1); + strcpy((char*)&nrb[1], TEST_RECORD_NAME); + nrb_data = (char*)&nrb[1]; + nrb_data += strlen(TEST_RECORD_NAME) + 1; + + if (-1 == GNUNET_NAMESTORE_records_serialize (1, + &rd, + rd_payload_length, + nrb_data)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Record serialization failed!\n"); + ok = 3; + GNUNET_DHT_disconnect(dht_handle); + + GNUNET_CRYPTO_rsa_key_free(our_key); + GNUNET_CRYPTO_rsa_key_free(bob_key); + GNUNET_CRYPTO_rsa_key_free(alice_key); + GNUNET_free(web); + GNUNET_free (nrb); + return; + } + GNUNET_CRYPTO_short_hash(TEST_RECORD_NAME, strlen(TEST_RECORD_NAME), &name_hash); + GNUNET_CRYPTO_short_hash(&alice_pkey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone_hash); + GNUNET_CRYPTO_short_hash_double(&zone_hash, &zone_hash_double); + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_hash_xor(&zone_hash_double, &name_hash_double, &xor_hash); + + rd_payload_length += sizeof(struct GNSNameRecordBlock) + + strlen(TEST_RECORD_NAME) + 1; + + GNUNET_DHT_put (dht_handle, &xor_hash, + 0, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + rd_payload_length, + (char*)nrb, + rd.expiration, + DHT_OPERATION_TIMEOUT, + &put_pseu_dht, + NULL); + + GNUNET_free(web); + GNUNET_free (nrb); +} + + +static void +put_pkey_dht(void *cls, int32_t success, const char *emsg) +{ + struct GNSNameRecordBlock *nrb; + struct GNUNET_CRYPTO_ShortHashCode name_hash; + struct GNUNET_CRYPTO_ShortHashCode zone_hash; + GNUNET_HashCode xor_hash; + GNUNET_HashCode name_hash_double; + GNUNET_HashCode zone_hash_double; + uint32_t rd_payload_length; + char* nrb_data = NULL; + struct GNUNET_CRYPTO_RsaSignature *sig; + struct GNUNET_NAMESTORE_RecordData rd; + + rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode); + rd.data = &alice_hash; + rd.record_type = GNUNET_GNS_RECORD_PKEY; + + sig = GNUNET_NAMESTORE_create_signature(bob_key, + GNUNET_TIME_UNIT_FOREVER_ABS, + TEST_AUTHORITY_ALICE, + &rd, + 1); + + rd_payload_length = GNUNET_NAMESTORE_records_get_size (1, &rd); + nrb = GNUNET_malloc(rd_payload_length + strlen(TEST_AUTHORITY_ALICE) + 1 + + sizeof(struct GNSNameRecordBlock)); + nrb->signature = *sig; + nrb->public_key = bob_pkey; + nrb->rd_count = htonl(1); + memset(&nrb[1], 0, strlen(TEST_AUTHORITY_ALICE) + 1); + strcpy((char*)&nrb[1], TEST_AUTHORITY_ALICE); + nrb_data = (char*)&nrb[1]; + nrb_data += strlen(TEST_AUTHORITY_ALICE) + 1; + + if (-1 == GNUNET_NAMESTORE_records_serialize (1, + &rd, + rd_payload_length, + nrb_data)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Record serialization failed!\n"); + ok = 3; + + GNUNET_CRYPTO_rsa_key_free(our_key); + GNUNET_CRYPTO_rsa_key_free(bob_key); + GNUNET_CRYPTO_rsa_key_free(alice_key); + GNUNET_free(sig); + GNUNET_free (nrb); + return; + } + + + GNUNET_CRYPTO_short_hash(TEST_AUTHORITY_ALICE, + strlen(TEST_AUTHORITY_ALICE), &name_hash); + GNUNET_CRYPTO_short_hash(&bob_pkey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone_hash); + GNUNET_CRYPTO_short_hash_double(&zone_hash, &zone_hash_double); + GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); + GNUNET_CRYPTO_hash_xor(&zone_hash_double, &name_hash_double, &xor_hash); + + rd_payload_length += sizeof(struct GNSNameRecordBlock) + + strlen(TEST_AUTHORITY_ALICE) + 1; + GNUNET_DHT_put (dht_handle, &xor_hash, + 0, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + rd_payload_length, + (char*)nrb, + rd.expiration, + DHT_OPERATION_TIMEOUT, + &put_www_dht, + NULL); + GNUNET_NAMESTORE_disconnect(namestore_handle, GNUNET_NO); + GNUNET_free (nrb); +} + +static void +do_lookup(void *cls, const struct GNUNET_PeerIdentity *id, + const struct GNUNET_CONFIGURATION_Handle *_cfg, + struct GNUNET_TESTING_Daemon *d, const char *emsg) +{ + + + char* our_keyfile; + + cfg = _cfg; + + GNUNET_SCHEDULER_cancel (die_task); + + /* put records into namestore */ + namestore_handle = GNUNET_NAMESTORE_connect(cfg); + if (NULL == namestore_handle) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n"); + ok = -1; + return; + } + + /* dht */ + dht_handle = GNUNET_DHT_connect(cfg, 1); + if (NULL == dht_handle) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to dht\n"); + ok = -1; + return; + } + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", + "ZONEKEY", + &our_keyfile)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n"); + ok = -1; + return; + } + + our_key = GNUNET_CRYPTO_rsa_key_create_from_file (our_keyfile); + bob_key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE_BOB); + alice_key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE_ALICE); + + GNUNET_free(our_keyfile); + + GNUNET_CRYPTO_rsa_key_get_public (our_key, &our_pkey); + GNUNET_CRYPTO_rsa_key_get_public (bob_key, &bob_pkey); + GNUNET_CRYPTO_rsa_key_get_public (alice_key, &alice_pkey); + GNUNET_CRYPTO_short_hash(&bob_pkey, sizeof(bob_pkey), &bob_hash); + GNUNET_CRYPTO_short_hash(&alice_pkey, sizeof(alice_pkey), &alice_hash); + + struct GNUNET_NAMESTORE_RecordData rd; + rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode); + rd.data = &bob_hash; + rd.record_type = GNUNET_GNS_RECORD_PKEY; + + GNUNET_NAMESTORE_record_create (namestore_handle, + our_key, + TEST_AUTHORITY_BOB, + &rd, + &put_pkey_dht, + NULL); + + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + cfg = c; + /* Get path from configuration file */ + if (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", + &test_directory)) + { + ok = 404; + return; + } + + + /* Set up a task to end testing if peer start fails */ + die_task = + GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, + "didn't start all daemons in reasonable amount of time!!!"); + + /* Start alice */ + //d1 = GNUNET_TESTING_daemon_start(cfg, TIMEOUT, GNUNET_NO, NULL, NULL, 0, + // NULL, NULL, NULL, &do_lookup, NULL); + pg = GNUNET_TESTING_daemons_start(cfg, 1, 1, 1, TIMEOUT, + NULL, NULL, &do_lookup, NULL, + NULL, NULL, NULL); +} + +static int +check () +{ + int ret; + + /* Arguments for GNUNET_PROGRAM_run */ + char *const argv[] = { "test-gns-pseu-shorten", /* Name to give running binary */ + "-c", + "test_gns_simple_lookup.conf", /* Config file to use */ +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + /* Run the run function as a new program */ + ret = + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, + "test-gns-pseu-shorten", "nohelp", options, &run, + &ok); + if (ret != GNUNET_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "`test-gns-pseu-shorten': Failed with error code %d\n", ret); + } + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_log_setup ("test-gns-pseu-shorten", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + /** + * Need to remove base directory, subdirectories taken care + * of by the testing framework. + */ + return ret; +} + +/* end of test_gns_twopeer.c */ diff --git a/src/gns/test_gns_simple_delegated_lookup.c b/src/gns/test_gns_simple_delegated_lookup.c new file mode 100644 index 0000000..36fb969 --- /dev/null +++ b/src/gns/test_gns_simple_delegated_lookup.c @@ -0,0 +1,355 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gns/test_gns_twopeer.c + * @brief base testcase for testing DHT service with + * two running peers. + * + * This testcase starts peers using the GNUNET_TESTING_daemons_start + * function call. On peer start, connects to the peers DHT service + * by calling GNUNET_DHT_connected. Once notified about all peers + * being started (by the peers_started_callback function), calls + * GNUNET_TESTING_connect_topology, which connects the peers in a + * "straight line" topology. On notification that all peers have + * been properly connected, calls the do_get function which initiates + * a GNUNET_DHT_get from the *second* peer. Once the GNUNET_DHT_get + * function starts, runs the do_put function to insert data at the first peer. + * If the GET is successful, schedules finish_testing + * to stop the test and shut down peers. If GET is unsuccessful + * after GET_TIMEOUT seconds, prints an error message and shuts down + * the peers. + */ +#include "platform.h" +#include "gnunet_testing_lib.h" +#include "gnunet_core_service.h" +#include "block_dns.h" +#include "gnunet_signatures.h" +#include "gnunet_namestore_service.h" +#include "../namestore/namestore.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_gns_service.h" + +/* DEFINES */ +#define VERBOSE GNUNET_YES + +/* Timeout for entire testcase */ +#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20) + +/* If number of peers not in config file, use this number */ +#define DEFAULT_NUM_PEERS 2 + +/* test records to resolve */ +#define TEST_DOMAIN "www.bob.gnunet" +#define TEST_IP "127.0.0.1" +#define TEST_RECORD_NAME "www" + +#define TEST_AUTHORITY_NAME "bob" + +#define KEYFILE_BOB "../namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey" + +/* Globals */ + +/** + * Directory to store temp data in, defined in config file + */ +static char *test_directory; + +static struct GNUNET_TESTING_PeerGroup *pg; + +/* Task handle to use to schedule test failure */ +GNUNET_SCHEDULER_TaskIdentifier die_task; + +/* Global return value (0 for success, anything else for failure) */ +static int ok; + +static struct GNUNET_NAMESTORE_Handle *namestore_handle; + +static struct GNUNET_GNS_Handle *gns_handle; + +const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Check whether peers successfully shut down. + */ +void +shutdown_callback (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error on shutdown! ret=%d\n", ok); + if (ok == 0) + ok = 2; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "done(ret=%d)!\n", ok); +} + +static void +on_lookup_result(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct in_addr a; + int i; + char* addr; + + if (rd_count == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup failed, rp_filtering?\n"); + ok = 2; + } + else + { + ok = 1; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls); + for (i=0; ishortname, second_daemon->shortname, distance); -#endif - } -#if VERBOSE - else - { - failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Failed to connect peer %s to peer %s with error :\n%s\n", - first_daemon->shortname, second_daemon->shortname, emsg); - } -#endif - - if (total_connections == expected_connections) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Created %d total connections, which is our target number! Starting next phase of testing.\n", - total_connections); -#endif - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from test lookup"); - - /* start gns for alice */ - GNUNET_TESTING_daemon_start_service (d1, "gns", TIMEOUT, &gns_started, NULL); - - } - else if (total_connections + failed_connections == expected_connections) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from topology_callback (too many failed connections)"); - } -} - -/** - * Set up some data, and call API PUT function - */ -static void -alice_idle (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - - alice_online = 1; - if (!bob_online) - { - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 2), - &alice_idle, NULL); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting peers\n"); - GNUNET_TESTING_daemons_connect (d1, d2, TIMEOUT, 5, 1, - ¬ify_connect, NULL); -} - -static void -bob_idle (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - /* he's lazy FIXME forever */ - bob_online = 1; - bob_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 20), - &bob_idle, NULL); -} - - - - -/** - * Callback which is called whenever a peer is started (as a result of the - * GNUNET_TESTING_daemons_start call. - * - * @param cls closure argument given to GNUNET_TESTING_daemons_start - * @param id the GNUNET_PeerIdentity of the started peer - * @param cfg the configuration for this specific peer (needed to connect - * to the DHT) - * @param d the handle to the daemon started - * @param emsg NULL if peer started, non-NULL on error - */ -static void -alice_started (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 2), - &alice_idle, NULL); -} - -static void -bob_started (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 2), - &bob_idle, NULL); -} - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - - /* Get path from configuration file */ - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", - &test_directory)) - { - ok = 404; - return; - } - - /* Get number of peers to start from configuration (should be two) */ - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - - /* Set peers_left so we know when all peers started */ - peers_left = num_peers; - - /* Set up a task to end testing if peer start fails */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "didn't start all daemons in reasonable amount of time!!!"); - - alice_online = 0; - bob_online = 0; - expected_connections = 1; - - /* Start alice */ - d1 = GNUNET_TESTING_daemon_start(cfg, TIMEOUT, GNUNET_NO, NULL, NULL, 0, - NULL, NULL, NULL, &alice_started, NULL); - - /* Somebody care to explain? */ - uint16_t port = 6000; - uint32_t upnum = 23; - uint32_t fdnum = 42; - - - /** - * Modify some config options for bob - * namely swap keys and disable dns hijacking - */ - struct GNUNET_CONFIGURATION_Handle *cfg2 = GNUNET_TESTING_create_cfg(cfg, - 23, &port, &upnum, - NULL, &fdnum); - - GNUNET_CONFIGURATION_set_value_string (cfg2, "paths", "servicehome", - "/tmp/test-gnunetd-gns-peer-2/"); - GNUNET_CONFIGURATION_set_value_string (cfg2, "gns", "HIJACK_DNS", - "NO"); - GNUNET_CONFIGURATION_set_value_string (cfg2, "gns", "ZONEKEY", - "/tmp/bobkey"); - GNUNET_CONFIGURATION_set_value_string (cfg2, "gns", "TRUSTED", - "alice:/tmp/alicekey"); - - //Start bob - d2 = GNUNET_TESTING_daemon_start(cfg2, TIMEOUT, GNUNET_NO, NULL, NULL, 0, - NULL, NULL, NULL, &bob_started, NULL); - - -} - -static int -check () -{ - int ret; - - /* Arguments for GNUNET_PROGRAM_run */ - char *const argv[] = { "test-gns-twopeer", /* Name to give running binary */ - "-c", - "test_gns_twopeer.conf", /* Config file to use */ -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - /* Run the run function as a new program */ - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-gns-twopeer", "nohelp", options, &run, - &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-gns-twopeer': Failed with error code %d\n", ret); - } - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-gns-twopeer", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - /** - * Need to remove base directory, subdirectories taken care - * of by the testing framework. - */ - return ret; -} - -/* end of test_gns_twopeer.c */ diff --git a/src/gns/test_gns_twopeer.conf b/src/gns/test_gns_twopeer.conf deleted file mode 100644 index 4048297..0000000 --- a/src/gns/test_gns_twopeer.conf +++ /dev/null @@ -1,80 +0,0 @@ -[fs] -AUTOSTART = NO - -[resolver] -AUTOSTART = NO - -[dht] -DEBUG = NO -AUTOSTART = YES -ACCEPT_FROM6 = ::1; -ACCEPT_FROM = 127.0.0.1; -HOSTNAME = localhost -PORT = 2100 -BINARY = gnunet-service-dht - -[block] -plugins = dht test gns - -[dhtcache] -QUOTA = 1 MB -DATABASE = sqlite - -[transport] -PLUGINS = tcp -DEBUG = NO -ACCEPT_FROM6 = ::1; -ACCEPT_FROM = 127.0.0.1; -NEIGHBOUR_LIMIT = 50 -PORT = 12365 - -[ats] -WAN_QUOTA_IN = 1 GB -WAN_QUOTA_OUT = 1 GB - -[core] -PORT = 12092 - -[arm] -DEFAULTSERVICES = core -PORT = 12366 -DEBUG = NO - -[transport-tcp] -TIMEOUT = 300 s -PORT = 12368 -BINDTO = 127.0.0.1 - -[TESTING] -WEAKRANDOM = YES - -[gnunetd] -HOSTKEY = $SERVICEHOME/.hostkey - -[PATHS] -DEFAULTCONFIG = gns.conf -SERVICEHOME = /tmp/test-gnunetd-gns-peer-1/ - - -[nat] -DISABLEV6 = YES -ENABLE_UPNP = NO -BEHIND_NAT = NO -ALLOW_NAT = NO -INTERNAL_ADDRESS = 127.0.0.1 -EXTERNAL_ADDRESS = 127.0.0.1 -USE_LOCALADDR = NO - -[dns] -AUTOSTART = YES - -[gns] -AUTOSTART = YES -BINARY = gnunet-service-gns -ZONEKEY = /tmp/alicekey - - -[nse] -AUTOSTART = NO - - diff --git a/src/gns/test_gnunet_gns.sh b/src/gns/test_gnunet_gns.sh deleted file mode 100755 index cd68027..0000000 --- a/src/gns/test_gnunet_gns.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -ME=`whoami` -if [ "$ME" != "root" ] -then - echo "This test only works if run as root. Skipping." - exit 0 -fi -export PATH=".:$PATH" -gnunet-service-gns -c gns.conf & -sleep 1 -LO=`nslookup alice.gnunet | grep Address | tail -n1` -if [ "$LO" != "Address: 1.2.3.4" ] -then - echo "Fail: $LO" -fi -LO=`nslookup www.bob.gnunet | grep Address | tail -n1` -if [ "$LO" != "Address: 4.5.6.7" ] -then - echo "Fail: $LO" -fi -kill `jobs -p` diff --git a/src/hello/Makefile.am b/src/hello/Makefile.am index 1788e8f..26aa6c7 100644 --- a/src/hello/Makefile.am +++ b/src/hello/Makefile.am @@ -19,6 +19,9 @@ libgnunethello_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ -version-info 0:0:0 +noinst_PROGRAMS = \ + gnunet-hello + check_PROGRAMS = \ test_hello @@ -32,3 +35,13 @@ test_hello_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la + +gnunet_hello_SOURCES = \ + gnunet-hello.c +gnunet_hello_LDADD = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la +gnunet_hello_DEPENDENCIES = \ + libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la + diff --git a/src/hello/Makefile.in b/src/hello/Makefile.in index 283d209..1887b27 100644 --- a/src/hello/Makefile.in +++ b/src/hello/Makefile.in @@ -15,6 +15,7 @@ @SET_MAKE@ + VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ @@ -35,6 +36,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ +noinst_PROGRAMS = gnunet-hello$(EXEEXT) check_PROGRAMS = test_hello$(EXEEXT) subdir = src/hello DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in @@ -93,6 +95,9 @@ libgnunethello_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunethello_la_LDFLAGS) $(LDFLAGS) \ -o $@ +PROGRAMS = $(noinst_PROGRAMS) +am_gnunet_hello_OBJECTS = gnunet-hello.$(OBJEXT) +gnunet_hello_OBJECTS = $(am_gnunet_hello_OBJECTS) am_test_hello_OBJECTS = test_hello.$(OBJEXT) test_hello_OBJECTS = $(am_test_hello_OBJECTS) test_hello_DEPENDENCIES = $(top_builddir)/src/hello/libgnunethello.la \ @@ -123,8 +128,10 @@ am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libgnunethello_la_SOURCES) $(test_hello_SOURCES) -DIST_SOURCES = $(libgnunethello_la_SOURCES) $(test_hello_SOURCES) +SOURCES = $(libgnunethello_la_SOURCES) $(gnunet_hello_SOURCES) \ + $(test_hello_SOURCES) +DIST_SOURCES = $(libgnunethello_la_SOURCES) $(gnunet_hello_SOURCES) \ + $(test_hello_SOURCES) ETAGS = etags CTAGS = ctags am__tty_colors = \ @@ -185,6 +192,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -218,6 +226,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -357,6 +366,17 @@ test_hello_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la +gnunet_hello_SOURCES = \ + gnunet-hello.c + +gnunet_hello_LDADD = \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la + +gnunet_hello_DEPENDENCIES = \ + libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la + all: all-am .SUFFIXES: @@ -433,6 +453,18 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +gnunet-hello$(EXEEXT): $(gnunet_hello_OBJECTS) $(gnunet_hello_DEPENDENCIES) + @rm -f gnunet-hello$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_hello_OBJECTS) $(gnunet_hello_LDADD) $(LIBS) test_hello$(EXEEXT): $(test_hello_OBJECTS) $(test_hello_DEPENDENCIES) @rm -f test_hello$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_hello_OBJECTS) $(test_hello_LDADD) $(LIBS) @@ -444,6 +476,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-hello.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hello.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_hello.Po@am__quote@ @@ -655,7 +688,7 @@ check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am -all-am: Makefile $(LTLIBRARIES) +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ @@ -688,7 +721,7 @@ maintainer-clean-generic: clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool mostlyclean-am + clean-libtool clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -760,18 +793,18 @@ uninstall-am: uninstall-libLTLIBRARIES .PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-libLTLIBRARIES \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-libLTLIBRARIES + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/hello/gnunet-hello.c b/src/hello/gnunet-hello.c new file mode 100644 index 0000000..bc35cdd --- /dev/null +++ b/src/hello/gnunet-hello.c @@ -0,0 +1,204 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file hello/gnunet-hello.c + * @brief change HELLO files to never expire + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_hello_lib.h" + +#define DEBUG GNUNET_EXTRA_LOGGING + +#define VERBOSE GNUNET_NO + +/** + * Closure for 'add_to_buf'. + */ +struct AddContext +{ + /** + * Where to add. + */ + char *buf; + + /** + * Maximum number of bytes left + */ + size_t max; + + /** + * Number of bytes added so far. + */ + size_t ret; +}; + + +/** + * Add the given address with infinit expiration to the buffer. + * + * @param cls closure + * @param address address to add + * @param expiration old expiration + * @return GNUNET_OK keep iterating + */ +static int +add_to_buf (void *cls, const struct GNUNET_HELLO_Address *address, + struct GNUNET_TIME_Absolute expiration) +{ + struct AddContext *ac = cls; + size_t ret; + + ret = GNUNET_HELLO_add_address (address, + GNUNET_TIME_UNIT_FOREVER_ABS, + ac->buf, + ac->max); + ac->buf += ret; + ac->max -= ret; + ac->ret += ret; + return GNUNET_OK; +} + + +/** + * Add addresses from the address list to the HELLO. + * + * @param cls the HELLO with the addresses to add + * @param max maximum space available + * @param buf where to add the addresses + * @return number of bytes added, 0 to terminate + */ +static size_t +add_from_hello (void *cls, size_t max, void *buf) +{ + struct GNUNET_HELLO_Message **orig = cls; + struct AddContext ac; + + if (NULL == *orig) + return 0; /* already done */ + ac.buf = buf; + ac.max = max; + ac.ret = 0; + GNUNET_assert (NULL == + GNUNET_HELLO_iterate_addresses (*orig, + GNUNET_NO, &add_to_buf, + &ac)); + *orig = NULL; + return ac.ret; +} + + +int +main (int argc, char *argv[]) +{ + struct GNUNET_DISK_FileHandle *fh; + struct GNUNET_HELLO_Message *orig; + struct GNUNET_HELLO_Message *result; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk; + uint64_t fsize; + + GNUNET_log_setup ("gnunet-hello", "INFO", NULL); + if (argc != 2) + { + FPRINTF (stderr, + "%s", + _("Call with name of HELLO file to modify.\n")); + return 1; + } + if (GNUNET_OK != GNUNET_DISK_file_size (argv[1], &fsize, GNUNET_YES, GNUNET_YES)) + { + FPRINTF (stderr, + _("Error accessing file `%s': %s\n"), + argv[1], + STRERROR (errno)); + return 1; + } + if (fsize > 65536) + { + FPRINTF (stderr, + _("File `%s' is too big to be a HELLO\n"), + argv[1]); + return 1; + } + if (fsize < sizeof (struct GNUNET_MessageHeader)) + { + FPRINTF (stderr, + _("File `%s' is too small to be a HELLO\n"), + argv[1]); + return 1; + } + fh = GNUNET_DISK_file_open (argv[1], + GNUNET_DISK_OPEN_READ, + GNUNET_DISK_PERM_USER_READ); + if (NULL == fh) + { + FPRINTF (stderr, + _("Error opening file `%s': %s\n"), + argv[1], + STRERROR (errno)); + return 1; + } + { + char buf[fsize] GNUNET_ALIGN; + + GNUNET_assert (fsize == + GNUNET_DISK_file_read (fh, buf, fsize)); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); + orig = (struct GNUNET_HELLO_Message *) buf; + if ( (fsize != GNUNET_HELLO_size (orig)) || + (GNUNET_OK != GNUNET_HELLO_get_key (orig, &pk)) ) + { + FPRINTF (stderr, + _("Did not find well-formed HELLO in file `%s'\n"), + argv[1]); + return 1; + } + result = GNUNET_HELLO_create (&pk, &add_from_hello, &orig); + GNUNET_assert (NULL != result); + fh = GNUNET_DISK_file_open (argv[1], + GNUNET_DISK_OPEN_WRITE, + GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); + if (NULL == fh) + { + FPRINTF (stderr, + _("Error opening file `%s': %s\n"), + argv[1], + STRERROR (errno)); + GNUNET_free (result); + return 1; + } + fsize = GNUNET_HELLO_size (result); + if (fsize != GNUNET_DISK_file_write (fh, + result, + fsize)) + { + FPRINTF (stderr, + _("Error writing HELLO to file `%s': %s\n"), + argv[1], + STRERROR (errno)); + (void) GNUNET_DISK_file_close (fh); + return 1; + } + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); + } + return 0; +} + +/* end of gnunet-hello.c */ diff --git a/src/hello/hello.c b/src/hello/hello.c index 7aa9740..6529c93 100644 --- a/src/hello/hello.c +++ b/src/hello/hello.c @@ -641,5 +641,46 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg) return ret; } +/** + * GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER". + * The specific structure of "IDENTIFIER" depends on the module and + * maybe differenciated into additional subcategories if applicable. + * This module only deals with hello identifiers (MODULE = "hello"). + *

+ * + * The concrete URI format is: + * + * "gnunet://hello/PEER[!YYYYMMDDHHNNSS!!

]...". + * These URIs can be used to add a peer record to peerinfo service. + * PEER is the string representation of peer's public key. + * YYYYMMDDHHNNSS is the expiration date. + * TYPE is a transport type. + * ADDRESS is the address, its format depends upon the transport type. + * The concrete transport types and corresponding address formats are: + * + *
  • + * + * !IPADDRESS + * IPVDDRESS is either IPV4 .-delimited address in form of XXX.XXX.XXX.XXX:PPPPP + * or IPV6 :-delimited address, but with '(' and ')' instead of '[' and ']' (RFC2396 advises against using square brackets in URIs): + * (XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX):PPPPP + * PPPPP is the port number. May be 0. + * + *
  • + * + * [add SMTP, HTTP and other addresses here] + * + *
+ * + * The encoding for hexadecimal values is defined in the crypto_hash.c + * module in the gnunetutil library and discussed there. + * + * Examples: + * + * gnunet://hello/0430205UC7D56PTQK8NV05776671CNN44FK4TL6D0GQ35OMF8MEN4RNMKA5UF6AL3DQO8B1SC5AQF50SQ2MABIRU4HC8H2HAJKJ59JL1JVRJAK308F9GASRFLMGUBB5TQ5AKR94AS5T3MDG8B9O1EMPRKB0HVCG7T6QPP4CDJ913LAEHVJ2DI1TOBB15Q1JIT5ARBOD12U4SIGRFDV3Q7T66G4TBVSJJ90UQF1BG29TGJJKLGEIMSPHHKO544D6EALQ4F2K0416311JC22GVAD48R616I7VK03K7MP7N0RS2MBV1TE9JV8CK1LSQMR7KCDRTLDA6917UGA67DHTGHERIACCGQ54TGSR48RMSGS9BA5HLMOKASFC1I6V4TT09TUGCU8GNDHQF0JF3H7LPV59UL5I38QID040G000!20120302010059!TCP!192.168.0.1:2086!TCP!64.23.8.174:0 + * gnunet://hello/0430205UC7D56PTQK8NV05776671CNN44FK4TL6D0GQ35OMF8MEN4RNMKA5UF6AL3DQO8B1SC5AQF50SQ2MABIRU4HC8H2HAJKJ59JL1JVRJAK308F9GASRFLMGUBB5TQ5AKR94AS5T3MDG8B9O1EMPRKB0HVCG7T6QPP4CDJ913LAEHVJ2DI1TOBB15Q1JIT5ARBOD12U4SIGRFDV3Q7T66G4TBVSJJ90UQF1BG29TGJJKLGEIMSPHHKO544D6EALQ4F2K0416311JC22GVAD48R616I7VK03K7MP7N0RS2MBV1TE9JV8CK1LSQMR7KCDRTLDA6917UGA67DHTGHERIACCGQ54TGSR48RMSGS9BA5HLMOKASFC1I6V4TT09TUGCU8GNDHQF0JF3H7LPV59UL5I38QID040G000!20120302010059!TCP!(2001:db8:85a3:8d3:1319:8a2e:370:7348):2086 + * + *

+ */ /* end of hello.c */ diff --git a/src/hello/test_hello.c b/src/hello/test_hello.c index 0efbdee..bdabc72 100644 --- a/src/hello/test_hello.c +++ b/src/hello/test_hello.c @@ -25,7 +25,7 @@ #include "platform.h" #include "gnunet_hello_lib.h" -#define DEBUG GNUNET_EXTRA_LOGGING +#define DEBUG GNUNET_NO #define VERBOSE GNUNET_NO diff --git a/src/hostlist/Makefile.in b/src/hostlist/Makefile.in index 737e87c..4777316 100644 --- a/src/hostlist/Makefile.in +++ b/src/hostlist/Makefile.in @@ -227,6 +227,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -260,6 +261,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c index 350a0ba..6be37fc 100644 --- a/src/hostlist/hostlist-client.c +++ b/src/hostlist/hostlist-client.c @@ -36,8 +36,6 @@ #include "gnunet_common.h" #include "gnunet_bio_lib.h" -#define DEBUG_HOSTLIST_CLIENT GNUNET_EXTRA_LOGGING - /** * Number of connections that we must have to NOT download @@ -208,6 +206,11 @@ static unsigned int linked_list_size; */ static struct Hostlist *hostlist_to_test; +/** + * Handle for our statistics GET operation. + */ +static struct GNUNET_STATISTICS_GetHandle *sget; + /** * Set to GNUNET_YES if the current URL had some problems. */ @@ -320,11 +323,9 @@ callback_download (void *ptr, size_t size, size_t nmemb, void *ctx) } if (GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) msg) == msize) { -#if DEBUG_HOSTLIST_CLIENT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received valid `%s' message from hostlist server.\n", "HELLO"); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# valid HELLOs downloaded from hostlist servers"), @@ -760,13 +761,11 @@ download_prepare () gws = GNUNET_NETWORK_fdset_create (); GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); -#if DEBUG_HOSTLIST_CLIENT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduling task for hostlist download using cURL\n"); -#endif ti_download = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, rtime, grs, gws, + rtime, grs, gws, &task_download, multi); GNUNET_NETWORK_fdset_destroy (gws); GNUNET_NETWORK_fdset_destroy (grs); @@ -790,11 +789,9 @@ task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) ti_download = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { -#if DEBUG_HOSTLIST_CLIENT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown requested while trying to download hostlist from `%s'\n", current_url); -#endif update_hostlist (); clean_up (); return; @@ -808,11 +805,8 @@ task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) clean_up (); return; } -#if DEBUG_HOSTLIST_CLIENT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ready for processing hostlist client request\n"); -#endif - do { running = 0; @@ -839,8 +833,8 @@ task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if ((msg->data.result != CURLE_OK) && (msg->data.result != CURLE_GOT_NOTHING)) GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("%s failed for `%s' at %s:%d: `%s'\n"), - "curl_multi_perform", current_url, __FILE__, __LINE__, + _("Download of hostlist from `%s' failed: `%s'\n"), + current_url, curl_easy_strerror (msg->data.result)); else { @@ -1018,18 +1012,16 @@ task_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) ti_check_download = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - - if (stat_connection_count < MIN_CONNECTIONS) - { - ti_download_dispatcher_task = - GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL); - } - if (stats == NULL) { curl_global_cleanup (); return; /* in shutdown */ } + if ( (stat_connection_count < MIN_CONNECTIONS) && + (GNUNET_SCHEDULER_NO_TASK == ti_download_dispatcher_task) ) + ti_download_dispatcher_task = + GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL); + delay = hostlist_delay; if (hostlist_delay.rel_value == 0) hostlist_delay = GNUNET_TIME_UNIT_SECONDS; @@ -1202,7 +1194,6 @@ handler_advertisement (void *cls, const struct GNUNET_PeerIdentity *peer, hostlist->hostlist_uri = (const char *) &hostlist[1]; memcpy (&hostlist[1], uri, uri_size); hostlist->time_creation = GNUNET_TIME_absolute_get (); - hostlist->time_last_usage = GNUNET_TIME_absolute_get_zero (); hostlist->quality = HOSTLIST_INITIAL; hostlist_to_test = hostlist; @@ -1235,12 +1226,10 @@ handler_advertisement (void *cls, const struct GNUNET_PeerIdentity *peer, static void primary_task (void *cls, int success) { - if (stats == NULL) - return; /* in shutdown */ -#if DEBUG_HOSTLIST_CLIENT + sget = NULL; + GNUNET_assert (stats != NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Statistics request done, scheduling hostlist download\n"); -#endif ti_check_download = GNUNET_SCHEDULER_add_now (&task_check, NULL); } @@ -1447,6 +1436,7 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, char *filename; int result; + GNUNET_assert (NULL != st); if (0 != curl_global_init (CURL_GLOBAL_WIN32)) { GNUNET_break (0); @@ -1510,11 +1500,11 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, } GNUNET_free (filename); } - GNUNET_STATISTICS_get (stats, "hostlist", - gettext_noop - ("# milliseconds between hostlist downloads"), - GNUNET_TIME_UNIT_MINUTES, &primary_task, &process_stat, - NULL); + sget = GNUNET_STATISTICS_get (stats, "hostlist", + gettext_noop + ("# milliseconds between hostlist downloads"), + GNUNET_TIME_UNIT_MINUTES, &primary_task, &process_stat, + NULL); return GNUNET_OK; } @@ -1526,32 +1516,39 @@ void GNUNET_HOSTLIST_client_stop () { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist client shutdown\n"); -#if DEBUG_HOSTLIST_CLIENT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist client shutdown\n"); -#endif + if (NULL != sget) + { + GNUNET_STATISTICS_get_cancel (sget); + sget = NULL; + } + stats = NULL; if (GNUNET_YES == stat_learning) save_hostlist_file (GNUNET_YES); - if (ti_saving_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (ti_saving_task); + ti_saving_task = GNUNET_SCHEDULER_NO_TASK; } if (ti_download_dispatcher_task != GNUNET_SCHEDULER_NO_TASK) - { + { GNUNET_SCHEDULER_cancel (ti_download_dispatcher_task); + ti_download_dispatcher_task = GNUNET_SCHEDULER_NO_TASK; } if (ti_testing_intervall_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (ti_testing_intervall_task); + ti_testing_intervall_task = GNUNET_SCHEDULER_NO_TASK; } if (ti_download != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (ti_download); + ti_download = GNUNET_SCHEDULER_NO_TASK; } if (ti_check_download != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (ti_check_download); + ti_check_download = GNUNET_SCHEDULER_NO_TASK; curl_global_cleanup (); } if (transport != NULL) @@ -1559,7 +1556,6 @@ GNUNET_HOSTLIST_client_stop () GNUNET_TRANSPORT_disconnect (transport); transport = NULL; } - GNUNET_assert (NULL == transport); GNUNET_free_non_null (proxy); proxy = NULL; cfg = NULL; diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c index 8e79ace..af46110 100644 --- a/src/hostlist/hostlist-server.c +++ b/src/hostlist/hostlist-server.c @@ -32,7 +32,6 @@ #include "gnunet-daemon-hostlist.h" #include "gnunet_resolver_service.h" -#define DEBUG_HOSTLIST_SERVER GNUNET_EXTRA_LOGGING /** * Handle to the HTTP server as provided by libmicrohttpd for IPv6. @@ -89,6 +88,18 @@ static struct GNUNET_PEERINFO_IteratorContext *pitr; */ static struct GNUNET_PEERINFO_Handle *peerinfo; +/** + * Set if we are allowed to advertise our hostlist to others. + */ +static int advertising; + +/** + * Buffer for the hostlist address + */ +static char *hostlist_uri; + + + /** * Context for host processor. */ @@ -99,15 +110,6 @@ struct HostSet char *data; }; -/** - * Set if we are allowed to advertise our hostlist to others. - */ -static int advertising; - -/** - * Buffer for the hostlist address - */ -static char *hostlist_uri; /** @@ -116,17 +118,15 @@ static char *hostlist_uri; static void finish_response (struct HostSet *results) { - if (response != NULL) + if (NULL != response) MHD_destroy_response (response); -#if DEBUG_HOSTLIST_SERVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating hostlist response with %u bytes\n", (unsigned int) results->size); -#endif response = MHD_create_response_from_data (results->size, results->data, MHD_YES, MHD_NO); - if ((daemon_handle_v4 == NULL) && (daemon_handle_v6 == NULL)) + if ((NULL == daemon_handle_v4) && (NULL == daemon_handle_v6)) { MHD_destroy_response (response); response = NULL; @@ -176,7 +176,7 @@ host_processor (void *cls, const struct GNUNET_PeerIdentity *peer, size_t s; int has_addr; - if (err_msg != NULL) + if (NULL != err_msg) { GNUNET_assert (NULL == peer); pitr = NULL; @@ -185,13 +185,13 @@ host_processor (void *cls, const struct GNUNET_PeerIdentity *peer, err_msg); return; } - if (peer == NULL) + if (NULL == peer) { pitr = NULL; finish_response (results); return; } - if (hello == NULL) + if (NULL == hello) return; has_addr = GNUNET_NO; GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_has_addr, &has_addr); @@ -208,11 +208,9 @@ host_processor (void *cls, const struct GNUNET_PeerIdentity *peer, } old = results->size; s = GNUNET_HELLO_size (hello); -#if DEBUG_HOSTLIST_SERVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u bytes of `%s' from peer `%s' for hostlist.\n", (unsigned int) s, "HELLO", GNUNET_i2s (peer)); -#endif if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) || (old + s >= MAX_BYTES_PER_HOSTLISTS)) { @@ -222,11 +220,9 @@ host_processor (void *cls, const struct GNUNET_PeerIdentity *peer, s, GNUNET_NO); return; /* too large, skip! */ } -#if DEBUG_HOSTLIST_SERVER GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Adding peer `%s' to hostlist (%u bytes)\n", GNUNET_i2s (peer), (unsigned int) s); -#endif GNUNET_array_grow (results->data, results->size, old + s); memcpy (&results->data[old], hello, s); } @@ -242,10 +238,8 @@ accept_policy_callback (void *cls, const struct sockaddr *addr, { if (NULL == response) { -#if DEBUG_HOSTLIST_SERVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received request for hostlist, but I am not yet ready; rejecting!\n"); -#endif return MHD_NO; } return MHD_YES; /* accept all */ @@ -276,12 +270,10 @@ access_handler_callback (void *cls, struct MHD_Connection *connection, if (NULL == *con_cls) { (*con_cls) = &dummy; -#if DEBUG_HOSTLIST_SERVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Sending 100 CONTINUE reply\n")); -#endif return MHD_YES; /* send 100 continue */ } - if (*upload_data_size != 0) + if (0 != *upload_data_size) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Refusing `%s' request with %llu bytes of upload data\n"), @@ -292,7 +284,7 @@ access_handler_callback (void *cls, struct MHD_Connection *connection, GNUNET_YES); return MHD_NO; /* do not support upload data */ } - if (response == NULL) + if (NULL == response) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ @@ -320,13 +312,12 @@ static size_t adv_transmit_ready (void *cls, size_t size, void *buf) { static uint64_t hostlist_adv_count; - size_t transmission_size; size_t uri_size; /* Including \0 termination! */ struct GNUNET_MessageHeader header; char *cbuf; - if (buf == NULL) + if (NULL == buf) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed, buffer invalid!\n"); @@ -370,7 +361,7 @@ connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer, if (!advertising) return; - if (hostlist_uri == NULL) + if (NULL == hostlist_uri) return; size = strlen (hostlist_uri) + 1; if (size + sizeof (struct GNUNET_MessageHeader) >= @@ -411,6 +402,7 @@ disconnect_handler (void *cls, const struct GNUNET_PeerIdentity *peer) /* nothing to do */ } + /** * PEERINFO calls this function to let us know about a possible peer * that we might want to connect to. @@ -426,23 +418,22 @@ process_notify (void *cls, const struct GNUNET_PeerIdentity *peer, { struct HostSet *results; -#if DEBUG_HOSTLIST_SERVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peerinfo is notifying us to rebuild our hostlist\n"); -#endif - if (err_msg != NULL) - { + if (NULL != err_msg) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Error in communication with PEERINFO service\n")); - /* return; */ - } + _("Error in communication with PEERINFO service: %s\n"), + err_msg); + if (NULL != pitr) + return; /* re-build already in progress ... */ results = GNUNET_malloc (sizeof (struct HostSet)); - GNUNET_assert (peerinfo != NULL); + GNUNET_assert (NULL != peerinfo); pitr = GNUNET_PEERINFO_iterate (peerinfo, NULL, GNUNET_TIME_UNIT_MINUTES, &host_processor, results); } + /** * Function that queries MHD's select sets and * starts the task waiting for them. @@ -490,7 +481,7 @@ prepare_daemon (struct MHD_Daemon *daemon_handle) struct GNUNET_NETWORK_FDSet *wws; struct GNUNET_NETWORK_FDSet *wes; int max; - unsigned long long timeout; + unsigned MHD_LONG_LONG timeout; int haveto; struct GNUNET_TIME_Relative tv; @@ -512,7 +503,7 @@ prepare_daemon (struct MHD_Daemon *daemon_handle) GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, - GNUNET_SCHEDULER_NO_TASK, tv, wrs, wws, + tv, wrs, wws, &run_daemon, daemon_handle); GNUNET_NETWORK_fdset_destroy (wrs); GNUNET_NETWORK_fdset_destroy (wws); @@ -521,7 +512,6 @@ prepare_daemon (struct MHD_Daemon *daemon_handle) } - /** * Start server offering our hostlist. * @@ -537,7 +527,13 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, { unsigned long long port; char *hostname; + char *ip; size_t size; + struct in_addr i4; + struct in6_addr i6; + struct sockaddr_in v4; + struct sockaddr_in6 v6; + const struct sockaddr *sa; advertising = advertise; if (!advertising) @@ -549,7 +545,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, cfg = c; stats = st; peerinfo = GNUNET_PEERINFO_connect (cfg); - if (peerinfo == NULL) + if (NULL == peerinfo) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not access PEERINFO service. Exiting.\n")); @@ -559,7 +555,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, GNUNET_CONFIGURATION_get_value_number (cfg, "HOSTLIST", "HTTPPORT", &port)) return GNUNET_SYSERR; - if ((port == 0) || (port > UINT16_MAX)) + if ((0 == port) || (port > UINT16_MAX)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Invalid port number %llu. Exiting.\n"), port); @@ -589,11 +585,52 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, } GNUNET_free (hostname); } - daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 -#if DEBUG_HOSTLIST_SERVER - | MHD_USE_DEBUG + + if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIP")) + { + GNUNET_break (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", + "BINDTOIP", &ip)); + } + else + ip = NULL; + if (NULL != ip) + { + if (1 == inet_pton (AF_INET, ip, &i4)) + { + memset (&v4, 0, sizeof (v4)); + v4.sin_family = AF_INET; + v4.sin_addr = i4; + v4.sin_port = htons (port); +#if HAVE_SOCKADDR_IN_SIN_LEN + v4.sin_len = sizeof (v4); #endif - , (unsigned short) port, + sa = (const struct sockaddr *) &v4; + } + else if (1 == inet_pton (AF_INET6, ip, &i6)) + { + memset (&v6, 0, sizeof (v6)); + v6.sin6_family = AF_INET6; + v6.sin6_addr = i6; + v6.sin6_port = htons (port); +#if HAVE_SOCKADDR_IN_SIN_LEN + v6.sin6_len = sizeof (v6); +#endif + sa = (const struct sockaddr *) &v6; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("`%s' is not a valid IP address! Ignoring BINDTOIP.\n"), + ip); + sa = NULL; + } + } + else + sa = NULL; + + daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 | MHD_USE_DEBUG, + (uint16_t) port, &accept_policy_callback, NULL, &access_handler_callback, NULL, MHD_OPTION_CONNECTION_LIMIT, @@ -603,12 +640,12 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, MHD_OPTION_CONNECTION_MEMORY_LIMIT, - (size_t) (16 * 1024), MHD_OPTION_END); - daemon_handle_v4 = MHD_start_daemon (MHD_NO_FLAG -#if DEBUG_HOSTLIST_SERVER - | MHD_USE_DEBUG -#endif - , (unsigned short) port, + (size_t) (16 * 1024), + MHD_OPTION_SOCK_ADDR, + sa, + MHD_OPTION_END); + daemon_handle_v4 = MHD_start_daemon (MHD_NO_FLAG | MHD_USE_DEBUG, + (uint16_t) port, &accept_policy_callback, NULL, &access_handler_callback, NULL, MHD_OPTION_CONNECTION_LIMIT, @@ -618,9 +655,12 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, MHD_OPTION_CONNECTION_MEMORY_LIMIT, - (size_t) (16 * 1024), MHD_OPTION_END); + (size_t) (16 * 1024), + MHD_OPTION_SOCK_ADDR, + sa, + MHD_OPTION_END); - if ((daemon_handle_v6 == NULL) && (daemon_handle_v4 == NULL)) + if ((NULL == daemon_handle_v6) && (NULL == daemon_handle_v4)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not start hostlist HTTP server on port %u\n"), @@ -629,34 +669,26 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, } core = co; - *server_ch = &connect_handler; *server_dh = &disconnect_handler; - if (daemon_handle_v4 != NULL) hostlist_task_v4 = prepare_daemon (daemon_handle_v4); if (daemon_handle_v6 != NULL) hostlist_task_v6 = prepare_daemon (daemon_handle_v6); - notify = GNUNET_PEERINFO_notify (cfg, process_notify, NULL); + notify = GNUNET_PEERINFO_notify (cfg, &process_notify, NULL); return GNUNET_OK; } + /** * Stop server offering our hostlist. */ void GNUNET_HOSTLIST_server_stop () { -#if DEBUG_HOSTLIST_SERVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n"); -#endif - if (NULL != notify) - { - GNUNET_PEERINFO_notify_cancel (notify); - notify = NULL; - } if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6) { GNUNET_SCHEDULER_cancel (hostlist_task_v6); @@ -667,11 +699,6 @@ GNUNET_HOSTLIST_server_stop () GNUNET_SCHEDULER_cancel (hostlist_task_v4); hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK; } - if (pitr != NULL) - { - GNUNET_PEERINFO_iterate_cancel (pitr); - pitr = NULL; - } if (NULL != daemon_handle_v4) { MHD_stop_daemon (daemon_handle_v4); @@ -682,12 +709,22 @@ GNUNET_HOSTLIST_server_stop () MHD_stop_daemon (daemon_handle_v6); daemon_handle_v6 = NULL; } - if (response != NULL) + if (NULL != response) { MHD_destroy_response (response); response = NULL; } - if (peerinfo != NULL) + if (NULL != notify) + { + GNUNET_PEERINFO_notify_cancel (notify); + notify = NULL; + } + if (NULL != pitr) + { + GNUNET_PEERINFO_iterate_cancel (pitr); + pitr = NULL; + } + if (NULL != peerinfo) { GNUNET_PEERINFO_disconnect (peerinfo); peerinfo = NULL; diff --git a/src/hostlist/hostlist.conf b/src/hostlist/hostlist.conf index b13e1e5..f7c1be3 100644 --- a/src/hostlist/hostlist.conf +++ b/src/hostlist/hostlist.conf @@ -7,8 +7,9 @@ CONFIG = $DEFAULTCONFIG BINARY = gnunet-daemon-hostlist # consider having "-e" as default as well once implemented OPTIONS = -b -SERVERS = http://v9.gnunet.org:58080/ http://ioerror.gnunet.org:65535/ +SERVERS = http://v9.gnunet.org/hostlist http://ioerror.gnunet.org:65535/ # proxy for downloading hostlists HTTP-PROXY = - +# bind hostlist http server to a specific IPv4 or IPv6 +# BINDTOIP = diff --git a/src/hostlist/learning_data.conf b/src/hostlist/learning_data.conf index e3a3897..4252f25 100644 --- a/src/hostlist/learning_data.conf +++ b/src/hostlist/learning_data.conf @@ -6,9 +6,3 @@ SERVERS = http://gnunet.org:8080/ PORT = 23354 HOSTNAME = localhost -[datastore] -AUTOSTART = YES - -[fs] -AUTOSTART = YES - diff --git a/src/hostlist/test_gnunet_daemon_hostlist.c b/src/hostlist/test_gnunet_daemon_hostlist.c index da3ab8b..f13f86d 100644 --- a/src/hostlist/test_gnunet_daemon_hostlist.c +++ b/src/hostlist/test_gnunet_daemon_hostlist.c @@ -142,9 +142,6 @@ setup_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); @@ -168,7 +165,7 @@ waitpid_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); @@ -213,9 +210,6 @@ check () { char *const argv[] = { "test-gnunet-daemon-hostlist", "-c", "test_gnunet_daemon_hostlist_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -239,11 +233,7 @@ main (int argc, char *argv[]) GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist"); GNUNET_log_setup ("test-gnunet-daemon-hostlist", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); diff --git a/src/hostlist/test_gnunet_daemon_hostlist_learning.c b/src/hostlist/test_gnunet_daemon_hostlist_learning.c index 9ef8812..08ab0de 100644 --- a/src/hostlist/test_gnunet_daemon_hostlist_learning.c +++ b/src/hostlist/test_gnunet_daemon_hostlist_learning.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -18,7 +18,7 @@ Boston, MA 02111-1307, USA. */ /** - * @file hostlist/test_gnunet_daemon_hostlist.c + * @file hostlist/test_gnunet_daemon_hostlist_learning.c * @brief test for gnunet_daemon_hostslist.c * @author Christian Grothoff */ @@ -30,8 +30,6 @@ #include "gnunet_resolver_service.h" #include "gnunet_statistics_service.h" -#define VERBOSE GNUNET_NO - #define START_ARM GNUNET_YES #define MAX_URL_LEN 1000 @@ -109,6 +107,16 @@ shutdown_testcase () GNUNET_STATISTICS_get_cancel (advsent_stat); advsent_stat = NULL; } + if (NULL != adv_peer.stats) + { + GNUNET_STATISTICS_destroy (adv_peer.stats, GNUNET_NO); + adv_peer.stats = NULL; + } + if (NULL != learn_peer.stats) + { + GNUNET_STATISTICS_destroy (learn_peer.stats, GNUNET_NO); + learn_peer.stats = NULL; + } if (check_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (check_task); @@ -146,7 +154,7 @@ shutdown_testcase () GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait (adv_peer.arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); - GNUNET_OS_process_close (adv_peer.arm_proc); + GNUNET_OS_process_destroy (adv_peer.arm_proc); adv_peer.arm_proc = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Killing hostlist client ARM process.\n"); @@ -154,7 +162,7 @@ shutdown_testcase () GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait (learn_peer.arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); - GNUNET_OS_process_close (learn_peer.arm_proc); + GNUNET_OS_process_destroy (learn_peer.arm_proc); learn_peer.arm_proc = NULL; #endif GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown complete....\n"); @@ -181,6 +189,14 @@ process_downloads_done (void *cls, int success) } +static void +do_shutdown (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + shutdown_testcase (); +} + + static int process_downloads (void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent) @@ -191,7 +207,9 @@ process_downloads (void *cls, const char *subsystem, const char *name, "Peer has successfully downloaded advertised URI\n"); learned_hostlist_downloaded = GNUNET_YES; if ((learned_hostlist_saved == GNUNET_YES) && (adv_sent == GNUNET_YES)) - shutdown_testcase (); + { + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + } } return GNUNET_OK; } @@ -215,7 +233,9 @@ process_uris_recv (void *cls, const char *subsystem, const char *name, "Peer has successfully saved advertised URI\n"); learned_hostlist_saved = GNUNET_YES; if ((learned_hostlist_downloaded == GNUNET_YES) && (adv_sent == GNUNET_YES)) - shutdown_testcase (); + { + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + } } return GNUNET_OK; } @@ -239,7 +259,9 @@ process_adv_sent (void *cls, const char *subsystem, const char *name, adv_sent = GNUNET_YES; if ((learned_hostlist_downloaded == GNUNET_YES) && (learned_hostlist_saved == GNUNET_YES)) - shutdown_testcase (); + { + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + } } return GNUNET_OK; } @@ -372,9 +394,6 @@ setup_learn_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); @@ -408,9 +427,6 @@ setup_adv_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); @@ -449,9 +465,6 @@ check () char *const argv[] = { "test-gnunet-daemon-hostlist-learning", "-c", "learning_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -505,11 +518,7 @@ main (int argc, char *argv[]) GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); GNUNET_log_setup ("test-gnunet-daemon-hostlist", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); #if !WINDOWS system ("gnunet-peerinfo -s -c test_learning_adv_peer.conf > /dev/null"); diff --git a/src/hostlist/test_gnunet_daemon_hostlist_peer1.conf b/src/hostlist/test_gnunet_daemon_hostlist_peer1.conf index 535b60e..78dde57 100644 --- a/src/hostlist/test_gnunet_daemon_hostlist_peer1.conf +++ b/src/hostlist/test_gnunet_daemon_hostlist_peer1.conf @@ -38,6 +38,7 @@ HOSTLISTFILE = hostlists_peer1.file OPTIONS = -b -p SERVERS = http://localhost:12981/ +[ats] PORT = 12971 UNIXPATH = /tmp/gnunet-p1-service-ats.sock diff --git a/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c b/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c index a991557..ff6e417 100644 --- a/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c +++ b/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c @@ -172,7 +172,7 @@ waitpid_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); diff --git a/src/hostlist/test_hostlist_defaults.conf b/src/hostlist/test_hostlist_defaults.conf index 5772250..c2d0a70 100644 --- a/src/hostlist/test_hostlist_defaults.conf +++ b/src/hostlist/test_hostlist_defaults.conf @@ -60,3 +60,9 @@ AUTOSTART = NO [vpn] AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[lockmanager] +AUTOSTART = NO diff --git a/src/include/Makefile.am b/src/include/Makefile.am index afe4ecb..34a879f 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -51,7 +51,9 @@ gnunetinclude_HEADERS = \ gnunet_hello_lib.h \ gnunet_helper_lib.h \ gnunet_load_lib.h \ + gnunet_lockmanager_service.h \ gnunet_mesh_service.h \ + gnunet_mysql_lib.h \ gnunet_namestore_plugin.h \ gnunet_namestore_service.h \ gnunet_nat_lib.h \ @@ -61,10 +63,12 @@ gnunetinclude_HEADERS = \ gnunet_peer_lib.h \ gnunet_peerinfo_service.h \ gnunet_plugin_lib.h \ + gnunet_postgres_lib.h \ gnunet_program_lib.h \ gnunet_protocols.h \ gnunet_pseudonym_lib.h \ gnunet_resolver_service.h \ + gnunet_regex_lib.h \ gnunet_scheduler_lib.h \ gnunet_server_lib.h \ gnunet_service_lib.h \ @@ -73,7 +77,9 @@ gnunetinclude_HEADERS = \ gnunet_statistics_service.h \ gnunet_stream_lib.h \ gnunet_strings_lib.h \ + gnunet_testbed_service.h \ gnunet_testing_lib.h \ + gnunet_testing_lib-new.h \ gnunet_time_lib.h \ gnunet_transport_service.h \ gnunet_transport_plugin.h \ diff --git a/src/include/Makefile.in b/src/include/Makefile.in index ce91bd7..ac6b874 100644 --- a/src/include/Makefile.in +++ b/src/include/Makefile.in @@ -87,18 +87,22 @@ am__gnunetinclude_HEADERS_DIST = gauger.h gettext.h platform.h plibc.h \ gnunet_dv_service.h gnunet_fragmentation_lib.h \ gnunet_fs_service.h gnunet_getopt_lib.h gnunet_gns_service.h \ gnunet_hello_lib.h gnunet_helper_lib.h gnunet_load_lib.h \ - gnunet_mesh_service.h gnunet_namestore_plugin.h \ + gnunet_lockmanager_service.h gnunet_mesh_service.h \ + gnunet_mysql_lib.h gnunet_namestore_plugin.h \ gnunet_namestore_service.h gnunet_nat_lib.h \ gnunet_network_lib.h gnunet_nse_service.h gnunet_os_lib.h \ gnunet_peer_lib.h gnunet_peerinfo_service.h \ - gnunet_plugin_lib.h gnunet_program_lib.h gnunet_protocols.h \ - gnunet_pseudonym_lib.h gnunet_resolver_service.h \ + gnunet_plugin_lib.h gnunet_postgres_lib.h gnunet_program_lib.h \ + gnunet_protocols.h gnunet_pseudonym_lib.h \ + gnunet_resolver_service.h gnunet_regex_lib.h \ gnunet_scheduler_lib.h gnunet_server_lib.h \ gnunet_service_lib.h gnunet_signal_lib.h gnunet_signatures.h \ gnunet_statistics_service.h gnunet_stream_lib.h \ - gnunet_strings_lib.h gnunet_testing_lib.h gnunet_time_lib.h \ - gnunet_transport_service.h gnunet_transport_plugin.h \ - gnunet_tun_lib.h gnunet_util_lib.h gnunet_vpn_service.h + gnunet_strings_lib.h gnunet_testbed_service.h \ + gnunet_testing_lib.h gnunet_testing_lib-new.h \ + gnunet_time_lib.h gnunet_transport_service.h \ + gnunet_transport_plugin.h gnunet_tun_lib.h gnunet_util_lib.h \ + gnunet_vpn_service.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -212,6 +216,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -245,6 +250,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -409,7 +415,9 @@ gnunetinclude_HEADERS = \ gnunet_hello_lib.h \ gnunet_helper_lib.h \ gnunet_load_lib.h \ + gnunet_lockmanager_service.h \ gnunet_mesh_service.h \ + gnunet_mysql_lib.h \ gnunet_namestore_plugin.h \ gnunet_namestore_service.h \ gnunet_nat_lib.h \ @@ -419,10 +427,12 @@ gnunetinclude_HEADERS = \ gnunet_peer_lib.h \ gnunet_peerinfo_service.h \ gnunet_plugin_lib.h \ + gnunet_postgres_lib.h \ gnunet_program_lib.h \ gnunet_protocols.h \ gnunet_pseudonym_lib.h \ gnunet_resolver_service.h \ + gnunet_regex_lib.h \ gnunet_scheduler_lib.h \ gnunet_server_lib.h \ gnunet_service_lib.h \ @@ -431,7 +441,9 @@ gnunetinclude_HEADERS = \ gnunet_statistics_service.h \ gnunet_stream_lib.h \ gnunet_strings_lib.h \ + gnunet_testbed_service.h \ gnunet_testing_lib.h \ + gnunet_testing_lib-new.h \ gnunet_time_lib.h \ gnunet_transport_service.h \ gnunet_transport_plugin.h \ diff --git a/src/include/block_dns.h b/src/include/block_dns.h index 4c2f1a3..e047779 100644 --- a/src/include/block_dns.h +++ b/src/include/block_dns.h @@ -64,7 +64,7 @@ struct GNUNET_DNS_Record * The descriptor for the service * (a peer may provide more than one service) */ - GNUNET_HashCode service_descriptor GNUNET_PACKED; + GNUNET_HashCode service_descriptor; /** * When does this record expire? diff --git a/src/include/block_gns.h b/src/include/block_gns.h index 4514acf..ffdb294 100644 --- a/src/include/block_gns.h +++ b/src/include/block_gns.h @@ -65,19 +65,14 @@ struct GNSNameRecordBlock { /** - * GNUNET_RSA_Signature using RSA-key generated from the records. - */ - struct GNUNET_CRYPTO_RsaSignature signature; - - /** - * What is being signed and why? + * The public key of the authority */ - struct GNUNET_CRYPTO_RsaSignaturePurpose purpose; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; /** - * The public key of the authority + * GNUNET_RSA_Signature using RSA-key generated from the records. */ - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; + struct GNUNET_CRYPTO_RsaSignature signature; /* number of records that follow */ uint32_t rd_count GNUNET_PACKED; @@ -86,7 +81,6 @@ struct GNSNameRecordBlock /* variable-size GNSRecordBlocks follows here */ - }; GNUNET_NETWORK_STRUCT_END diff --git a/src/include/gnunet_arm_service.h b/src/include/gnunet_arm_service.h index af1c8cd..116bfc5 100644 --- a/src/include/gnunet_arm_service.h +++ b/src/include/gnunet_arm_service.h @@ -111,6 +111,19 @@ enum GNUNET_ARM_ProcessStatus typedef void (*GNUNET_ARM_Callback) (void *cls, enum GNUNET_ARM_ProcessStatus result); +/** + * Callback function invoked when list operation is complete. + * + * @param cls closure + * @param result outcome of the operation (GNUNET_YES if successful) + * @param count number of strings in the list + * @param list list of running services + */ +typedef void (*GNUNET_ARM_List_Callback) (void *cls, + int result, + unsigned int count, + const char *const *list); + /** * Handle for interacting with ARM. @@ -183,6 +196,18 @@ GNUNET_ARM_stop_service (struct GNUNET_ARM_Handle *h, const char *service_name, GNUNET_ARM_Callback cb, void *cb_cls); +/** + * List all running services. + * + * @param h handle to ARM + * @param timeout how long to wait before failing for good + * @param cb callback to invoke when service is ready + * @param cb_cls closure for callback + */ +void +GNUNET_ARM_list_running_services (struct GNUNET_ARM_Handle *h, + struct GNUNET_TIME_Relative timeout, + GNUNET_ARM_List_Callback cb, void *cb_cls); #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h index 858ae1d..aa7a089 100644 --- a/src/include/gnunet_ats_service.h +++ b/src/include/gnunet_ats_service.h @@ -522,6 +522,17 @@ void GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh); +/** + * We would like to reset the address suggestion block time for this + * peer + * + * @param sh handle + * @param peer identity of the peer we want to reset + */ +void +GNUNET_ATS_reset_backoff (struct GNUNET_ATS_SchedulingHandle *sh, + const struct GNUNET_PeerIdentity *peer); + /** * We would like to establish a new connection with a peer. ATS * should suggest a good address to begin with. @@ -552,7 +563,7 @@ GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, * @param addrlen address length * @return location as GNUNET_ATS_Information */ -const struct GNUNET_ATS_Information +struct GNUNET_ATS_Information GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle *sh, const struct sockaddr * addr, socklen_t addrlen); @@ -594,6 +605,7 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, const struct GNUNET_HELLO_Address *address, struct Session *session, int in_use); + /** * A session got destroyed, stop including it as a valid address. * diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h index 60fa938..51da46d 100644 --- a/src/include/gnunet_client_lib.h +++ b/src/include/gnunet_client_lib.h @@ -69,13 +69,10 @@ GNUNET_CLIENT_connect (const char *service_name, * destroyed (unless, of course, there is an error with the server in * which case the message may still be lost). * - * @param sock handle to the service connection - * @param finish_pending_write should a transmission already passed to the - * handle be completed? + * @param client handle to the service connection */ void -GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, - int finish_pending_write); +GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client); /** @@ -106,13 +103,13 @@ typedef void (*GNUNET_CLIENT_ShutdownTask) (void *cls, int reason); /** * Read from the service. * - * @param sock the service + * @param client connection to the service * @param handler function to call with the message * @param handler_cls closure for handler * @param timeout how long to wait until timing out */ void -GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, +GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *client, GNUNET_CLIENT_MessageHandler handler, void *handler_cls, struct GNUNET_TIME_Relative timeout); @@ -128,7 +125,7 @@ struct GNUNET_CLIENT_TransmitHandle; * are free in the transmission buffer. May call the notify * method immediately if enough space is available. * - * @param sock connection to the service + * @param client connection to the service * @param size number of bytes to send * @param timeout after how long should we give up (and call * notify with buf NULL and size 0)? @@ -144,7 +141,7 @@ struct GNUNET_CLIENT_TransmitHandle; * using GNUNET_CONNECTION_notify_transmit_ready_cancel) */ struct GNUNET_CLIENT_TransmitHandle * -GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, +GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client, size_t size, struct GNUNET_TIME_Relative timeout, int auto_retry, @@ -169,7 +166,7 @@ GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle * will be called with a "NULL" response (in which * case the connection should probably be destroyed). * - * @param sock connection to use + * @param client connection to use * @param hdr message to transmit * @param timeout when to give up (for both transmission * and for waiting for a response) @@ -184,7 +181,7 @@ GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle * is already pending */ int -GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, +GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *client, const struct GNUNET_MessageHeader *hdr, struct GNUNET_TIME_Relative timeout, int auto_retry, diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index a1ef4ee..9f77658 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h @@ -140,6 +140,26 @@ */ #define GNUNET_PACKED __attribute__((packed)) +/** + * gcc-ism to get gcc bitfield layout when compiling with -mms-bitfields + */ +#if MINGW +#define GNUNET_GCC_STRUCT_LAYOUT __attribute__((gcc_struct)) +#else +#define GNUNET_GCC_STRUCT_LAYOUT +#endif + +/** + * gcc-ism to force alignment; we use this to align char-arrays + * that may then be cast to 'struct's. See also gcc + * bug #33594. + */ +#ifdef __BIGGEST_ALIGNMENT__ +#define GNUNET_ALIGN __attribute__((aligned (__BIGGEST_ALIGNMENT__))) +#else +#define GNUNET_ALIGN __attribute__((aligned (8))) +#endif + /** * gcc-ism to document unused arguments */ @@ -199,27 +219,25 @@ struct GNUNET_MessageHeader uint16_t type GNUNET_PACKED; }; -GNUNET_NETWORK_STRUCT_END + /** * @brief 512-bit hashcode */ -typedef struct +typedef struct GNUNET_HashCode { uint32_t bits[512 / 8 / sizeof (uint32_t)]; /* = 16 */ } GNUNET_HashCode; -GNUNET_NETWORK_STRUCT_BEGIN - /** * The identity of the host (basically the SHA-512 hashcode of * it's public key). */ struct GNUNET_PeerIdentity { - GNUNET_HashCode hashPubKey GNUNET_PACKED; + GNUNET_HashCode hashPubKey; }; GNUNET_NETWORK_STRUCT_END diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h index f8f302a..0fcb4e0 100644 --- a/src/include/gnunet_configuration_lib.h +++ b/src/include/gnunet_configuration_lib.h @@ -86,6 +86,19 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename); +/** + * Load default configuration. This function will parse the + * defaults from the given defaults_d directory. + * + * @param cfg configuration to update + * @param defaults_d directory with the defaults + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, + const char *defaults_d); + + /** * Parse a configuration file, add all of the options in the * file to the configuration environment. diff --git a/src/include/gnunet_connection_lib.h b/src/include/gnunet_connection_lib.h index 3e48d32..5ee4635 100644 --- a/src/include/gnunet_connection_lib.h +++ b/src/include/gnunet_connection_lib.h @@ -109,10 +109,10 @@ typedef void (*GNUNET_CONNECTION_Receiver) (void *cls, const void *buf, * that the underlying socket or fd should never really be closed. * Used for indicating process death. * - * @param sock the connection to set persistent + * @param connection the connection to set persistent */ void -GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *sock); +GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection); /** * Disable the "CORK" feature for communication with the given socket, @@ -122,17 +122,17 @@ GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *sock); * Used to make sure that the last messages sent through the connection * reach the other side before the process is terminated. * - * @param sock the connection to make flushing and blocking + * @param connection the connection to make flushing and blocking * @return GNUNET_OK on success */ int -GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock); +GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection); /** - * Create a socket handle by boxing an existing OS socket. The OS + * Create a connection handle by boxing an existing OS socket. The OS * socket should henceforth be no longer used directly. - * GNUNET_socket_destroy will close it. + * GNUNET_CONNECTION_destroy will close it. * * @param osSocket existing socket to box * @return the boxed socket handle @@ -142,13 +142,13 @@ GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket); /** - * Create a socket handle by accepting on a listen socket. This + * Create a connection handle by accepting on a listen socket. This * function may block if the listen socket has no connection ready. * * @param access function to use to check if access is allowed * @param access_cls closure for access * @param lsock listen socket - * @return the socket handle, NULL on error (for example, access refused) + * @return the connection handle, NULL on error (for example, access refused) */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, @@ -157,14 +157,14 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, /** - * Create a socket handle by (asynchronously) connecting to a host. + * Create a connection handle by (asynchronously) connecting to a host. * This function returns immediately, even if the connection has not * yet been established. This function only creates TCP connections. * * @param cfg configuration to use * @param hostname name of the host to connect to * @param port port to connect to - * @return the socket handle + * @return the connection handle */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle @@ -173,13 +173,13 @@ GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle /** - * Create a socket handle by connecting to a UNIX domain service. + * Create a connection handle by connecting to a UNIX domain service. * This function returns immediately, even if the connection has not * yet been established. This function only creates UNIX connections. * * @param cfg configuration to use * @param unixpath path to connect to) - * @return the socket handle, NULL on systems without UNIX support + * @return the connection handle, NULL on systems without UNIX support */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct @@ -190,14 +190,14 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct /** - * Create a socket handle by (asynchronously) connecting to a host. + * Create a connection handle by (asynchronously) connecting to a host. * This function returns immediately, even if the connection has not * yet been established. This function only creates TCP connections. * * @param af_family address family to use * @param serv_addr server address * @param addrlen length of server address - * @return the socket handle + * @return the connection handle */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_sockaddr (int af_family, @@ -205,84 +205,77 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family, socklen_t addrlen); /** - * Check if socket is valid (no fatal errors have happened so far). - * Note that a socket that is still trying to connect is considered + * Check if connection is valid (no fatal errors have happened so far). + * Note that a connection that is still trying to connect is considered * valid. * - * @param sock socket to check + * @param connection handle to check * @return GNUNET_YES if valid, GNUNET_NO otherwise */ int -GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *sock); +GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection); /** * Obtain the network address of the other party. * - * @param sock the client to get the address for + * @param connection the client to get the address for * @param addr where to store the address * @param addrlen where to store the length of the address * @return GNUNET_OK on success */ int -GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *sock, +GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection, void **addr, size_t * addrlen); /** - * Close the socket and free associated resources. Pending - * transmissions may be completed or dropped depending on the - * arguments. If a receive call is pending and should - * NOT be completed, 'GNUNET_CONNECTION_receive_cancel' - * should be called explicitly first. + * Close the connection and free associated resources. There must + * not be any pending requests for reading or writing to the + * connection at this time. * - * @param sock socket to destroy - * @param finish_pending_write should pending writes be completed or aborted? - * (this applies to transmissions where the data has already been - * read from the application; all other transmissions should be - * aborted using 'GNUNET_CONNECTION_notify_transmit_ready_cancel'). + * @param connection connection to destroy */ void -GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *sock, - int finish_pending_write); +GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection); /** - * Receive data from the given socket. Note that this function will + * Receive data from the given connection. Note that this function will * call "receiver" asynchronously using the scheduler. It will * "immediately" return. Note that there MUST only be one active - * receive call per socket at any given point in time (so do not + * receive call per connection at any given point in time (so do not * call receive again until the receiver callback has been invoked). * - * @param sock socket handle + * @param connection connection handle * @param max maximum number of bytes to read * @param timeout maximum amount of time to wait * @param receiver function to call with received data * @param receiver_cls closure for receiver */ void -GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *sock, size_t max, +GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t max, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_Receiver receiver, void *receiver_cls); /** - * Cancel receive job on the given socket. Note that the + * Cancel receive job on the given connection. Note that the * receiver callback must not have been called yet in order * for the cancellation to be valid. * - * @param sock socket handle + * @param connection connection handle * @return closure of the original receiver callback closure */ void * -GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock); +GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection); /** - * Function called to notify a client about the socket + * Function called to notify a client about the connection * begin ready to queue more data. "buf" will be - * NULL and "size" zero if the socket was closed for + * NULL and "size" zero if the connection was closed for * writing in the meantime. * * @param cls closure @@ -301,17 +294,17 @@ typedef size_t (*GNUNET_CONNECTION_TransmitReadyNotify) (void *cls, size_t size, struct GNUNET_CONNECTION_TransmitHandle; /** - * Ask the socket to call us once the specified number of bytes + * Ask the connection to call us once the specified number of bytes * are free in the transmission buffer. May call the notify * method immediately if enough space is available. Note that * this function will abort if "size" is greater than * GNUNET_SERVER_MAX_MESSAGE_SIZE. * * Note that "notify" will be called either when enough - * buffer space is available OR when the socket is destroyed. + * buffer space is available OR when the connection is destroyed. * The size parameter given to notify is guaranteed to be * larger or equal to size if the buffer is ready, or zero - * if the socket was destroyed (or at least closed for + * if the connection was destroyed (or at least closed for * writing). Finally, any time before 'notify' is called, a * client may call "notify_transmit_ready_cancel" to cancel * the transmission request. @@ -320,7 +313,7 @@ struct GNUNET_CONNECTION_TransmitHandle; * time. Notify will be run with the same scheduler priority * as that of the caller. * - * @param sock socket + * @param connection connection * @param size number of bytes to send * @param timeout after how long should we give up (and call * notify with buf NULL and size 0)? @@ -330,7 +323,7 @@ struct GNUNET_CONNECTION_TransmitHandle; * NULL if we are already going to notify someone else (busy) */ struct GNUNET_CONNECTION_TransmitHandle * -GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *sock, +GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify @@ -349,16 +342,6 @@ GNUNET_CONNECTION_notify_transmit_ready_cancel (struct *th); -/** - * Configure this connection to ignore shutdown signals. - * - * @param sock socket handle - * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default - */ -void -GNUNET_CONNECTION_ignore_shutdown (struct GNUNET_CONNECTION_Handle *sock, - int do_ignore); - #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h index 75443b6..a78d8cc 100644 --- a/src/include/gnunet_container_lib.h +++ b/src/include/gnunet_container_lib.h @@ -70,7 +70,8 @@ typedef int (*GNUNET_HashCodeIterator) (void *cls, GNUNET_HashCode * next); * * @param filename the name of the file (or the prefix) * @param size the size of the bloom-filter (number of - * bytes of storage space to use) + * bytes of storage space to use); will be rounded up + * to next power of 2 * @param k the number of GNUNET_CRYPTO_hash-functions to apply per * element (number of bits set per element in the set) * @return the bloomfilter @@ -1152,12 +1153,28 @@ GNUNET_CONTAINER_slist_clear (struct GNUNET_CONTAINER_SList *l); * @param l list * @param buf payload buffer to find * @param len length of the payload (number of bytes in buf) + * + * @return GNUNET_YES if found, GNUNET_NO otherwise */ int GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l, const void *buf, size_t len); - +/** + * Check if a list contains a certain element using 'compare' function + * + * @param l list + * @param buf payload buffer to find + * @param len length of the payload (number of bytes in buf) + * @param compare comparison function + * + * @return NULL if the 'buf' could not be found, pointer to the + * list element, if found + */ +void * +GNUNET_CONTAINER_slist_contains2 (const struct GNUNET_CONTAINER_SList *l, + const void *buf, size_t len, + int (*compare)(const void *, const size_t, const void *, const size_t)); /** * Count the elements of a list * @param l list diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h index 1f6c0f3..cb48f41 100644 --- a/src/include/gnunet_core_service.h +++ b/src/include/gnunet_core_service.h @@ -157,8 +157,8 @@ typedef void (*GNUNET_CORE_StartupCallback) (void *cls, * @param cfg configuration to use * @param queue_size size of the per-peer message queue * @param cls closure for the various callbacks that follow (including handlers in the handlers array) - * @param init callback to call on timeout or once we have successfully - * connected to the core service; note that timeout is only meaningful if init is not NULL + * @param init callback to call once we have successfully + * connected to the core service * @param connects function to call on peer connect, can be NULL * @param disconnects function to call on peer disconnect / timeout, can be NULL * @param inbound_notify function to call for all inbound messages, can be NULL @@ -229,8 +229,7 @@ struct GNUNET_CORE_TransmitHandle; * @param cork is corking allowed for this transmission? * @param priority how important is the message? * @param maxdelay how long can the message wait? - * @param target who should receive the message, - * use NULL for this peer (loopback) + * @param target who should receive the message, never NULL (can be this peer's identity for loopback) * @param notify_size how many bytes of buffer space does notify want? * @param notify function to call when buffer space is available; * will be called with NULL on timeout or if the overall queue @@ -292,6 +291,12 @@ GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cb_cls); +/** + * Handle to cancel 'is_peer_connected' test. + */ +struct GNUNET_CORE_ConnectTestHandle; + + /** * Check if the given peer is currently connected and return information * about the session if so. This function is for special cirumstances @@ -300,22 +305,28 @@ GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, * connect/disconnect callbacks from GNUNET_CORE_connect. This * function is NOT part of the 'versioned', 'official' API. * - * FIXME: we should probably make it possible to 'cancel' the - * operation... - * * @param cfg configuration to use * @param peer the specific peer to check for * @param peer_cb function to call with the peer information * @param cb_cls closure for peer_cb - * @return GNUNET_OK if iterating, GNUNET_SYSERR on error + * @return handle to cancel the operation */ -int +struct GNUNET_CORE_ConnectTestHandle * GNUNET_CORE_is_peer_connected (const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_PeerIdentity *peer, + const struct GNUNET_PeerIdentity *peer, GNUNET_CORE_ConnectEventHandler peer_cb, void *cb_cls); +/** + * Abort 'is_connected' test operation. + * + * @param cth handle for operation to cancel + */ +void +GNUNET_CORE_is_peer_connected_cancel (struct GNUNET_CORE_ConnectTestHandle *cth); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 6e37266..777ddd9 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Christian Grothoff (and other contributing authors) + (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -86,7 +86,7 @@ enum GNUNET_CRYPTO_Quality /** - * Length of an RSA KEY (d,e,len), 2048 bit (=256 octests) key d, 2 byte e + * Length of an RSA KEY (n,e,len), 2048 bit (=256 octests) key n, 2 byte e */ #define GNUNET_CRYPTO_RSA_KEY_LENGTH 258 @@ -101,6 +101,32 @@ enum GNUNET_CRYPTO_Quality */ struct GNUNET_CRYPTO_RsaPrivateKey; +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * GNUnet mandates a certain format for the encoding + * of private RSA key information that is provided + * by the RSA implementations. This format is used + * to serialize a private RSA key (typically when + * writing it to disk). + */ +struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded +{ + /** + * Total size of the structure, in bytes, in big-endian! + */ + uint16_t len GNUNET_PACKED; + uint16_t sizen GNUNET_PACKED; /* in big-endian! */ + uint16_t sizee GNUNET_PACKED; /* in big-endian! */ + uint16_t sized GNUNET_PACKED; /* in big-endian! */ + uint16_t sizep GNUNET_PACKED; /* in big-endian! */ + uint16_t sizeq GNUNET_PACKED; /* in big-endian! */ + uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */ + uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */ + /* followed by the actual values */ +}; +GNUNET_NETWORK_STRUCT_END + /** * @brief 0-terminated ASCII encoding of a GNUNET_HashCode. @@ -112,6 +138,26 @@ struct GNUNET_CRYPTO_HashAsciiEncoded + +/** + * @brief 256-bit hashcode + */ +struct GNUNET_CRYPTO_ShortHashCode +{ + uint32_t bits[256 / 8 / sizeof (uint32_t)]; /* = 8 */ +}; + + +/** + * @brief 0-terminated ASCII encoding of a 'struct GNUNET_ShortHashCode'. + */ +struct GNUNET_CRYPTO_ShortHashAsciiEncoded +{ + unsigned char short_encoding[53]; +}; + + + /** * @brief an RSA signature */ @@ -320,6 +366,7 @@ GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n); void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key); + /** * Check that a new session key is well-formed. * @@ -406,7 +453,19 @@ GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block, /** - * Convert ASCII encoding back to GNUNET_CRYPTO_hash + * Convert short hash to ASCII encoding. + * + * @param block the hash code + * @param result where to store the encoding (struct GNUNET_CRYPTO_ShortHashAsciiEncoded can be + * safely cast to char*, a '\\0' termination is set). + */ +void +GNUNET_CRYPTO_short_hash_to_enc (const struct GNUNET_CRYPTO_ShortHashCode * block, + struct GNUNET_CRYPTO_ShortHashAsciiEncoded *result); + + +/** + * Convert ASCII encoding back to a 'GNUNET_HashCode' * * @param enc the encoding * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) @@ -419,15 +478,52 @@ GNUNET_CRYPTO_hash_from_string2 (const char *enc, size_t enclen, /** - * Convert ASCII encoding back to GNUNET_CRYPTO_hash + * Convert ASCII encoding back to a 'struct GNUNET_CRYPTO_ShortHash' + * * @param enc the encoding + * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) * @param result where to store the GNUNET_CRYPTO_hash code * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding */ +int +GNUNET_CRYPTO_short_hash_from_string2 (const char *enc, size_t enclen, + struct GNUNET_CRYPTO_ShortHashCode * result); + + +/** + * Convert ASCII encoding back to GNUNET_HashCode + * + * @param enc the encoding + * @param result where to store the hash code + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ #define GNUNET_CRYPTO_hash_from_string(enc, result) \ GNUNET_CRYPTO_hash_from_string2 (enc, strlen(enc), result) +/** + * Convert ASCII encoding back to a 'struct GNUNET_CRYPTO_ShortHash' + * + * @param enc the encoding + * @param result where to store the GNUNET_CRYPTO_ShortHash + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +#define GNUNET_CRYPTO_short_hash_from_string(enc, result) \ + GNUNET_CRYPTO_short_hash_from_string2 (enc, strlen(enc), result) + + +/** + * Compare function for ShortHashCodes, producing a total ordering + * of all hashcodes. + * + * @param h1 some hash code + * @param h2 some hash code + * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2. + */ +int +GNUNET_CRYPTO_short_hash_cmp (const struct GNUNET_CRYPTO_ShortHashCode * h1, + const struct GNUNET_CRYPTO_ShortHashCode * h2); + /** * Compute the distance between 2 hashcodes. * The computation must be fast, not involve @@ -455,6 +551,42 @@ void GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret); +/** + * Compute short (256-bit) hash of a given block. + * + * @param block the data to hash + * @param size size of the block + * @param ret pointer to where to write the hashcode + */ +void +GNUNET_CRYPTO_short_hash (const void *block, size_t size, + struct GNUNET_CRYPTO_ShortHashCode * ret); + + +/** + * Double short (256-bit) hash to create a long hash. + * + * @param sh short hash to double + * @param dh where to store the (doubled) long hash (not really a hash) + */ +void +GNUNET_CRYPTO_short_hash_double (const struct GNUNET_CRYPTO_ShortHashCode *sh, + struct GNUNET_HashCode *dh); + + +/** + * Truncate doubled short hash back to a short hash. + * + * @param dh doubled short hash to reduce again + * @param sh where to store the short hash + * @return GNUNET_OK on success, GNUNET_SYSERR if this was not a + * doubled short hash + */ +int +GNUNET_CRYPTO_short_hash_from_truncation (const struct GNUNET_HashCode *dh, + struct GNUNET_CRYPTO_ShortHashCode *sh); + + /** * Calculate HMAC of a message (RFC 2104) * @@ -735,6 +867,40 @@ GNUNET_CRYPTO_kdf (void *result, size_t out_len, const void *xts, struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_key_create (void); + +/** + * Convert a public key to a string. + * + * @param pub key to convert + * @return string representing 'pub' + */ +char * +GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub); + + +/** + * Convert a string representing a public key to a public key. + * + * @param enc encoded public key + * @param enclen number of bytes in enc (without 0-terminator) + * @param pub where to store the public key + * @return GNUNET_OK on success + */ +int +GNUNET_CRYPTO_rsa_public_key_from_string (const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub); + + +/** + * Encode the private key in a format suitable for + * storing it into a file. + * @returns encoding of the private key. + * The first 4 bytes give the size of the array, as usual. + */ +struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * +GNUNET_CRYPTO_rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey); + /** * Decode the private key from the data-format back * to the "normal", internal format. @@ -763,6 +929,18 @@ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename); +/** + * Setup a hostkey file for a peer given the name of the + * configuration file (!). This function is used so that + * at a later point code can be certain that reading a + * hostkey is fast (for example in time-dependent testcases). + * + * @param cfg_name name of the configuration file to use + */ +void +GNUNET_CRYPTO_setup_hostkey (const char *cfg_name); + + /** * Deterministically (!) create a private key using only the * given HashCode as input to the PRNG. @@ -869,6 +1047,7 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose, void GNUNET_CRYPTO_random_disable_entropy_gathering (void); + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/include/gnunet_datastore_service.h b/src/include/gnunet_datastore_service.h index b4af0e6..2950832 100644 --- a/src/include/gnunet_datastore_service.h +++ b/src/include/gnunet_datastore_service.h @@ -292,8 +292,8 @@ typedef void (*GNUNET_DATASTORE_DatumProcessor) (void *cls, * @param max_queue_size at what queue size should this request be dropped * (if other requests of higher priority are in the queue) * @param timeout how long to wait at most for a response - * @param proc function to call on each matching value; - * will be called once with a NULL value at the end + * @param proc function to call on a matching value; + * or with a NULL value if no datum matches * @param proc_cls closure for proc * @return NULL if the entry was not queued, otherwise a handle that can be used to * cancel diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h index e533ef2..6606acb 100644 --- a/src/include/gnunet_dht_service.h +++ b/src/include/gnunet_dht_service.h @@ -121,6 +121,28 @@ GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle); /* *************** Standard API: get and put ******************* */ + +/** + * Opaque handle to cancel a PUT operation. + */ +struct GNUNET_DHT_PutHandle; + + +/** + * Type of a PUT continuation. You must not call + * "GNUNET_DHT_disconnect" in this continuation. + * + * @param cls closure + * @param success GNUNET_OK if the PUT was transmitted, + * GNUNET_NO on timeout, + * GNUNET_SYSERR on disconnect from service + * after the PUT message was transmitted + * (so we don't know if it was received or not) + */ +typedef void (*GNUNET_DHT_PutContinuation)(void *cls, + int success); + + /** * Perform a PUT operation storing data in the DHT. * @@ -135,18 +157,37 @@ GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle); * @param exp desired expiration time for the value * @param timeout how long to wait for transmission of this request * @param cont continuation to call when done (transmitting request to service) + * You must not call "GNUNET_DHT_disconnect" in this continuation * @param cont_cls closure for cont + * @return handle to cancel the "PUT" operation, NULL on error + * (size too big) */ -void +struct GNUNET_DHT_PutHandle * GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const GNUNET_HashCode * key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const char *data, struct GNUNET_TIME_Absolute exp, - struct GNUNET_TIME_Relative timeout, GNUNET_SCHEDULER_Task cont, + struct GNUNET_TIME_Relative timeout, + GNUNET_DHT_PutContinuation cont, void *cont_cls); +/** + * Cancels a DHT PUT operation. Note that the PUT request may still + * go out over the network (we can't stop that); However, if the PUT + * has not yet been sent to the service, cancelling the PUT will stop + * this from happening (but there is no way for the user of this API + * to tell if that is the case). The only use for this API is to + * prevent a later call to 'cont' from "GNUNET_DHT_put" (i.e. because + * the system is shutting down). + * + * @param ph put operation to cancel ('cont' will no longer be called) + */ +void +GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph); + + /** * Iterator called on each result obtained for a DHT * operation that expects a reply @@ -179,7 +220,6 @@ typedef void (*GNUNET_DHT_GetIterator) (void *cls, * also "GNUNET_BLOCK_evaluate". * * @param handle handle to the DHT service - * @param timeout how long to wait for transmission of this request to the service * @param type expected type of the response object * @param key the key to look up * @param desired_replication_level estimate of how many @@ -194,7 +234,6 @@ typedef void (*GNUNET_DHT_GetIterator) (void *cls, */ struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, - struct GNUNET_TIME_Relative timeout, enum GNUNET_BLOCK_Type type, const GNUNET_HashCode * key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, @@ -216,37 +255,85 @@ GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle); /* *************** Extended API: monitor ******************* */ +/** + * Handle to monitor requests + */ struct GNUNET_DHT_MonitorHandle; /** - * Callback called on each request going through the DHT. + * Callback called on each GET request going through the DHT. + * + * @param cls Closure. + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the GET path (or NULL if not recorded). + * @param desired_replication_level Desired replication level. + * @param key Key of the requested data. + */ +typedef void (*GNUNET_DHT_MonitorGetCB) (void *cls, + enum GNUNET_DHT_RouteOption options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + const GNUNET_HashCode * key); + +/** + * Callback called on each GET reply going through the DHT. * * @param cls Closure. - * @param mtype Type of the DHT message monitored. - * @param exp When will this value expire. - * @param key Key of the result/request. - * @param get_path Peers on reply path (or NULL if not recorded). + * @param type The type of data in the result. + * @param get_path Peers on GET path (or NULL if not recorded). * @param get_path_length number of entries in get_path. * @param put_path peers on the PUT path (or NULL if not recorded). * @param put_path_length number of entries in get_path. - * @param desired_replication_level Desired replication level. - * @param type Type of the result/request. + * @param exp Expiration time of the data. + * @param key Key of the data. * @param data Pointer to the result data. * @param size Number of bytes in data. */ -typedef void (*GNUNET_DHT_MonitorCB) (void *cls, - uint16_t mtype, - struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity * - get_path, unsigned int get_path_length, - const struct GNUNET_PeerIdentity * - put_path, unsigned int put_path_length, - uint32_t desired_replication_level, - enum GNUNET_DHT_RouteOption options, - enum GNUNET_BLOCK_Type type, - const void *data, - size_t size); +typedef void (*GNUNET_DHT_MonitorGetRespCB) (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_PeerIdentity + *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity + * put_path, + unsigned int put_path_length, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size); + +/** + * Callback called on each PUT request going through the DHT. + * + * @param cls Closure. + * @param options Options, for instance RecordRoute, DemultiplexEverywhere. + * @param type The type of data in the request. + * @param hop_count Hop count so far. + * @param path_length number of entries in path (or 0 if not recorded). + * @param path peers on the PUT path (or NULL if not recorded). + * @param desired_replication_level Desired replication level. + * @param exp Expiration time of the data. + * @param key Key under which data is to be stored. + * @param data Pointer to the data carried. + * @param size Number of bytes in data. + */ +typedef void (*GNUNET_DHT_MonitorPutCB) (void *cls, + enum GNUNET_DHT_RouteOption options, + enum GNUNET_BLOCK_Type type, + uint32_t hop_count, + uint32_t desired_replication_level, + unsigned int path_length, + const struct GNUNET_PeerIdentity *path, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const void *data, + size_t size); /** * Start monitoring the local DHT service. @@ -254,7 +341,9 @@ typedef void (*GNUNET_DHT_MonitorCB) (void *cls, * @param handle Handle to the DHT service. * @param type Type of blocks that are of interest. * @param key Key of data of interest, NULL for all. - * @param cb Callback to process all monitored data. + * @param get_cb Callback to process monitored get messages. + * @param get_resp_cb Callback to process monitored get response messages. + * @param put_cb Callback to process monitored put messages. * @param cb_cls Closure for cb. * * @return Handle to stop monitoring. @@ -263,7 +352,9 @@ struct GNUNET_DHT_MonitorHandle * GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const GNUNET_HashCode *key, - GNUNET_DHT_MonitorCB cb, + GNUNET_DHT_MonitorGetCB get_cb, + GNUNET_DHT_MonitorGetRespCB get_resp_cb, + GNUNET_DHT_MonitorPutCB put_cb, void *cb_cls); diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index 18f5535..d6ec0fe 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h @@ -302,8 +302,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, OFF_T offset, /** - * Get the size of the file (or directory) - * of the given file (in bytes). + * Get the size of the file (or directory) of the given file (in + * bytes). * * @param filename name of the file or directory * @param size set to the size of the file (or, @@ -311,11 +311,13 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, OFF_T offset, * of all sizes of files in the directory) * @param includeSymLinks should symbolic links be * included? - * @return GNUNET_OK on success, GNUNET_SYSERR on error + * @param singleFileMode GNUNET_YES to only get size of one file + * and return GNUNET_SYSERR for directories. + * @return GNUNET_SYSERR on error, GNUNET_OK on success */ int GNUNET_DISK_file_size (const char *filename, uint64_t * size, - int includeSymLinks); + int includeSymLinks, int singleFileMode); /** diff --git a/src/include/gnunet_dnsparser_lib.h b/src/include/gnunet_dnsparser_lib.h index 0c310ba..28cc4c0 100644 --- a/src/include/gnunet_dnsparser_lib.h +++ b/src/include/gnunet_dnsparser_lib.h @@ -128,7 +128,7 @@ struct GNUNET_DNSPARSER_Flags */ unsigned int recursion_available : 1 GNUNET_PACKED; -}; +} GNUNET_GCC_STRUCT_LAYOUT; /** diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index 3eb5892..1f1e60f 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h @@ -1820,7 +1820,11 @@ GNUNET_FS_file_information_create_from_data (struct GNUNET_FS_Handle *h, * @param cls closure * @param offset offset to read from; it is possible * that the caller might need to go backwards - * a bit at times + * a bit at times; set to UINT64_MAX to tell + * the reader that we won't be reading for a while + * (used to close the file descriptor but NOT fully + * clean up the reader's state); in this case, + * a value of '0' for max should be ignored * @param max maximum number of bytes that should be * copied to buf; readers are not allowed * to provide less data unless there is an error; diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h index 2422178..4e040f7 100644 --- a/src/include/gnunet_gns_service.h +++ b/src/include/gnunet_gns_service.h @@ -34,6 +34,7 @@ #define GNUNET_GNS_SERVICE_H #include "gnunet_util_lib.h" +#include "gnunet_dnsparser_lib.h" #include "gnunet_namestore_service.h" #ifdef __cplusplus @@ -55,6 +56,10 @@ struct GNUNET_GNS_Handle; */ struct GNUNET_GNS_LookupHandle; +/** + * Handle to control a shorten operation + */ + /** * Record types * Based on GNUNET_DNSPARSER_TYPEs (standard DNS) @@ -62,30 +67,30 @@ struct GNUNET_GNS_LookupHandle; enum GNUNET_GNS_RecordType { /* Standard DNS */ - GNUNET_GNS_RECORD_TYPE_A = 1, - GNUNET_GNS_RECORD_TYPE_NS = 2, - GNUNET_GNS_RECORD_TYPE_CNAME = 5, - GNUNET_GNS_RECORD_TYPE_SOA = 6, - GNUNET_GNS_RECORD_TYPE_PTR = 12, - GNUNET_GNS_RECORD_MX = 15, - GNUNET_GNS_RECORD_TXT = 16, - GNUNET_GNS_RECORD_AAAA = 28, + GNUNET_GNS_RECORD_TYPE_A = GNUNET_DNSPARSER_TYPE_A, + GNUNET_GNS_RECORD_TYPE_NS = GNUNET_DNSPARSER_TYPE_NS, + GNUNET_GNS_RECORD_TYPE_CNAME = GNUNET_DNSPARSER_TYPE_CNAME, + GNUNET_GNS_RECORD_TYPE_SOA = GNUNET_DNSPARSER_TYPE_SOA, + GNUNET_GNS_RECORD_TYPE_PTR = GNUNET_DNSPARSER_TYPE_PTR, + GNUNET_GNS_RECORD_MX = GNUNET_DNSPARSER_TYPE_MX, + GNUNET_GNS_RECORD_TXT = GNUNET_DNSPARSER_TYPE_TXT, + GNUNET_GNS_RECORD_AAAA = GNUNET_DNSPARSER_TYPE_AAAA, /* GNS specific */ - GNUNET_GNS_RECORD_PKEY = 256 + GNUNET_GNS_RECORD_PKEY = GNUNET_NAMESTORE_TYPE_PKEY, + GNUNET_GNS_RECORD_PSEU = GNUNET_NAMESTORE_TYPE_PSEU, + GNUNET_GNS_RECORD_ANY = GNUNET_NAMESTORE_TYPE_ANY }; /** * Initialize the connection with the GNS service. - * FIXME: Do we need the ht_len? * * @param cfg configuration to use - * @param ht_len size of the internal hash table to use for parallel lookups - * @return NULL on error + * + * @return handle to the GNS service, or NULL on error */ struct GNUNET_GNS_Handle * -GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, - unsigned int ht_len); +GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); /** @@ -100,56 +105,135 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle); /* *************** Standard API: lookup ******************* */ /** - * Iterator called on each result obtained for a GNS + * Iterator called on obtained result for a GNS * lookup * * @param cls closure * @param name "name" of the original lookup - * @param record the records in reply - * @param num_records the number of records in reply + * @param rd_count number of records + * @param rd the records in reply */ -typedef void (*GNUNET_GNS_LookupIterator) (void *cls, - const char * name, - const struct GNUNET_NAMESTORE_RecordData *record, - unsigned int num_records); +typedef void (*GNUNET_GNS_LookupResultProcessor) (void *cls, + uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd); /** - * Perform an asynchronous lookup operation on the GNS. + * Perform an asynchronous lookup operation on the GNS + * in the default zone. * * @param handle handle to the GNS service - * @param timeout how long to wait for transmission of this request to the service - * // FIXME: what happens afterwards? + * @param name the name to look up + * @param type the GNUNET_GNS_RecordType to look for + * @param proc function to call on result + * @param proc_cls closure for processor + * + * @return handle to the queued request + */ +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, + const char * name, + enum GNUNET_GNS_RecordType type, + GNUNET_GNS_LookupResultProcessor proc, + void *proc_cls); + +/** + * Perform an asynchronous lookup operation on the GNS + * in the zone specified by 'zone'. + * * @param handle handle to the GNS service - * @param timeout timeout of request * @param name the name to look up + * @param zone the zone to start the resolution in * @param type the GNUNET_GNS_RecordType to look for - * @param iter function to call on each result - * @param iter_cls closure for iter + * @param proc function to call on result + * @param proc_cls closure for processor * - * @return handle to stop the async lookup + * @return handle to the queued request */ -struct GNUNET_GNS_LookupHandle * -GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, - struct GNUNET_TIME_Relative timeout, +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle, const char * name, + struct GNUNET_CRYPTO_ShortHashCode *zone, enum GNUNET_GNS_RecordType type, - GNUNET_GNS_LookupIterator iter, - void *iter_cls); + GNUNET_GNS_LookupResultProcessor proc, + void *proc_cls); + +/* *************** Standard API: shorten ******************* */ /** - * Stop async GNS lookup. Frees associated resources. + * Processor called on for a name shortening result + * called only once * - * @param lookup_handle lookup operation to stop. + * @param cls closure + * @param short_name the shortened name or NULL if no result + */ +typedef void (*GNUNET_GNS_ShortenResultProcessor) (void *cls, + const char* short_name); + + +/** + * Perform a name shortening operation on the GNS. * - * On return lookup_handle will no longer be valid, caller - * must not use again!!! + * @param handle handle to the GNS service + * @param name the name to look up + * @param proc function to call on result + * @param proc_cls closure for processor + * @return handle to the operation */ -void -GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle); +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, + const char * name, + GNUNET_GNS_ShortenResultProcessor proc, + void *proc_cls); + + +/** + * Perform a name shortening operation on the GNS. + * + * @param handle handle to the GNS service + * @param name the name to look up + * @param zone the zone to start the resolution in + * @param proc function to call on result + * @param proc_cls closure for processor + * @return handle to the operation + */ +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_shorten_zone (struct GNUNET_GNS_Handle *handle, + const char * name, + struct GNUNET_CRYPTO_ShortHashCode *zone, + GNUNET_GNS_ShortenResultProcessor proc, + void *proc_cls); + +/* *************** Standard API: get authority ******************* */ + +/** + * Processor called on for a name shortening result + * called only once + * + * @param cls closure + * @param auth_name the name of the auhtority or NULL + */ +typedef void (*GNUNET_GNS_GetAuthResultProcessor) (void *cls, + const char* short_name); + + +/** + * Perform an authority lookup for a given name. + * + * @param handle handle to the GNS service + * @param name the name to look up authority for + * @param proc function to call on result + * @param proc_cls closure for processor + * @return handle to the operation + */ +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle, + const char * name, + GNUNET_GNS_GetAuthResultProcessor proc, + void *proc_cls); #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/include/gnunet_helper_lib.h b/src/include/gnunet_helper_lib.h index 7115748..9c1bc21 100644 --- a/src/include/gnunet_helper_lib.h +++ b/src/include/gnunet_helper_lib.h @@ -74,6 +74,12 @@ typedef void (*GNUNET_HELPER_Continuation)(void *cls, int result); +/** + * Handle to cancel 'send' + */ +struct GNUNET_HELPER_SendHandle; + + /** * Send an message to the helper. * @@ -82,10 +88,11 @@ typedef void (*GNUNET_HELPER_Continuation)(void *cls, * @param can_drop can the message be dropped if there is already one in the queue? * @param cont continuation to run once the message is out * @param cont_cls closure for 'cont' - * @return GNUNET_YES if the message will be sent - * GNUNET_NO if the message was dropped + * @return NULL if the message was dropped, + * otherwise handle to cancel *cont* (actual transmission may + * not be abortable) */ -int +struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, @@ -93,4 +100,14 @@ GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, void *cont_cls); +/** + * Cancel a 'send' operation. If possible, transmitting the + * message is also aborted, but at least 'cont' won't be + * called. + * + * @param sh operation to cancel + */ +void +GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh); + #endif /* end of include guard: GNUNET_HELPER_LIB_H */ diff --git a/src/include/gnunet_lockmanager_service.h b/src/include/gnunet_lockmanager_service.h new file mode 100644 index 0000000..570cce5 --- /dev/null +++ b/src/include/gnunet_lockmanager_service.h @@ -0,0 +1,165 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file include/gnunet_lockmanager_service.h + * @brief API for the lockmanger service + * @author Sree Harsha Totakura + */ + +#ifndef GNUNET_LOCKMANAGER_SERVICE_H +#define GNUNET_LOCKMANAGER_SERVICE_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +#include "gnunet_configuration_lib.h" + +/** + * Opaque handle for the lockmanager service + */ +struct GNUNET_LOCKMANAGER_Handle; + + +/** + * Connect to the lockmanager service + * + * @param cfg the configuration to use + * + * @return upon success the handle to the service; NULL upon error + */ +struct GNUNET_LOCKMANAGER_Handle * +GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Disconnect from the lockmanager service + * + * @param handle the handle to the lockmanager service + */ +void +GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle); + + +/** + * Enumeration for status + */ +enum GNUNET_LOCKMANAGER_Status + { + /** + * Signifies a successful operation + */ + GNUNET_LOCKMANAGER_SUCCESS = 1, + + /** + * Used to signal that a lock is no longer valid. It must then be released + */ + GNUNET_LOCKMANAGER_RELEASE + }; + + +/** + * This callback will be called when a lock has been successfully acquired or + * when an acquired lock has been lost (happens when the lockmanager service + * crashes/restarts). + * + * @param cls the closure from GNUNET_LOCKMANAGER_lock call + * + * @param domain_name the locking domain of the lock + * + * @param lock the lock for which this status is relevant + * + * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully + * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost + */ +typedef void +(*GNUNET_LOCKMANAGER_StatusCallback) (void *cls, + const char *domain_name, + uint32_t lock, + enum GNUNET_LOCKMANAGER_Status + status); + + +/** + * Opaque handle to locking request + */ +struct GNUNET_LOCKMANAGER_LockingRequest; + + +/** + * Tries to acquire the given lock(even if the lock has been lost) until the + * request is called. If the lock is available the status_cb will be + * called. If the lock is busy then the request is queued and status_cb + * will be called when the lock has been made available and acquired by us. + * + * @param handle the handle to the lockmanager service + * + * @param domain_name name of the locking domain. Clients who want to share + * locks must use the same name for the locking domain. Also the + * domain_name should be selected with the prefix + * "GNUNET__" to avoid domain name collisions. + * + * + * @param lock which lock to lock + * + * @param status_cb the callback for signalling when the lock is acquired and + * when it is lost + * + * @param status_cb_cls the closure to the above callback + * + * @return the locking request handle for this request + */ +struct GNUNET_LOCKMANAGER_LockingRequest * +GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, + const char *domain_name, + uint32_t lock, + GNUNET_LOCKMANAGER_StatusCallback + status_cb, + void *status_cb_cls); + + +/** + * Function to cancel the locking request generated by + * GNUNET_LOCKMANAGER_acquire_lock. If the lock is acquired us then the lock is + * released. GNUNET_LOCKMANAGER_StatusCallback will not be called upon any + * status changes resulting due to this call. + * + * @param request the LockingRequest to cancel + */ +void +GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest + *request); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_LOCKMANAGER_SERVICE_H */ +#endif +/* end of gnunet_lockmanager_service.h */ diff --git a/src/include/gnunet_mysql_lib.h b/src/include/gnunet_mysql_lib.h new file mode 100644 index 0000000..c61bdca --- /dev/null +++ b/src/include/gnunet_mysql_lib.h @@ -0,0 +1,214 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file include/gnunet_mysql_lib.h + * @brief library to help with access to a MySQL database + * @author Christian Grothoff + */ +#ifndef GNUNET_MYSQL_LIB_H +#define GNUNET_MYSQL_LIB_H + +#include "gnunet_util_lib.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Mysql context. + */ +struct GNUNET_MYSQL_Context; + + +/** + * Handle for a prepared statement. + */ +struct GNUNET_MYSQL_StatementHandle; + + +/** + * Type of a callback that will be called for each + * data set returned from MySQL. + * + * @param cls user-defined argument + * @param num_values number of elements in values + * @param values values returned by MySQL + * @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort + */ +typedef int (*GNUNET_MYSQL_DataProcessor) (void *cls, unsigned int num_values, + MYSQL_BIND * values); + + +/** + * Create a mysql context. + * + * @param cfg configuration + * @param section configuration section to use to get MySQL configuration options + * @return the mysql context + */ +struct GNUNET_MYSQL_Context * +GNUNET_MYSQL_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section); + + +/** + * Destroy a mysql context. Also frees all associated prepared statements. + * + * @param mc context to destroy + */ +void +GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc); + + +/** + * Close database connection and all prepared statements (we got a DB + * error). The connection will automatically be re-opened and + * statements will be re-prepared if they are needed again later. + * + * @param mc mysql context + */ +void +GNUNET_MYSQL_statements_invalidate (struct GNUNET_MYSQL_Context *mc); + + +/** + * Get internal handle for a prepared statement. This function should rarely + * be used, and if, with caution! On failures during the interaction with + * the handle, you must call 'GNUNET_MYSQL_statements_invalidate'! + * + * @param mc mysql context + * @param sh prepared statement to introspect + * @return MySQL statement handle, NULL on error + */ +MYSQL_STMT * +GNUNET_MYSQL_statement_get_stmt (struct GNUNET_MYSQL_Context *mc, + struct GNUNET_MYSQL_StatementHandle *sh); + + +/** + * Prepare a statement. Prepared statements are automatically discarded + * when the MySQL context is destroyed. + * + * @param mc mysql context + * @param query query text + * @return prepared statement, NULL on error + */ +struct GNUNET_MYSQL_StatementHandle * +GNUNET_MYSQL_statement_prepare (struct GNUNET_MYSQL_Context *mc, + const char *query); + + +/** + * Run a SQL statement. + * + * @param mc mysql context + * @param sql SQL statement to run + * @return GNUNET_OK on success + * GNUNET_SYSERR if there was a problem + */ +int +GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc, + const char *sql); + + +/** + * Run a prepared SELECT statement. + * + * @param mc mysql context + * @param sh handle to SELECT statment + * @param result_size number of elements in results array + * @param results pointer to already initialized MYSQL_BIND + * array (of sufficient size) for passing results + * @param processor function to call on each result + * @param processor_cls extra argument to processor + * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective + * values (size + buffer-reference for pointers); terminated + * with "-1" + * @return GNUNET_SYSERR on error, otherwise + * the number of successfully affected (or queried) rows + */ +int +GNUNET_MYSQL_statement_run_prepared_select (struct GNUNET_MYSQL_Context *mc, + struct GNUNET_MYSQL_StatementHandle *sh, + unsigned int result_size, MYSQL_BIND * results, + GNUNET_MYSQL_DataProcessor processor, + void *processor_cls, ...); + + +/** + * Run a prepared SELECT statement. + * + * @param mc mysql context + * @param s statement to run + * @param result_size number of elements in results array + * @param results pointer to already initialized MYSQL_BIND + * array (of sufficient size) for passing results + * @param processor function to call on each result + * @param processor_cls extra argument to processor + * @param ap pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective + * values (size + buffer-reference for pointers); terminated + * with "-1" + * @return GNUNET_SYSERR on error, otherwise + * the number of successfully affected (or queried) rows + */ +int +GNUNET_MYSQL_statement_run_prepared_select_va (struct GNUNET_MYSQL_Context *mc, + struct GNUNET_MYSQL_StatementHandle *s, + unsigned int result_size, + MYSQL_BIND * results, + GNUNET_MYSQL_DataProcessor processor, + void *processor_cls, + va_list ap); + + +/** + * Run a prepared statement that does NOT produce results. + * + * @param mc mysql context + * @param sh handle to statment + * @param insert_id NULL or address where to store the row ID of whatever + * was inserted (only for INSERT statements!) + * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective + * values (size + buffer-reference for pointers); terminated + * with "-1" + * @return GNUNET_SYSERR on error, otherwise + * the number of successfully affected rows + */ +int +GNUNET_MYSQL_statement_run_prepared (struct GNUNET_MYSQL_Context *mc, + struct GNUNET_MYSQL_StatementHandle *sh, + unsigned long long *insert_id, ...); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* end of gnunet_mysql_lib.h */ +#endif diff --git a/src/include/gnunet_namestore_plugin.h b/src/include/gnunet_namestore_plugin.h index 5468513..b27867f 100644 --- a/src/include/gnunet_namestore_plugin.h +++ b/src/include/gnunet_namestore_plugin.h @@ -56,7 +56,7 @@ typedef void (*GNUNET_NAMESTORE_RecordIterator) (void *cls, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, struct GNUNET_TIME_Absolute expire, const char *name, - unsigned int rd_count, + unsigned int rd_len, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature); @@ -85,13 +85,13 @@ struct GNUNET_NAMESTORE_PluginFunctions * @param rd array of records with data to store * @param signature signature of the record block, NULL if signature is unavailable (i.e. * because the user queried for a particular record type only) - * @return GNUNET_OK on success + * @return GNUNET_OK on success, else GNUNET_SYSERR */ int (*put_records) (void *cls, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, struct GNUNET_TIME_Absolute expire, const char *name, - unsigned int rd_count, + unsigned int rd_len, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature); @@ -105,7 +105,7 @@ struct GNUNET_NAMESTORE_PluginFunctions * @return GNUNET_OK on success */ int (*remove_records) (void *cls, - const GNUNET_HashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *zone, const char *name); @@ -115,19 +115,36 @@ struct GNUNET_NAMESTORE_PluginFunctions * * @param cls closure (internal context for the plugin) * @param zone hash of public key of the zone, NULL to iterate over all zones - * @param name_hash hash of name, NULL to iterate over all records of the zone + * @param name name as '\0' terminated string, NULL to iterate over all records of the zone * @param offset offset in the list of all matching records * @param iter function to call with the result * @param iter_cls closure for iter * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error */ int (*iterate_records) (void *cls, - const GNUNET_HashCode *zone, - const GNUNET_HashCode *name_hash, + const struct GNUNET_CRYPTO_ShortHashCode *zone, + const char *name, uint64_t offset, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); + /** + * Look for an existing PKEY delegation record for a given public key. + * Returns at most one result to the iterator. + * + * @param cls closure (internal context for the plugin) + * @param zone hash of public key of the zone to look up in, never NULL + * @param value_zone hash of the public key of the target zone (value), never NULL + * @param iter function to call with the result + * @param iter_cls closure for iter + * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error + */ + int (*zone_to_name) (void *cls, + const struct GNUNET_CRYPTO_ShortHashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *value_zone, + GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); + + /** * Delete an entire zone (all records). Not used in normal operation. * @@ -135,7 +152,7 @@ struct GNUNET_NAMESTORE_PluginFunctions * @param zone zone to delete */ void (*delete_zone) (void *cls, - const GNUNET_HashCode *zone); + const struct GNUNET_CRYPTO_ShortHashCode *zone); }; diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h index 8ab2ce8..a484601 100644 --- a/src/include/gnunet_namestore_service.h +++ b/src/include/gnunet_namestore_service.h @@ -43,6 +43,26 @@ extern "C" #endif #endif +/** + * Record type indicating any record/'*' + */ +#define GNUNET_NAMESTORE_TYPE_ANY 0 + +/** + * Record type for GNS zone transfer ("PKEY"). + */ +#define GNUNET_NAMESTORE_TYPE_PKEY 65536 + +/** + * Record type for GNS zone transfer ("PSEU"). + */ +#define GNUNET_NAMESTORE_TYPE_PSEU 65537 + +/** + * Record type for GNS legacy hostnames ("LEHO"). + */ +#define GNUNET_NAMESTORE_TYPE_LEHO 65538 + /** * Entry in the queue. */ @@ -63,6 +83,8 @@ struct GNUNET_NAMESTORE_ZoneIterator; */ #define GNUNET_NAMESTORE_MAX_VALUE_SIZE (63 * 1024) + + /** * Connect to the namestore service. * @@ -90,7 +112,7 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop); * * @param cls closure * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate) - * GNUNET_NO if content was already there + * GNUNET_NO if content was already there or not found * GNUNET_YES (or other positive value) on success * @param emsg NULL on success, otherwise an error message */ @@ -121,7 +143,13 @@ enum GNUNET_NAMESTORE_RecordFlags * This is a private record of this peer and it should * thus not be handed out to other peers. */ - GNUNET_NAMESTORE_RF_PRIVATE = 2 + GNUNET_NAMESTORE_RF_PRIVATE = 2, + + /** + * This record was added by the system + * and is pending user confimation + */ + GNUNET_NAMESTORE_RF_PENDING = 4 }; @@ -168,7 +196,7 @@ struct GNUNET_NAMESTORE_RecordData * @param h handle to the namestore * @param zone_key public key of the zone * @param name name that is being mapped (at most 255 characters long) - * @param expire when does the corresponding block in the DHT expire (until + * @param freshness when does the corresponding block in the DHT expire (until * when should we never do a DHT lookup for the same name again)? * @param rd_count number of entries in 'rd' array * @param rd array of records with data to store @@ -181,7 +209,7 @@ struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, const char *name, - struct GNUNET_TIME_Absolute expire, + struct GNUNET_TIME_Absolute freshness, unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature, @@ -194,6 +222,7 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, * to validate signatures received from the network. * * @param public_key public key of the zone + * @param expire block expiration * @param name name that is being mapped (at most 255 characters long) * @param rd_count number of entries in 'rd' array * @param rd array of records with data to store @@ -202,10 +231,11 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, */ int GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key, - const char *name, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature); + const struct GNUNET_TIME_Absolute freshness, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature); /** @@ -223,11 +253,11 @@ GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinary */ struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_RsaPrivateKey *pkey, - const char *name, - const struct GNUNET_NAMESTORE_RecordData *rd, - GNUNET_NAMESTORE_ContinuationWithStatus cont, - void *cont_cls); + const struct GNUNET_CRYPTO_RsaPrivateKey *pkey, + const char *name, + const struct GNUNET_NAMESTORE_RecordData *rd, + GNUNET_NAMESTORE_ContinuationWithStatus cont, + void *cont_cls); /** @@ -240,7 +270,7 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h, * @param h handle to the namestore * @param pkey private key of the zone * @param name name that is being mapped (at most 255 characters long) - * @param rd record data + * @param rd record data, remove specific record, NULL to remove the name and all records * @param cont continuation to call when done * @param cont_cls closure for cont * @return handle to abort the request @@ -272,9 +302,9 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h, */ typedef void (*GNUNET_NAMESTORE_RecordProcessor) (void *cls, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, - struct GNUNET_TIME_Absolute expire, + struct GNUNET_TIME_Absolute freshness, const char *name, - unsigned int rd_count, + unsigned int rd_len, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature); @@ -295,17 +325,36 @@ typedef void (*GNUNET_NAMESTORE_RecordProcessor) (void *cls, */ struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, - const GNUNET_HashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *zone, const char *name, uint32_t record_type, GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls); +/** + * Look for an existing PKEY delegation record for a given public key. + * Returns at most one result to the processor. + * + * @param h handle to the namestore + * @param zone hash of public key of the zone to look up in, never NULL + * @param value_zone hash of the public key of the target zone (value), never NULL + * @param proc function to call on the matching records, or with + * NULL (rd_count == 0) if there are no matching records + * @param proc_cls closure for proc + * @return a handle that can be used to + * cancel + */ +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h, + const struct GNUNET_CRYPTO_ShortHashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *value_zone, + GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls); + + + /** * Starts a new zone iteration (used to periodically PUT all of our - * records into our DHT). This MUST lock the GNUNET_NAMESTORE_Handle - * for any other calls than GNUNET_NAMESTORE_zone_iterator_next and - * GNUNET_NAMESTORE_zone_iteration_stop. "proc" will be called once + * records into our DHT). "proc" will be called once * immediately, and then again after * "GNUNET_NAMESTORE_zone_iterator_next" is invoked. * @@ -321,7 +370,7 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, */ struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h, - const GNUNET_HashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *zone, enum GNUNET_NAMESTORE_RecordFlags must_have_flags, enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags, GNUNET_NAMESTORE_RecordProcessor proc, @@ -357,6 +406,117 @@ void GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe); + +/* convenience APIs for serializing / deserializing GNS records */ + +/** + * Calculate how many bytes we will need to serialize the given + * records. + * + * @param rd_count number of records in the rd array + * @param rd array of GNUNET_NAMESTORE_RecordData with rd_count elements + * + * @return the required size to serialize + * + */ +size_t +GNUNET_NAMESTORE_records_get_size (unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd); + +/** + * Serialize the given records to the given destination buffer. + * + * @param rd_count number of records in the rd array + * @param rd array of GNUNET_NAMESTORE_RecordData with rd_count elements + * @param dest_size size of the destination array + * @param dest where to write the result + * + * @return the size of serialized records + */ +ssize_t +GNUNET_NAMESTORE_records_serialize (unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + size_t dest_size, + char *dest); + + +/** + * Deserialize the given records to the given destination. + * + * @param len size of the serialized record data + * @param src the serialized record data + * @param rd_count number of records in the rd array + * @param dest where to put the data + * + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_NAMESTORE_records_deserialize (size_t len, + const char *src, + unsigned int rd_count, + struct GNUNET_NAMESTORE_RecordData *dest); + + +/** + * Checks if a name is wellformed + * + * @param name the name to check + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_NAMESTORE_check_name (const char * name); + +/** + * Convert the 'value' of a record to a string. + * + * @param type type of the record + * @param data value in binary encoding + * @param data_size number of bytes in data + * @return NULL on error, otherwise human-readable representation of the value + */ +char * +GNUNET_NAMESTORE_value_to_string (uint32_t type, + const void *data, + size_t data_size); + + +/** + * Convert human-readable version of a 'value' of a record to the binary + * representation. + * + * @param type type of the record + * @param s human-readable string + * @param data set to value in binary encoding (will be allocated) + * @param data_size set to number of bytes in data + * @return GNUNET_OK on success + */ +int +GNUNET_NAMESTORE_string_to_value (uint32_t type, + const char *s, + void **data, + size_t *data_size); + + +/** + * Convert a type name (i.e. "AAAA") to the corresponding number. + * + * @param typename name to convert + * @return corresponding number, UINT32_MAX on error + */ +uint32_t +GNUNET_NAMESTORE_typename_to_number (const char *typename); + + +/** + * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A") + * + * @param type number of a type to convert + * @return corresponding typestring, NULL on error + */ +const char * +GNUNET_NAMESTORE_number_to_typename (uint32_t type); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/include/gnunet_nat_lib.h b/src/include/gnunet_nat_lib.h index 6c1db80..3a1e9a6 100644 --- a/src/include/gnunet_nat_lib.h +++ b/src/include/gnunet_nat_lib.h @@ -117,8 +117,11 @@ GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, const void *addr, * * @param h handle (used for configuration) * @param sa the address of the peer (IPv4-only) + * + * @return GNUNET_SYSERR on error, GNUNET_NO if nat client is disabled, + * GNUNET_OK otherwise */ -void +int GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, const struct sockaddr_in *sa); diff --git a/src/include/gnunet_network_lib.h b/src/include/gnunet_network_lib.h index a14d5f0..085845a 100644 --- a/src/include/gnunet_network_lib.h +++ b/src/include/gnunet_network_lib.h @@ -373,6 +373,26 @@ int GNUNET_NETWORK_get_fd (struct GNUNET_NETWORK_Handle *desc); +/** + * Return the sockaddr for this network handle + * + * @param desc wrapper to process + * @return POSIX file descriptor + */ +struct sockaddr* +GNUNET_NETWORK_get_addr (struct GNUNET_NETWORK_Handle *desc); + + +/** + * Return sockaddr length for this network handle + * + * @param desc wrapper to process + * @return socklen_t for sockaddr + */ +socklen_t +GNUNET_NETWORK_get_addrlen (struct GNUNET_NETWORK_Handle *desc); + + /** * Copy a native fd set * @param to destination diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h index e9e484f..67b6cce 100644 --- a/src/include/gnunet_os_lib.h +++ b/src/include/gnunet_os_lib.h @@ -227,7 +227,7 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig); * @param proc pointer to process structure */ void -GNUNET_OS_process_close (struct GNUNET_OS_Process *proc); +GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc); /** @@ -364,7 +364,8 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls, /** - * Retrieve the status of a process. Nonblocking version. + * Retrieve the status of a process, waiting on him if dead. + * Nonblocking version. * * @param proc pointer to process structure * @param type status type diff --git a/src/include/gnunet_peerinfo_service.h b/src/include/gnunet_peerinfo_service.h index 12264fb..49ba916 100644 --- a/src/include/gnunet_peerinfo_service.h +++ b/src/include/gnunet_peerinfo_service.h @@ -58,7 +58,6 @@ struct GNUNET_PEERINFO_Handle * GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); - /** * Disconnect from the peerinfo service. Note that all iterators must * have completed or have been cancelled by the time this function is @@ -72,6 +71,22 @@ void GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h); +/** + * Continuation called with a status result. + * + * @param cls closure + * @param emsg error message, NULL on success + */ +typedef void (*GNUNET_PEERINFO_Continuation)(void *cls, + const char *emsg); + + +/** + * Opaque handle to cancel 'add' operation. + */ +struct GNUNET_PEERINFO_AddContext; + + /** * Add a host to the persistent list. This method operates in * semi-reliable mode: if the transmission is not completed by @@ -82,10 +97,29 @@ GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h); * * @param h handle to the peerinfo service * @param hello the verified (!) HELLO message + * @param cont continuation to call when done, NULL is allowed + * @param cont_cls closure for 'cont' + * @return handle to cancel add operation; all pending + * 'add' operations will be cancelled automatically + * on disconnect, so it is not necessary to keep this + * handle (unless 'cont' is NULL and at some point + * calling 'cont' must be prevented) */ -void +struct GNUNET_PEERINFO_AddContext * GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h, - const struct GNUNET_HELLO_Message *hello); + const struct GNUNET_HELLO_Message *hello, + GNUNET_PEERINFO_Continuation cont, + void *cont_cls); + + +/** + * Cancel pending 'add' operation. Must only be called before + * either 'cont' or 'GNUNET_PEERINFO_disconnect' are invoked. + * + * @param ac handle for the add operation to cancel + */ +void +GNUNET_PEERINFO_add_peer_cancel (struct GNUNET_PEERINFO_AddContext *ac); /** diff --git a/src/include/gnunet_postgres_lib.h b/src/include/gnunet_postgres_lib.h new file mode 100644 index 0000000..559793d --- /dev/null +++ b/src/include/gnunet_postgres_lib.h @@ -0,0 +1,163 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file include/gnunet_postgres_lib.h + * @brief library to help with access to a Postgres database + * @author Christian Grothoff + */ +#ifndef GNUNET_POSTGRES_LIB_H +#define GNUNET_POSTGRES_LIB_H + +#include "gnunet_util_lib.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Check if the result obtained from Postgres has + * the desired status code. If not, log an error, clear the + * result and return GNUNET_SYSERR. + * + * @param dbh database handle + * @param ret return value from database operation to check + * @param expected_status desired status + * @param command description of the command that was run + * @param args arguments given to the command + * @param filename name of the source file where the command was run + * @param line line number in the source file + * @return GNUNET_OK if the result is acceptable + */ +int +GNUNET_POSTGRES_check_result_ (PGconn *dbh, PGresult * ret, int expected_status, + const char *command, const char *args, + const char *filename, int line); + + +/** + * Check if the result obtained from Postgres has + * the desired status code. If not, log an error, clear the + * result and return GNUNET_SYSERR. + * + * @param dbh database handle + * @param ret return value from database operation to check + * @param expected_status desired status + * @param command description of the command that was run + * @param args arguments given to the command + * @return GNUNET_OK if the result is acceptable + */ +#define GNUNET_POSTGRES_check_result(dbh,ret,expected_status,command,args) GNUNET_POSTGRES_check_result_(dbh,ret,expected_status,command,args,__FILE__,__LINE__) + + +/** + * Run simple SQL statement (without results). + * + * @param dbh database handle + * @param sql statement to run + * @param filename filename for error reporting + * @param line code line for error reporting + * @return GNUNET_OK on success + */ +int +GNUNET_POSTGRES_exec_ (PGconn *dbh, const char *sql, const char *filename, int line); + + +/** + * Run simple SQL statement (without results). + * + * @param dbh database handle + * @param sql statement to run + * @return GNUNET_OK on success + */ +#define GNUNET_POSTGRES_exec(dbh,sql) GNUNET_POSTGRES_exec_(dbh,sql,__FILE__,__LINE__) + + +/** + * Prepare SQL statement. + * + * @param dbh database handle + * @param name name for the prepared SQL statement + * @param sql SQL code to prepare + * @param nparms number of parameters in sql + * @param filename filename for error reporting + * @param line code line for error reporting + * @return GNUNET_OK on success + */ +int +GNUNET_POSTGRES_prepare_ (PGconn *dbh, const char *name, const char *sql, + int nparms, + const char *filename, int line); + + +/** + * Prepare SQL statement. + * + * @param dbh database handle + * @param name name for the prepared SQL statement + * @param sql SQL code to prepare + * @param nparams number of parameters in sql + * @return GNUNET_OK on success + */ +#define GNUNET_POSTGRES_prepare(dbh,name,sql,nparams) GNUNET_POSTGRES_prepare_(dbh,name,sql,nparams,__FILE__,__LINE__) + + +/** + * Connect to a postgres database + * + * @param cfg configuration + * @param section configuration section to use to get Postgres configuration options + * @return the postgres handle + */ +PGconn * +GNUNET_POSTGRES_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section); + + +/** + * Delete the row identified by the given rowid (qid + * in postgres). + * + * @param dbh database handle + * @param stmt name of the prepared statement + * @param rowid which row to delete + * @return GNUNET_OK on success + */ +int +GNUNET_POSTGRES_delete_by_rowid (PGconn *dbh, + const char *stmt, + uint32_t rowid); + + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* end of gnunet_postgres_lib.h */ +#endif diff --git a/src/include/gnunet_program_lib.h b/src/include/gnunet_program_lib.h index 48d5280..fa96ecf 100644 --- a/src/include/gnunet_program_lib.h +++ b/src/include/gnunet_program_lib.h @@ -53,6 +53,28 @@ typedef void (*GNUNET_PROGRAM_Main) (void *cls, char *const *args, cfg); +/** + * Run a standard GNUnet command startup sequence (initialize loggers + * and configuration, parse options). + * + * @param argc number of command line arguments + * @param argv command line arguments + * @param binaryName our expected name + * @param binaryHelp help text for the program + * @param options command line options + * @param task main function to run + * @param task_cls closure for task + * @param run_without_scheduler GNUNET_NO start the scheduler, GNUNET_YES do not + * start the scheduler just run the main task + * @return GNUNET_SYSERR on error, GNUNET_OK on success + */ +int +GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, + const char *binaryHelp, + const struct GNUNET_GETOPT_CommandLineOption *options, + GNUNET_PROGRAM_Main task, void *task_cls, + int run_without_scheduler); + /** * Run a standard GNUnet command startup sequence (initialize loggers * and configuration, parse options). diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index dd7c7fe..b655f08 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -87,6 +87,15 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_ARM_RESULT 11 +/** + * Request to ARM to list all currently running services + */ +#define GNUNET_MESSAGE_TYPE_ARM_LIST 12 + +/** + * Response from ARM for listing currently running services + */ +#define GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT 13 /******************************************************************************* * HELLO message types @@ -119,15 +128,18 @@ extern "C" ******************************************************************************/ /** - * Type of messages between the gnunet-wlan-helper and the daemon - * + * Type of data messages from the plugin to the gnunet-wlan-helper */ -#define GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA 40 +#define GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER 39 /** - * Control messages between the gnunet-wlan-helper and the daemon + * Type of data messages from the gnunet-wlan-helper to the plugin */ +#define GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER 40 +/** + * Control message between the gnunet-wlan-helper and the daemon (with the MAC). + */ #define GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL 41 /** @@ -242,12 +254,6 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY 65 -/** - * Notify clients about new peer-to-peer connections (before - * key exchange and authentication). - */ -#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT 66 - /** * Notify clients about new peer-to-peer connections (triggered * after key exchange). @@ -518,25 +524,40 @@ extern "C" #define GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT 148 /** - * Request / receive information about transiting GETs + * Receive information about transiting GETs */ #define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET 149 /** - * Request / receive information about transiting GET responses + * Receive information about transiting GET responses */ #define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP 150 /** - * Request / receive information about transiting PUTs + * Receive information about transiting PUTs */ #define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT 151 /** - * Request / receive information about transiting PUT responses (TODO) + * Receive information about transiting PUT responses (TODO) */ #define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT_RESP 152 +/** + * Request information about transiting messages + */ +#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_START 153 + +/** + * Stop information about transiting messages + */ +#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP 154 + +/** + * Acknowledge receiving PUT request + */ +#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK 155 + /******************************************************************************* * HOSTLIST message types @@ -1007,7 +1028,11 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_IN_USE 351 - +/** + * Type of the 'struct AddressUseMessage' sent by ATS to client + * to confirm that an address is used or not used anymore + */ +#define GNUNET_MESSAGE_TYPE_ATS_RESET_BACKOFF 352 /******************************************************************************* @@ -1260,8 +1285,27 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_NAMESTORE_START 430 +/******************************************************************************* + * LOCKMANAGER message types + ******************************************************************************/ + +/** + * Message to acquire Lock + */ +#define GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE 440 + +/** + * Message to release lock + */ +#define GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE 441 + +/** + * SUCESS reply from lockmanager + */ +#define GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS 442 + /** - * Next available: 440 + * Next available: 450 */ /******************************************************************************* diff --git a/src/include/gnunet_pseudonym_lib.h b/src/include/gnunet_pseudonym_lib.h index bde98ef..8fd938d 100644 --- a/src/include/gnunet_pseudonym_lib.h +++ b/src/include/gnunet_pseudonym_lib.h @@ -44,12 +44,16 @@ extern "C" * * @param cls closure * @param pseudonym hash code of public key of pseudonym + * @param name name of the pseudonym (might be NULL) + * @param unique_name unique name of the pseudonym (might be NULL) * @param md meta data known about the pseudonym * @param rating the local rating of the pseudonym * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort */ typedef int (*GNUNET_PSEUDONYM_Iterator) (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, + const char *unique_name, const struct GNUNET_CONTAINER_MetaData * md, int rating); @@ -110,22 +114,76 @@ GNUNET_PSEUDONYM_discovery_callback_unregister (GNUNET_PSEUDONYM_Iterator iterator, void *closure); /** - * Return the unique, human readable name for the given pseudonym. + * Return unique variant of the namespace name. + * Use after GNUNET_PSEUDONYM_id_to_name() to make sure + * that name is unique. * - * @return NULL on failure (should never happen) + * @param cfg configuration + * @param nsid cryptographic ID of the namespace + * @param name name to uniquify + * @param suffix if not NULL, filled with the suffix value + * @return NULL on failure (should never happen), name on success. + * Free the name with GNUNET_free(). */ char * -GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg, - const GNUNET_HashCode * pseudo); +GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, const char *name, unsigned int *suffix); /** - * Get the pseudonym ID belonging to the given human readable name. + * Get namespace name, metadata and rank + * This is a wrapper around internal read_info() call, and ensures that + * returned data is not invalid (not NULL). + * Writing back information returned by this function will give + * a name "no-name" to pseudonyms that have no name. This side-effect is + * unavoidable, but hardly harmful. * - * @return GNUNET_OK on success + * @param cfg configuration + * @param nsid cryptographic ID of the namespace + * @param ret_meta a location to store metadata pointer. NULL, if metadata + * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy(). + * @param ret_rank a location to store rank. NULL, if rank not needed. + * @param ret_name a location to store human-readable name. Name is not unique. + * NULL, if name is not needed. Free with GNUNET_free(). + * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with + * a duplicate of a "no-name" placeholder + * @return GNUNET_OK on success. GNUENT_SYSERR if the data was + * unobtainable (in that case ret_* are filled with placeholders - + * empty metadata container, rank -1 and a "no-name" name). + */ +int +GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta, + int32_t *ret_rank, char **ret_name, int *name_is_a_dup); + + +/** + * Get the namespace ID belonging to the given namespace name. + * + * @param cfg configuration to use + * @param ns_uname unique (!) human-readable name for the namespace + * @param nsid set to namespace ID based on 'ns_uname' + * @return GNUNET_OK on success, GNUNET_SYSERR on failure */ int GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *hname, GNUNET_HashCode * psid); + const char *ns_uname, GNUNET_HashCode * nsid); + +/** + * Set the pseudonym metadata, rank and name. + * + * @param cfg overall configuration + * @param nsid id of the pseudonym + * @param name name to set. Must be the non-unique version of it. + * May be NULL, in which case it erases pseudonym's name! + * @param md metadata to set + * May be NULL, in which case it erases pseudonym's metadata! + * @param rank rank to assign + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int +GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, const char *name, + const struct GNUNET_CONTAINER_MetaData *md, int rank); #if 0 /* keep Emacsens' auto-indent happy */ diff --git a/src/include/gnunet_regex_lib.h b/src/include/gnunet_regex_lib.h new file mode 100644 index 0000000..aec37c1 --- /dev/null +++ b/src/include/gnunet_regex_lib.h @@ -0,0 +1,180 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file include/gnunet_regex_lib.h + * @brief library to parse regular expressions into dfa + * @author Maximilian Szengel + * + */ + +#ifndef GNUNET_REGEX_LIB_H +#define GNUNET_REGEX_LIB_H + +#include "gnunet_util_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * Automaton (NFA/DFA) representation. + */ +struct GNUNET_REGEX_Automaton; + +/** + * Edge representation. + */ +struct GNUNET_REGEX_Edge +{ + /** + * Label of the edge. + */ + const char *label; + + /** + * Destionation of the edge. + */ + GNUNET_HashCode destination; +}; + +/** + * Construct an NFA by parsing the regex string of length 'len'. + * + * @param regex regular expression string. + * @param len length of the string. + * + * @return NFA, needs to be freed using GNUNET_REGEX_destroy_automaton. + */ +struct GNUNET_REGEX_Automaton * +GNUNET_REGEX_construct_nfa (const char *regex, const size_t len); + +/** + * Construct DFA for the given 'regex' of length 'len'. + * + * @param regex regular expression string. + * @param len length of the regular expression. + * + * @return DFA, needs to be freed using GNUNET_REGEX_destroy_automaton. + */ +struct GNUNET_REGEX_Automaton * +GNUNET_REGEX_construct_dfa (const char *regex, const size_t len); + +/** + * Free the memory allocated by constructing the GNUNET_REGEX_Automaton. + * data structure. + * + * @param a automaton to be destroyed. + */ +void +GNUNET_REGEX_automaton_destroy (struct GNUNET_REGEX_Automaton *a); + +/** + * Save the given automaton as a GraphViz dot file. + * + * @param a the automaton to be saved. + * @param filename where to save the file. + */ +void +GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a, + const char *filename); + +/** + * Evaluates the given 'string' against the given compiled regex. + * + * @param a automaton. + * @param string string to check. + * + * @return 0 if string matches, non 0 otherwise. + */ +int +GNUNET_REGEX_eval (struct GNUNET_REGEX_Automaton *a, + const char *string); + +/** + * Get the first key for the given 'input_string'. This hashes + * the first x bits of the 'input_strings'. + * + * @param input_string string. + * @param string_len length of the 'input_string'. + * @param key pointer to where to write the hash code. + * + * @return number of bits of 'input_string' that have been consumed + * to construct the key + */ +unsigned int +GNUNET_REGEX_get_first_key (const char *input_string, unsigned int string_len, + GNUNET_HashCode * key); + +/** + * Check if the given 'proof' matches the given 'key'. + * + * @param proof partial regex + * @param key hash + * + * @return GNUNET_OK if the proof is valid for the given key + */ +int +GNUNET_REGEX_check_proof (const char *proof, + const GNUNET_HashCode *key); + +/** + * Iterator callback function. + * + * @param cls closure. + * @param key hash for current state. + * @param proof proof for current state. + * @param accepting GNUNET_YES if this is an accepting state, GNUNET_NO if not. + * @param num_edges number of edges leaving current state. + * @param edges edges leaving current state. + */ +typedef void (*GNUNET_REGEX_KeyIterator)(void *cls, + const GNUNET_HashCode *key, + const char *proof, + int accepting, + unsigned int num_edges, + const struct GNUNET_REGEX_Edge *edges); + +/** + * Iterate over all edges starting from start state of automaton 'a'. Calling + * iterator for each edge. + * + * @param a automaton. + * @param iterator iterator called for each edge. + * @param iterator_cls closure. + */ +void +GNUNET_REGEX_iterate_all_edges (struct GNUNET_REGEX_Automaton *a, + GNUNET_REGEX_KeyIterator iterator, + void *iterator_cls); + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* end of gnunet_regex_lib.h */ +#endif + diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h index e16ccc5..4727534 100644 --- a/src/include/gnunet_scheduler_lib.h +++ b/src/include/gnunet_scheduler_lib.h @@ -238,7 +238,7 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls); * scheduled AFTER this call may still be delayed arbitrarily. */ void -GNUNET_SCHEDULER_shutdown (); +GNUNET_SCHEDULER_shutdown (void); /** @@ -308,26 +308,6 @@ GNUNET_SCHEDULER_add_continuation_with_priority (GNUNET_SCHEDULER_Task task, voi enum GNUNET_SCHEDULER_Priority priority); -/** - * Schedule a new task to be run after the specified prerequisite task - * has completed. It will be run with DEFAULT priority. - * - * * @param prerequisite_task run this task after the task with the given - * task identifier completes (and any of our other - * conditions, such as delay, read or write-readiness - * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency - * on completion of other tasks (this will cause the task to run as - * soon as possible). - * @param task main function of the task - * @param task_cls closure of task - * @return unique task identifier for the job - * only valid until "task" is started! - */ -GNUNET_SCHEDULER_TaskIdentifier -GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_TaskIdentifier prerequisite_task, - GNUNET_SCHEDULER_Task task, void *task_cls); - - /** * Schedule a new task to be run with a specified priority. * @@ -431,6 +411,30 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_Task task, void *task_cls); +/** + * Schedule a new task to be run with a specified priority and to be + * run after the specified delay or when the specified file descriptor + * is ready for reading. The delay can be used as a timeout on the + * socket being ready. The task will be scheduled for execution once + * either the delay has expired or the socket operation is ready. It + * will be run with the DEFAULT priority. + * + * @param delay when should this operation time out? Use + * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown" + * @param priority priority to use for the task + * @param rfd read file-descriptor + * @param task main function of the task + * @param task_cls closure of task + * @return unique task identifier for the job + * only valid until "task" is started! + */ +GNUNET_SCHEDULER_TaskIdentifier +GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay, + enum GNUNET_SCHEDULER_Priority priority, + struct GNUNET_NETWORK_Handle *rfd, + GNUNET_SCHEDULER_Task task, void *task_cls); + + /** * Schedule a new task to be run with a specified delay or when the * specified file descriptor is ready for writing. The delay can be @@ -511,12 +515,7 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, * || shutdown-active) * * - * * @param prio how important is this task? - * @param prerequisite_task run this task after the task with the given - * task identifier completes (and any of our other - * conditions, such as delay, read or write-readiness - * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency - * on completion of other tasks. + * @param prio how important is this task? * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever", * which means that the task will only be run after we receive SIGTERM * @param rs set of file descriptors we want to read (can be NULL) @@ -527,8 +526,7 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, * only valid until "task" is started! */ GNUNET_SCHEDULER_TaskIdentifier -GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, - GNUNET_SCHEDULER_TaskIdentifier prerequisite_task, +GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h index 7fb8ae7..73fe800 100644 --- a/src/include/gnunet_server_lib.h +++ b/src/include/gnunet_server_lib.h @@ -55,12 +55,16 @@ extern "C" */ struct GNUNET_SERVER_Handle; - /** * @brief opaque handle for a client of the server */ struct GNUNET_SERVER_Client; +/** + * @brief opaque handle server returns for aborting transmission to a client. + */ +struct GNUNET_SERVER_TransmitHandle; + /** * Functions with this signature are called whenever a message is @@ -150,13 +154,23 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls, int require_found); +/** + * Stop the listen socket and get ready to shutdown the server + * once only 'monitor' clients are left. + * + * @param server server to stop listening on + */ +void +GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server); + + /** * Free resources held by this server. * - * @param s server to destroy + * @param server server to destroy */ void -GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s); +GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server); /** @@ -190,10 +204,10 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, * @param callback_cls closure for callback * @return non-NULL if the notify callback was queued; can be used * to cancel the request using - * GNUNET_CONNECTION_notify_transmit_ready_cancel. + * GNUNET_SERVER_notify_transmit_ready_cancel. * NULL if we are already going to notify someone else (busy) */ -struct GNUNET_CONNECTION_TransmitHandle * +struct GNUNET_SERVER_TransmitHandle * GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, size_t size, struct GNUNET_TIME_Relative timeout, @@ -201,6 +215,31 @@ GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, callback, void *callback_cls); +/** + * Abort transmission request. + * + * @param th request to abort + */ +void +GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th); + + +/** + * Set the 'monitor' flag on this client. Clients which have been + * marked as 'monitors' won't prevent the server from shutting down + * once 'GNUNET_SERVER_stop_listening' has been invoked. The idea is + * that for "normal" clients we likely want to allow them to process + * their requests; however, monitor-clients are likely to 'never' + * disconnect during shutdown and thus will not be considered when + * determining if the server should continue to exist after + * 'GNUNET_SERVER_destroy' has been called. + * + * @param client the client to set the 'monitor' flag on + */ +void +GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client); + + /** * Set the persistent flag on this client, used to setup client connection * to only be killed when the service it's connected to is actually dead. @@ -210,6 +249,7 @@ GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, void GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client); + /** * Resume receiving from this client, we are done processing the * current request. This function must be called from within each @@ -239,14 +279,6 @@ GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client, struct GNUNET_TIME_Relative timeout); -/** - * Set if a client should finish a pending write when disconnecting. - */ -void -GNUNET_SERVER_client_set_finish_pending_write (struct GNUNET_SERVER_Client *client, - int finish); - - /** * Disable the warning the server issues if a message is not acknowledged * in a timely fashion. Use this call if a client is intentionally delayed @@ -391,22 +423,6 @@ void GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client); -/** - * Configure this server's connections to continue handling client - * requests as usual even after we get a shutdown signal. The change - * only applies to clients that connect to the server from the outside - * using TCP after this call. Clients managed previously or those - * added using GNUNET_SERVER_connect_socket and - * GNUNET_SERVER_connect_callback are not affected by this option. - * - * @param h server handle - * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default - */ -void -GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, int do_ignore); - - - /** * Disable the "CORK" feature for communication with the given client, * forcing the OS to immediately flush the buffer on transmission @@ -591,11 +607,15 @@ struct GNUNET_SERVER_MessageStreamTokenizer; * Functions with this signature are called whenever a * complete message is received by the tokenizer. * + * Do not call GNUNET_SERVER_mst_destroy in callback + * * @param cls closure * @param client identification of the client * @param message the actual message + * + * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing */ -typedef void (*GNUNET_SERVER_MessageTokenizerCallback) (void *cls, void *client, +typedef int (*GNUNET_SERVER_MessageTokenizerCallback) (void *cls, void *client, const struct GNUNET_MessageHeader * message); diff --git a/src/include/gnunet_service_lib.h b/src/include/gnunet_service_lib.h index 1641e0f..39e6a80 100644 --- a/src/include/gnunet_service_lib.h +++ b/src/include/gnunet_service_lib.h @@ -43,7 +43,7 @@ extern "C" * Get the list of addresses that a server for the given service * should bind to. * - * @param serviceName name of the service + * @param service_name name of the service * @param cfg configuration (which specifies the addresses) * @param addrs set (call by reference) to an array of pointers to the * addresses the server should bind to and listen on; the @@ -60,7 +60,7 @@ extern "C" * set to NULL). */ int -GNUNET_SERVICE_get_server_addresses (const char *serviceName, +GNUNET_SERVICE_get_server_addresses (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, struct sockaddr ***addrs, socklen_t ** addr_lens); @@ -85,16 +85,22 @@ typedef void (*GNUNET_SERVICE_Main) (void *cls, */ enum GNUNET_SERVICE_Options { - /** - * Use defaults. - */ + /** + * Use defaults. + */ GNUNET_SERVICE_OPTION_NONE = 0, - /** - * Do not trigger server shutdown on signals, allow for the user - * to terminate the server explicitly when needed. - */ - GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN = 1 + /** + * Do not trigger server shutdown on signals, allow for the user + * to terminate the server explicitly when needed. + */ + GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN = 1, + + /** + * Trigger a SOFT server shutdown on signals, allowing active + * non-monitor clients to complete their transactions. + */ + GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN = 2 }; @@ -104,32 +110,37 @@ enum GNUNET_SERVICE_Options * * @param argc number of command line arguments * @param argv command line arguments - * @param serviceName our service name - * @param opt service options + * @param service_name our service name + * @param options service options * @param task main task of the service * @param task_cls closure for task * @return GNUNET_SYSERR on error, GNUNET_OK * if we shutdown nicely */ int -GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName, - enum GNUNET_SERVICE_Options opt, GNUNET_SERVICE_Main task, +GNUNET_SERVICE_run (int argc, char *const *argv, const char *service_name, + enum GNUNET_SERVICE_Options options, GNUNET_SERVICE_Main task, void *task_cls); +/** + * Opaque handle for a service. + */ struct GNUNET_SERVICE_Context; /** * Run a service startup sequence within an existing * initialized system. * - * @param serviceName our service name + * @param service_name our service name * @param cfg configuration to use + * @param options service options * @return NULL on error, service handle */ struct GNUNET_SERVICE_Context * -GNUNET_SERVICE_start (const char *serviceName, - const struct GNUNET_CONFIGURATION_Handle *cfg); +GNUNET_SERVICE_start (const char *service_name, + const struct GNUNET_CONFIGURATION_Handle *cfg, + enum GNUNET_SERVICE_Options options); /** diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h index 580282d..ee105c6 100644 --- a/src/include/gnunet_signatures.h +++ b/src/include/gnunet_signatures.h @@ -115,6 +115,12 @@ extern "C" */ #define GNUNET_SIGNATURE_PURPOSE_NSE_SEND 14 + +/** + * Signature of a gnunet naming system record block + */ +#define GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN 15 + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/include/gnunet_statistics_service.h b/src/include/gnunet_statistics_service.h index bfd65f8..0515331 100644 --- a/src/include/gnunet_statistics_service.h +++ b/src/include/gnunet_statistics_service.h @@ -145,6 +145,7 @@ struct GNUNET_STATISTICS_GetHandle; * @param timeout after how long should we give up (and call * notify with buf NULL and size 0)? * @param cont continuation to call when done (can be NULL) + * This callback CANNOT destroy the statistics handle in the same call. * @param proc function to call on each value * @param cls closure for proc and cont * @return NULL on error diff --git a/src/include/gnunet_stream_lib.h b/src/include/gnunet_stream_lib.h index 930cc1d..e09c264 100644 --- a/src/include/gnunet_stream_lib.h +++ b/src/include/gnunet_stream_lib.h @@ -62,7 +62,12 @@ enum GNUNET_STREAM_Status /** * A serious error occured while operating on this stream */ - GNUNET_STREAM_SYSERR = 3 + GNUNET_STREAM_SYSERR = 3, + + /** + * An error resulted in an unusable stream + */ + GNUNET_STREAM_BROKEN }; /** @@ -125,18 +130,51 @@ GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg, /** - * Shutdown the stream for reading or writing (man 2 shutdown). + * Handle for shutdown + */ +struct GNUNET_STREAM_ShutdownHandle; + + +/** + * Completion callback for shutdown + * + * @param cls the closure from GNUNET_STREAM_shutdown call + * @param operation the operation that was shutdown (SHUT_RD, SHUT_WR, + * SHUT_RDWR) + */ +typedef void (*GNUNET_STREAM_ShutdownCompletion) (void *cls, + int operation); + + +/** + * Shutdown the stream for reading or writing (similar to man 2 shutdown). * * @param socket the stream socket - * @param how SHUT_RD, SHUT_WR or SHUT_RDWR + * @param operation SHUT_RD, SHUT_WR or SHUT_RDWR + * @param completion_cb the callback that will be called upon successful + * shutdown of given operation + * @param completion_cls the closure for the completion callback + * @return the shutdown handle; NULL in case of any error */ -void +struct GNUNET_STREAM_ShutdownHandle * GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket, - int how); + int operation, + GNUNET_STREAM_ShutdownCompletion completion_cb, + void *completion_cls); + + +/** + * Cancels a pending shutdown + * + * @param handle the shutdown handle returned from GNUNET_STREAM_shutdown + */ +void +GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle); /** - * Closes the stream + * Closes the stream and frees the associated state. The stream should be + * shutdown before closing. * * @param socket the stream socket */ @@ -185,10 +223,10 @@ GNUNET_STREAM_listen (const struct GNUNET_CONFIGURATION_Handle *cfg, /** * Closes the listen socket * - * @param socket the listen socket + * @param lsocket the listen socket */ void -GNUNET_STREAM_listen_close (struct GNUNET_STREAM_ListenSocket *socket); +GNUNET_STREAM_listen_close (struct GNUNET_STREAM_ListenSocket *lsocket); /** @@ -217,15 +255,22 @@ struct GNUNET_STREAM_IOWriteHandle; struct GNUNET_STREAM_IOReadHandle; /** - * Tries to write the given data to the stream + * Tries to write the given data to the stream. The maximum size of data that + * can be written as part of a write operation is (64 * (64000 - sizeof (struct + * GNUNET_STREAM_DataMessage))). If size is greater than this it is not an API + * violation, however only the said number of maximum bytes will be written. * * @param socket the socket representing a stream * @param data the data buffer from where the data is written into the stream * @param size the number of bytes to be written from the data buffer * @param timeout the timeout period - * @param write_cont the function to call upon writing some bytes into the stream + * @param write_cont the function to call upon writing some bytes into the + * stream * @param write_cont_cls the closure - * @return handle to cancel the operation; NULL if a previous write is pending + * + * @return handle to cancel the operation; if a previous write is pending or + * the stream has been shutdown for this operation then write_cont is + * immediately called and NULL is returned. */ struct GNUNET_STREAM_IOWriteHandle * GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, @@ -243,7 +288,7 @@ GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, * @param cls the closure from GNUNET_STREAM_read * @param status the status of the stream at the time this function is called * @param data traffic from the other side - * @param size the number of bytes available in data read + * @param size the number of bytes available in data read; will be 0 on timeout * @return number of bytes of processed from 'data' (any data remaining should be * given to the next time the read processor is called). */ @@ -254,13 +299,16 @@ typedef size_t (*GNUNET_STREAM_DataProcessor) (void *cls, /** - * Tries to read data from the stream + * Tries to read data from the stream. * * @param socket the socket representing a stream * @param timeout the timeout period * @param proc function to call with data (once only) * @param proc_cls the closure for proc - * @return handle to cancel the operation + * + * @return handle to cancel the operation; if the stream has been shutdown for + * this type of opeartion then the DataProcessor is immediately + * called with GNUNET_STREAM_SHUTDOWN as status and NULL if returned */ struct GNUNET_STREAM_IOReadHandle * GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket, @@ -270,12 +318,24 @@ GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket, /** - * Cancel pending write operation. + * Cancels pending write operation. Also cancels packet retransmissions which + * may have resulted otherwise. + * + * CAUTION: Normally a write operation is considered successful if the data + * given to it is sent and acknowledged by the receiver. As data is divided + * into packets, it is possible that not all packets are received by the + * receiver. Any missing packets are then retransmitted till the receiver + * acknowledges all packets or until a timeout . During this scenario if the + * write operation is cancelled all such retransmissions are also + * cancelled. This may leave the receiver's receive buffer incompletely filled + * as some missing packets are never retransmitted. So this operation should be + * used before shutting down transmission from our side or before closing the + * socket. * * @param ioh handle to operation to cancel */ void -GNUNET_STREAM_io_write_cancel (struct GNUNET_STREAM_IOWriteHandle *ioh); +GNUNET_STREAM_io_write_cancel (struct GNUNET_STREAM_IOWriteHandle *iowh); /** @@ -284,7 +344,7 @@ GNUNET_STREAM_io_write_cancel (struct GNUNET_STREAM_IOWriteHandle *ioh); * @param ioh handle to operation to cancel */ void -GNUNET_STREAM_io_read_cancel (struct GNUNET_STREAM_IOReadHandle *ioh); +GNUNET_STREAM_io_read_cancel (struct GNUNET_STREAM_IOReadHandle *iorh); #if 0 diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 8101a81..54d2e30 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h @@ -66,12 +66,12 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, * Convert a given fancy human-readable time to our internal * representation. * - * @param fancy_size human readable string (i.e. 1 minute) + * @param fancy_time human readable string (i.e. 1 minute) * @param rtime set to the relative time * @return GNUNET_OK on success, GNUNET_SYSERR on error */ int -GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_size, +GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, struct GNUNET_TIME_Relative *rtime); @@ -121,6 +121,27 @@ GNUNET_STRINGS_to_utf8 (const char *input, size_t len, const char *charset); char * GNUNET_STRINGS_from_utf8 (const char *input, size_t len, const char *charset); +/** + * Convert the utf-8 input string to lowercase + * Output needs to be allocated appropriately + * + * @param input input string + * @param output output buffer + */ +void +GNUNET_STRINGS_utf8_tolower(const char* input, char** output); + + +/** + * Convert the utf-8 input string to lowercase + * Output needs to be allocated appropriately + * + * @param input input string + * @param output output buffer + */ +void +GNUNET_STRINGS_utf8_toupper(const char* input, char** output); + /** * Complete filename (a la shell) from abbrevition. @@ -213,6 +234,42 @@ GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta); const char * GNUNET_STRINGS_get_short_name (const char *filename); + +/** + * Convert binary data to ASCII encoding. The ASCII encoding is rather + * GNUnet specific. It was chosen such that it only uses characters + * in [0-9A-V], can be produced without complex arithmetics and uses a + * small number of characters. The GNUnet encoding uses 103 characters. + * Does not append 0-terminator, but returns a pointer to the place where + * it should be placed, if needed. + * + * @param data data to encode + * @param size size of data (in bytes) + * @param out buffer to fill + * @param out_size size of the buffer. Must be large enough to hold + * ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5 + * @return pointer to the next byte in 'out' or NULL on error. + */ +char * +GNUNET_STRINGS_data_to_string (const unsigned char *data, size_t size, + char *out, size_t out_size); + + +/** + * Convert ASCII encoding back to data + * out_size must match exactly the size of the data before it was encoded. + * + * @param enc the encoding + * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) + * @param out location where to store the decoded data + * @param out_size sizeof the output buffer + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +int +GNUNET_STRINGS_string_to_data (const char *enc, size_t enclen, + unsigned char *out, size_t out_size); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif @@ -220,6 +277,118 @@ GNUNET_STRINGS_get_short_name (const char *filename); } #endif +enum GNUNET_STRINGS_FilenameCheck +{ + GNUNET_STRINGS_CHECK_EXISTS = 0x00000001, + GNUNET_STRINGS_CHECK_IS_DIRECTORY = 0x00000002, + GNUNET_STRINGS_CHECK_IS_LINK = 0x00000004, + GNUNET_STRINGS_CHECK_IS_ABSOLUTE = 0x00000008 +}; + +/** + * Parse a path that might be an URI. + * + * @param path path to parse. Must be NULL-terminated. + * @param scheme_part a pointer to 'char *' where a pointer to a string that + * represents the URI scheme will be stored. Can be NULL. The string is + * allocated by the function, and should be freed by GNUNET_free() when + * it is no longer needed. + * @param path_part a pointer to 'const char *' where a pointer to the path + * part of the URI will be stored. Can be NULL. Points to the same block + * of memory as 'path', and thus must not be freed. Might point to '\0', + * if path part is zero-length. + * @return GNUNET_YES if it's an URI, GNUNET_NO otherwise. If 'path' is not + * an URI, '* scheme_part' and '*path_part' will remain unchanged + * (if they weren't NULL). + */ +int +GNUNET_STRINGS_parse_uri (const char *path, char **scheme_part, + const char **path_part); + + +/** + * Check whether filename is absolute or not, and if it's an URI + * + * @param filename filename to check + * @param can_be_uri GNUNET_YES to check for being URI, GNUNET_NO - to + * assume it's not URI + * @param r_is_uri a pointer to an int that is set to GNUNET_YES if 'filename' + * is URI and to GNUNET_NO otherwise. Can be NULL. If 'can_be_uri' is + * not GNUNET_YES, *r_is_uri is set to GNUNET_NO. + * @param r_uri_scheme a pointer to a char * that is set to a pointer to URI scheme. + * The string is allocated by the function, and should be freed with + * GNUNET_free (). Can be NULL. + * @return GNUNET_YES if 'filename' is absolute, GNUNET_NO otherwise. + */ +int +GNUNET_STRINGS_path_is_absolute (const char *filename, + int can_be_uri, + int *r_is_uri, + char **r_uri_scheme); + + +/** + * Perform checks on 'filename; + * + * @param filename file to check + * @param checks checks to perform + * @return GNUNET_YES if all checks pass, GNUNET_NO if at least one of them + * fails, GNUNET_SYSERR when a check can't be performed + */ +int +GNUNET_STRINGS_check_filename (const char *filename, + enum GNUNET_STRINGS_FilenameCheck checks); + + +/** + * Tries to convert 'zt_addr' string to an IPv6 address. + * The string is expected to have the format "[ABCD::01]:80". + * + * @param zt_addr 0-terminated string. May be mangled by the function. + * @param addrlen length of zt_addr (not counting 0-terminator). + * @param r_buf a buffer to fill. Initially gets filled with zeroes, + * then its sin6_port, sin6_family and sin6_addr are set appropriately. + * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which + * case the contents of r_buf are undefined. + */ +int +GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, + uint16_t addrlen, + struct sockaddr_in6 *r_buf); + + +/** + * Tries to convert 'zt_addr' string to an IPv4 address. + * The string is expected to have the format "1.2.3.4:80". + * + * @param zt_addr 0-terminated string. May be mangled by the function. + * @param addrlen length of zt_addr (not counting 0-terminator). + * @param r_buf a buffer to fill. + * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which case + * the contents of r_buf are undefined. + */ +int +GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, + uint16_t addrlen, + struct sockaddr_in *r_buf); + + +/** + * Tries to convert 'addr' string to an IP (v4 or v6) address. + * Will automatically decide whether to treat 'addr' as v4 or v6 address. + * + * @param addr a string, may not be 0-terminated. + * @param addrlen number of bytes in addr (if addr is 0-terminated, + * 0-terminator should not be counted towards addrlen). + * @param r_buf a buffer to fill. + * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which + * case the contents of r_buf are undefined. + */ +int +GNUNET_STRINGS_to_address_ip (const char *addr, + uint16_t addrlen, + struct sockaddr_storage *r_buf); + /* ifndef GNUNET_UTIL_STRING_H */ #endif diff --git a/src/include/gnunet_testbed_service.h b/src/include/gnunet_testbed_service.h new file mode 100644 index 0000000..ab8db87 --- /dev/null +++ b/src/include/gnunet_testbed_service.h @@ -0,0 +1,1029 @@ +/* + This file is part of GNUnet + (C) 2008, 2009, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file include/gnunet_testbed_service.h + * @brief API for writing tests and creating large-scale + * emulation testbeds for GNUnet. + * @author Christian Grothoff + */ + +#ifndef GNUNET_TESTBED_SERVICE_H +#define GNUNET_TESTBED_SERVICE_H + +#include "gnunet_util_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Opaque handle to a host running experiments managed by the testbed framework. + * The master process must be able to SSH to this host without password (via + * ssh-agent). + */ +struct GNUNET_TESTBED_Host; + +/** + * Opaque handle to a peer controlled by the testbed framework. A peer runs + * at a particular host. + */ +struct GNUNET_TESTBED_Peer; + +/** + * Opaque handle to an abstract operation to be executed by the testbed framework. + */ +struct GNUNET_TESTBED_Operation; + +/** + * Handle to interact with a GNUnet testbed controller. Each controller has at + * least one master handle which is created when the controller is created; this + * master handle interacts with the controller via stdin/stdout of the controller + * process. Additionally, controllers can interact with each other (in a P2P + * fashion); those links are established via TCP/IP on the controller's service + * port. + */ +struct GNUNET_TESTBED_Controller; + +/** + * Handle to a large-scale testbed that is managed at a high level. + */ +struct GNUNET_TESTBED_Testbed; + + +/** + * Create a host to run peers and controllers on. + * + * @param hostname name of the host, use "NULL" for localhost + * @param username username to use for the login; may be NULL + * @param port port number to use for ssh; use 0 to let ssh decide + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Host * +GNUNET_TESTBED_host_create (const char *hostname, + const char *username, + uint16_t port); + + +/** + * Load a set of hosts from a configuration file. + * + * @param filename file with the host specification + * @param hosts set to the hosts found in the file + * @return number of hosts returned in 'hosts', 0 on error + */ +unsigned int +GNUNET_TESTBED_hosts_load_from_file (const char *filename, + struct GNUNET_TESTBED_Host **hosts); + + +/** + * Destroy a host handle. Must only be called once everything + * running on that host has been stopped. + * + * @param host handle to destroy + */ +void +GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host); + + +/** + * Enumeration with (at most 64) possible event types that + * can be monitored using the testbed framework. + */ +enum GNUNET_TESTBED_EventType +{ + /** + * A peer has been started. + */ + GNUNET_TESTBED_ET_PEER_START = 0, + + /** + * A peer has been stopped. + */ + GNUNET_TESTBED_ET_PEER_STOP = 1, + + /** + * A connection between two peers was established. + */ + GNUNET_TESTBED_ET_CONNECT = 2, + + /** + * A connection between two peers was torn down. + */ + GNUNET_TESTBED_ET_DISCONNECT = 3, + + /** + * A requested testbed operation has been completed. + */ + GNUNET_TESTBED_ET_OPERATION_FINISHED = 4, + + /** + * The 'GNUNET_TESTBED_run' operation has been completed + */ + GNUNET_TESTBED_ET_TESTBED_ONLINE = 5 + +}; + + +/** + * Types of information that can be requested about a peer. + */ +enum GNUNET_TESTBED_PeerInformationType +{ + + /** + * Special value (not valid for requesting information) + * that is used in the event struct if a 'generic' pointer + * is returned (for other operations not related to this + * enumeration). + */ + GNUNET_TESTBED_PIT_GENERIC = 0, + + /** + * What host is the peer running on? Returns a 'const struct + * GNUNET_TESTBED_Host *'. Valid until + * 'GNUNET_TESTBED_operation_done' is called. + */ + GNUNET_TESTBED_PIT_HOST, + + /** + * What configuration is the peer using? Returns a 'const struct + * GNUNET_CONFIGURATION_Handle *'. Valid until + * 'GNUNET_TESTNIG_operation_done' is called. However, the + * values may be inaccurate if the peer is reconfigured in + * the meantime. + */ + GNUNET_TESTBED_PIT_CONFIGURATION, + + /** + * What is the identity of the peer? Returns a + * 'const struct GNUNET_PeerIdentity *'. Valid until + * 'GNUNET_TESTNIG_operation_done' is called. + */ + GNUNET_TESTBED_PIT_IDENTITY + +}; + + +/** + * Argument to GNUNET_TESTBED_ControllerCallback with details about + * the event. + */ +struct GNUNET_TESTBED_EventInformation +{ + + /** + * Type of the event. + */ + enum GNUNET_TESTBED_EventType type; + + /** + * Details about the event. + */ + union + { + + /** + * Details about peer start event. + */ + struct + { + /** + * Handle for the host where the peer + * was started. + */ + struct GNUNET_TESTBED_Host *host; + + /** + * Handle for the peer that was started. + */ + struct GNUNET_TESTBED_Peer *peer; + + } peer_start; + + /** + * Details about peer stop event. + */ + struct + { + + /** + * Handle for the peer that was started. + */ + struct GNUNET_TESTBED_Peer *peer; + + } peer_stop; + + /** + * Details about connect event. + */ + struct + { + /** + * Handle for one of the connected peers. + */ + struct GNUNET_TESTBED_Peer *peer1; + + /** + * Handle for one of the connected peers. + */ + struct GNUNET_TESTBED_Peer *peer2; + + } peer_connect; + + /** + * Details about disconnect event. + */ + struct + { + /** + * Handle for one of the disconnected peers. + */ + struct GNUNET_TESTBED_Peer *peer1; + + /** + * Handle for one of the disconnected peers. + */ + struct GNUNET_TESTBED_Peer *peer2; + + } peer_disconnect; + + /** + * Details about an operation finished event. + */ + struct + { + + /** + * Handle for the operation that was finished. + */ + struct GNUNET_TESTBED_Operation *operation; + + /** + * Closure that was passed in when the event was + * requested. + */ + void *op_cls; + + /** + * Error message for the operation, NULL on success. + */ + const char *emsg; + + /** + * Peer information type; captures which of the types + * in the 'op_result' is actually in use. + */ + enum GNUNET_TESTBED_PeerInformationType pit; + + /** + * Pointer to an operation-specific return value; NULL on error; + * can be NULL for certain operations. Valid until + * 'GNUNET_TESTBED_operation_done' is called. + */ + union + { + /** + * No result (NULL pointer) or generic result + * (whatever the GNUNET_TESTBED_ConnectAdapter returned). + */ + void *generic; + + /** + * Identity of host running the peer. + */ + struct GNUNET_TESTBED_Host *host; + + /** + * Identity of the peer. + */ + const struct GNUNET_PeerIdentity *pid; + + /** + * Configuration of the peer. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + } op_result; + + } operation_finished; + + + /** + * Details about an testbed run completed event. + */ + struct + { + + /** + * Error message for the operation, NULL on success. + */ + const char *emsg; + + /** + * Array of peers now running (valid until + * 'GNUNET_TESTBED_testbed_stop' is called). Note that it is + * not allowed to call 'GNUNET_TESTBED_peer_destroy' on peers + * from this array. + */ + struct GNUNET_TESTBED_Peer **peers; + + /** + * Size of the 'peers' array. + */ + unsigned int num_peers; + + } testbed_run_finished; + + } details; + +}; + + +/** + * Signature of the event handler function called by the + * respective event controller. + * + * @param cls closure + * @param event information about the event + */ +typedef void (*GNUNET_TESTBED_ControllerCallback)(void *cls, + const struct GNUNET_TESTBED_EventInformation *event); + + +/** + * Start a controller process using the given configuration at the + * given host. + * + * @param cfg configuration to use + * @param host host to run the controller on, NULL for 'localhost' + * @param event_mask bit mask with set of events to call 'cc' for; + * or-ed values of "1LL" shifted by the + * respective 'enum GNUNET_TESTBED_EventType' + * (i.e. "(1LL << GNUNET_TESTBED_ET_CONNECT) | ...") + * @param cc controller callback to invoke on events + * @param cc_cls closure for cc + * @return handle to the controller + */ +struct GNUNET_TESTBED_Controller * +GNUNET_TESTBED_controller_start (const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTBED_Host *host, + uint64_t event_mask, + GNUNET_TESTBED_ControllerCallback cc, + void *cc_cls); + + +/** + * Configure shared services at a controller. Using this function, + * you can specify that certain services (such as "resolver") + * should not be run for each peer but instead be shared + * across N peers on the specified host. This function + * must be called before any peers are created at the host. + * + * @param controller controller to configure + * @param service_name name of the service to share + * @param num_peers number of peers that should share one instance + * of the specified service (1 for no sharing is the default), + * use 0 to disable the service + */ +void +GNUNET_TESTBED_controller_configure_sharing (struct GNUNET_TESTBED_Controller *controller, + const char *service_name, + uint32_t num_peers); + + +/** + * Stop the given controller (also will terminate all peers and + * controllers dependent on this controller). This function + * blocks until the testbed has been fully terminated (!). + * + * @param controller handle to controller to stop + */ +void +GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_Controller *controller); + + +/** + * Create a link from a 'master' controller to a slave controller. + * Whenever the master controller is asked to start a peer at the + * given 'delegated_host', it will delegate the request to the + * specified slave controller. Note that the slave controller runs at + * the 'slave_host', which may or may not be the same host as the + * 'delegated_host' (for hierarchical delegations). The configuration + * of the slave controller is given and to be used to either create + * the slave controller or to connect to an existing slave controller + * process. 'is_subordinate' specifies if the given slave controller + * should be started and managed by the master controller, or if the + * slave already has a master and this is just a secondary master that + * is also allowed to use the existing slave. + * + * @param master handle to the master controller who creates the association + * @param delegated_host requests to which host should be delegated + * @param slave_host which host is used to run the slave controller + * @param slave_cfg configuration to use for the slave controller + * @param is_subordinate GNUNET_YES if the slave should be started (and stopped) + * by the master controller; GNUNET_NO if we are just + * allowed to use the slave via TCP/IP + */ +void +GNUNET_TESTBED_controller_link (struct GNUNET_TESTBED_Controller *master, + struct GNUNET_TESTBED_Host *delegated_host, + struct GNUNET_TESTBED_Host *slave_host, + const struct GNUNET_CONFIGURATION_Handle *slave_cfg, + int is_subordinate); + + +/** + * Create the given peer at the specified host using the given + * controller. If the given controller is not running on the target + * host, it should find or create a controller at the target host and + * delegate creating the peer. Explicit delegation paths can be setup + * using 'GNUNET_TESTBED_controller_link'. If no explicit delegation + * path exists, a direct link with a subordinate controller is setup + * for the first delegated peer to a particular host; the subordinate + * controller is then destroyed once the last peer that was delegated + * to the remote host is stopped. + * + * Creating the peer only creates the handle to manipulate and further + * configure the peer; use "GNUNET_TESTBED_peer_start" and + * "GNUNET_TESTBED_peer_stop" to actually start/stop the peer's + * processes. + * + * Note that the given configuration will be adjusted by the + * controller to avoid port/path conflicts with other peers. + * The "final" configuration can be obtained using + * 'GNUNET_TESTBED_peer_get_information'. + * + * @param controller controller process to use + * @param host host to run the peer on + * @param cfg configuration to use for the peer + * @return handle to the peer (actual startup will happen asynchronously) + */ +struct GNUNET_TESTBED_Peer * +GNUNET_TESTBED_peer_create (struct GNUNET_TESTBED_Controller *controller, + struct GNUNET_TESTBED_Host *host, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Start the given peer. + * + * @param peer peer to start + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_start (struct GNUNET_TESTBED_Peer *peer); + + +/** + * Stop the given peer. The handle remains valid (use + * "GNUNET_TESTBED_peer_destroy" to fully clean up the + * state of the peer). + * + * @param peer peer to stop + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_stop (struct GNUNET_TESTBED_Peer *peer); + + +/** + * Request information about a peer. + * + * @param peer peer to request information about + * @param pit desired information + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_get_information (struct GNUNET_TESTBED_Peer *peer, + enum GNUNET_TESTBED_PeerInformationType pit); + + +/** + * Change peer configuration. Must only be called while the + * peer is stopped. Ports and paths cannot be changed this + * way. + * + * @param peer peer to change configuration for + * @param cfg new configuration (differences to existing + * configuration only) + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_update_configuration (struct GNUNET_TESTBED_Peer *peer, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Destroy the given peer; the peer should have been + * stopped first (if it was started). + * + * @param peer peer to stop + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_destroy (struct GNUNET_TESTBED_Peer *peer); + + +/** + * Options for peer connections. + */ +enum GNUNET_TESTBED_ConnectOption +{ + /** + * No option (not valid as an argument). + */ + GNUNET_TESTBED_CO_NONE = 0, + + /** + * Allow or disallow a connection between the specified peers. + * Followed by GNUNET_NO (int) if a connection is disallowed + * or GNUNET_YES if a connection is allowed. Note that the + * default (all connections allowed or disallowed) is + * specified in the configuration of the controller. + */ + GNUNET_TESTBED_CO_ALLOW = 1, + + /** + * FIXME: add (and implement) options to limit connection to + * particular transports, force simulation of particular latencies + * or message loss rates, or set bandwidth limitations. + */ + +}; + + +/** + * Manipulate the P2P underlay topology by configuring a link + * between two peers. + * + * @param op_cls closure argument to give with the operation event + * @param p1 first peer + * @param p2 second peer + * @param co option to change + * @param ap option-specific values + * @return handle to the operation, NULL if configuring the link at this + * time is not allowed + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_underlay_configure_link_va (void *op_cls, + struct GNUNET_TESTBED_Peer *p1, + struct GNUNET_TESTBED_Peer *p2, + enum GNUNET_TESTBED_ConnectOption co, + va_list ap); + + +/** + * Manipulate the P2P underlay topology by configuring a link + * between two peers. + * + * @param op_cls closure argument to give with the operation event + * @param p1 first peer + * @param p2 second peer + * @param co option to change + * @param ... option-specific values + * @return handle to the operation, NULL if configuring the link at this + * time is not allowed + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_underlay_configure_link (void *op_cls, + struct GNUNET_TESTBED_Peer *p1, + struct GNUNET_TESTBED_Peer *p2, + enum GNUNET_TESTBED_ConnectOption co, ...); + + + +/** + * Topologies supported for testbeds. + */ +enum GNUNET_TESTBED_TopologyOption +{ + /** + * A clique (everyone connected to everyone else). No options. + */ + GNUNET_TESTBED_TOPOLOGY_CLIQUE, + + /** + * Small-world network (2d torus plus random links). Followed + * by the number of random links to add (unsigned int). + */ + GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD, + + /** + * Small-world network (ring plus random links). Followed + * by the number of random links to add (unsigned int). + */ + GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING, + + /** + * Ring topology. No options. + */ + GNUNET_TESTBED_TOPOLOGY_RING, + + /** + * 2-d torus. No options. + */ + GNUNET_TESTBED_TOPOLOGY_2D_TORUS, + + /** + * Random graph. Followed by the link density, that is the + * percentage of links present in relation to a clique + * (float). + */ + GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI, + + /** + * Certain percentage of peers are unable to communicate directly + * replicating NAT conditions. Followed by the fraction of + * NAT'ed peers (float). + */ + GNUNET_TESTBED_TOPOLOGY_INTERNAT, + + /** + * Scale free topology. FIXME: options? + */ + GNUNET_TESTBED_TOPOLOGY_SCALE_FREE, + + /** + * Straight line topology. No options. + */ + GNUNET_TESTBED_TOPOLOGY_LINE, + + /** + * All peers are disconnected. No options. + */ + GNUNET_TESTBED_TOPOLOGY_NONE, + + /** + * Read a topology from a given file. Followed by the name of the file (const char *). + */ + GNUNET_TESTBED_TOPOLOGY_FROM_FILE +}; + + +/** + * Configure overall network topology to have a particular shape. + * + * @param op_cls closure argument to give with the operation event + * @param num_peers number of peers in 'peers' + * @param peers array of 'num_peers' with the peers to configure + * @param topo desired underlay topology to use + * @param ap topology-specific options + * @return handle to the operation, NULL if configuring the topology + * is not allowed at this time + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_underlay_configure_topology_va (void *op_cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + enum GNUNET_TESTBED_TopologyOption topo, + va_list ap); + + +/** + * Configure overall network topology to have a particular shape. + * + * @param op_cls closure argument to give with the operation event + * @param num_peers number of peers in 'peers' + * @param peers array of 'num_peers' with the peers to configure + * @param topo desired underlay topology to use + * @param ... topology-specific options + * @return handle to the operation, NULL if configuring the topology + * is not allowed at this time + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_underlay_configure_topology (void *op_cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + enum GNUNET_TESTBED_TopologyOption topo, + ...); + + +/** + * Both peers must have been started before calling this function. + * This function then obtains a HELLO from 'p1', gives it to 'p2' + * and asks 'p2' to connect to 'p1'. + * + * @param op_cls closure argument to give with the operation event + * @param p1 first peer + * @param p2 second peer + * @return handle to the operation, NULL if connecting these two + * peers is fundamentally not possible at this time (peers + * not running or underlay disallows) + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_overlay_connect (void *op_cls, + struct GNUNET_TESTBED_Peer *p1, + struct GNUNET_TESTBED_Peer *p2); + + +/** + * All peers must have been started before calling this function. + * This function then connects the given peers in the P2P overlay + * using the given topology. + * + * @param op_cls closure argument to give with the operation event + * @param num_peers number of peers in 'peers' + * @param peers array of 'num_peers' with the peers to configure + * @param topo desired underlay topology to use + * @param va topology-specific options + * @return handle to the operation, NULL if connecting these + * peers is fundamentally not possible at this time (peers + * not running or underlay disallows) + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer *peers, + enum GNUNET_TESTBED_TopologyOption topo, + va_list va); + + +/** + * All peers must have been started before calling this function. + * This function then connects the given peers in the P2P overlay + * using the given topology. + * + * @param op_cls closure argument to give with the operation event + * @param num_peers number of peers in 'peers' + * @param peers array of 'num_peers' with the peers to configure + * @param topo desired underlay topology to use + * @param ... topology-specific options + * @return handle to the operation, NULL if connecting these + * peers is fundamentally not possible at this time (peers + * not running or underlay disallows) + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_overlay_configure_topology (void *op_cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer *peers, + enum GNUNET_TESTBED_TopologyOption topo, + ...); + + + +/** + * Ask the testbed controller to write the current overlay topology to + * a file. Naturally, the file will only contain a snapshot as the + * topology may evolve all the time. + * + * @param controller overlay controller to inspect + * @param filename name of the file the topology should + * be written to. + */ +void +GNUNET_TESTBED_overlay_write_topology_to_file (struct GNUNET_TESTBED_Controller *controller, + const char *filename); + + +/** + * Adapter function called to establish a connection to + * a service. + * + * @param cls closure + * @param cfg configuration of the peer to connect to + * @return service handle to return in 'op_result', NULL on error + */ +typedef void * (*GNUNET_TESTBED_ConnectAdapter)(void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Adapter function called to destroy a connection to + * a service. + * + * @param cls closure + * @param op_result service handle returned from the connect adapter + */ +typedef void (*GNUNET_TESTBED_DisconnectAdapter)(void *cls, + void *op_result); + + +/** + * Connect to a service offered by the given peer. Will ensure that + * the request is queued to not overwhelm our ability to create and + * maintain connections with other systems. The actual service + * handle is then returned via the 'op_result' member in the event + * callback. The 'ca' callback is used to create the connection + * when the time is right; the 'da' callback will be used to + * destroy the connection (upon 'GNUNET_TESTBED_operation_done'). + * 'GNUNET_TESTBED_operation_cancel' can be used to abort this + * operation until the event callback has been called. + * + * @param op_cls closure to pass in operation event + * @param peer peer that runs the service + * @param service_name name of the service to connect to + * @param ca helper function to establish the connection + * @param da helper function to close the connection + * @param cada_cls closure for ca and da + * @return handle for the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_service_connect (void *op_cls, + struct GNUNET_TESTBED_Peer *peer, + const char *service_name, + GNUNET_TESTBED_ConnectAdapter ca, + GNUNET_TESTBED_DisconnectAdapter da, + void *cada_cls); + + +/** + * Cancel a pending operation. Releases all resources + * of the operation and will ensure that no event + * is generated for the operation. Does NOT guarantee + * that the operation will be fully undone (or that + * nothing ever happened). + * + * @param operation operation to cancel + */ +void +GNUNET_TESTBED_operation_cancel (struct GNUNET_TESTBED_Operation *operation); + + +/** + * Signal that the information from an operation has been fully + * processed. This function MUST be called for each event + * of type 'operation_finished' to fully remove the operation + * from the operation queue. After calling this function, the + * 'op_result' becomes invalid (!). + * + * @param operation operation to signal completion for + */ +void +GNUNET_TESTBED_operation_done (struct GNUNET_TESTBED_Operation *operation); + + +/** + * Configure and run a testbed using the given + * master controller on 'num_hosts' starting + * 'num_peers' using the given peer configuration. + * + * @param controller master controller for the testbed + * (must not be destroyed until after the + * testbed is destroyed). + * @param num_hosts number of hosts in 'hosts', 0 to only + * use 'localhost' + * @param hosts list of hosts to use for the testbed + * @param num_peers number of peers to start + * @param peer_cfg peer configuration template to use + * @param underlay_topology underlay topology to create + * @param va topology-specific options + * @return handle to the testbed + */ +struct GNUNET_TESTBED_Testbed * +GNUNET_TESTBED_create_va (struct GNUNET_TESTBED_Controller *controller, + unsigned int num_hosts, + struct GNUNET_TESTBED_Host **hosts, + unsigned int num_peers, + const struct GNUNET_CONFIGURATION_Handle *peer_cfg, + enum GNUNET_TESTBED_TopologyOption underlay_topology, + va_list va); + + +/** + * Configure and run a testbed using the given + * master controller on 'num_hosts' starting + * 'num_peers' using the given peer configuration. + * + * @param controller master controller for the testbed + * (must not be destroyed until after the + * testbed is destroyed). + * @param num_hosts number of hosts in 'hosts', 0 to only + * use 'localhost' + * @param hosts list of hosts to use for the testbed + * @param num_peers number of peers to start + * @param peer_cfg peer configuration template to use + * @param underlay_topology underlay topology to create + * @param ... topology-specific options + */ +struct GNUNET_TESTBED_Testbed * +GNUNET_TESTBED_create (struct GNUNET_TESTBED_Controller *controller, + unsigned int num_hosts, + struct GNUNET_TESTBED_Host **hosts, + unsigned int num_peers, + const struct GNUNET_CONFIGURATION_Handle *peer_cfg, + enum GNUNET_TESTBED_TopologyOption underlay_topology, + ...); + + +/** + * Destroy a testbed. Stops all running peers and then + * destroys all peers. Does NOT destroy the master controller. + * + * @param testbed testbed to destroy + */ +void +GNUNET_TESTBED_destroy (struct GNUNET_TESTBED_Testbed *testbed); + + +/** + * Convenience method for running a testbed with + * a single call. Underlay and overlay topology + * are configured using the "UNDERLAY" and "OVERLAY" + * options in the "[testbed]" section of the configuration\ + * (with possible options given in "UNDERLAY_XXX" and/or + * "OVERLAY_XXX"). + * + * The testbed is to be terminated using a call to + * "GNUNET_SCHEDULER_shutdown". + * + * @param host_filename name of the file with the 'hosts', NULL + * to run everything on 'localhost' + * @param cfg configuration to use (for testbed, controller and peers) + * @param num_peers number of peers to start; FIXME: maybe put that ALSO into cfg? + * @param event_mask bit mask with set of events to call 'cc' for; + * or-ed values of "1LL" shifted by the + * respective 'enum GNUNET_TESTBED_EventType' + * (i.e. "(1LL << GNUNET_TESTBED_ET_CONNECT) || ...") + * @param cc controller callback to invoke on events + * @param cc_cls closure for cc + * @param master task to run once the testbed is ready + * @param master_cls closure for 'task'. + */ +void +GNUNET_TESTBED_run (const char *host_filename, + const struct GNUNET_CONFIGURATION_Handle *cfg, + unsigned int num_peers, + uint64_t event_mask, + GNUNET_TESTBED_ControllerCallback cc, + void *cc_cls, + GNUNET_SCHEDULER_Task master, + void *master_cls); + + +/** + * Signature of a main function for a testcase. + * + * @param cls closure + * @param num_peers number of peers in 'peers' + * @param peers handle to peers run in the testbed + */ +typedef void (*GNUNET_TESTBED_TestMaster)(void *cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers); + + +/** + * Convenience method for running a "simple" test on the local system + * with a single call from 'main'. Underlay and overlay topology are + * configured using the "UNDERLAY" and "OVERLAY" options in the + * "[testbed]" section of the configuration (with possible options + * given in "UNDERLAY_XXX" and/or "OVERLAY_XXX"). + * + * The test is to be terminated using a call to + * "GNUNET_SCHEDULER_shutdown". If starting the test fails, + * the program is stopped without 'master' ever being run. + * + * NOTE: this function should be called from 'main', NOT from + * within a GNUNET_SCHEDULER-loop. This function will initialze + * the scheduler loop, the testbed and then pass control to + * 'master'. + * + * @param testname name of the testcase (to configure logging, etc.) + * @param cfg_filename configuration filename to use + * (for testbed, controller and peers) + * @param num_peers number of peers to start + * @param test_master task to run once the test is ready + * @param test_master_cls closure for 'task'. + */ +void +GNUNET_TESTBED_test_run (const char *testname, + const char *cfg_filename, + unsigned int num_peers, + GNUNET_TESTBED_TestMaster test_master, + void *test_master_cls); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/gnunet_testing_lib-new.h b/src/include/gnunet_testing_lib-new.h new file mode 100644 index 0000000..9b5f4c2 --- /dev/null +++ b/src/include/gnunet_testing_lib-new.h @@ -0,0 +1,299 @@ +/* + This file is part of GNUnet + (C) 2008, 2009, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file include/gnunet_testing_lib-new.h + * @brief convenience API for writing testcases for GNUnet; + * can start/stop one or more peers on a system; + * testing is responsible for managing private keys, + * ports and paths; it is a low-level library that + * does not support higher-level functions such as + * P2P connection, topology management or distributed + * testbed maintenance (those are in gnunet_testbed_service.h) + * @author Christian Grothoff + */ + +#ifndef GNUNET_TESTING_LIB_NEW_H +#define GNUNET_TESTING_LIB_NEW_H + +#include "gnunet_util_lib.h" +#include "gnunet_statistics_service.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Handle for a system on which GNUnet peers are executed; + * a system is used for reserving unique paths and ports. + */ +struct GNUNET_TESTING_System; + + +/** + * Handle for a GNUnet peer controlled by testing. + */ +struct GNUNET_TESTING_Peer; + + +/** + * Create a system handle. There must only be one system + * handle per operating system. + * + * @param tmppath prefix path to use for all service homes + * @param controller hostname of the controlling host, + * service configurations are modified to allow + * control connections from this host; can be NULL + * @return handle to this system, NULL on error + */ +struct GNUNET_TESTING_System * +GNUNET_TESTING_system_create (const char *tmppath, + const char *controller); + + + +/** + * Free system resources. + * + * @param system system to be freed + * @param remove_paths should the 'tmppath' and all subdirectories + * be removed (clean up on shutdown)? + */ +void +GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system, + int remove_paths); + + +/** + * Testing includes a number of pre-created hostkeys for faster peer + * startup. This function loads such keys into memory from a file. + * + * @param system the testing system handle + * @param filename the path of the hostkeys file + * @return GNUNET_OK on success; GNUNET_SYSERR on error + */ +int +GNUNET_TESTING_hostkeys_load (struct GNUNET_TESTING_System *system, + const char *filename); + + +/** + * Function to remove the loaded hostkeys + * + * @param system the testing system handle + */ +void +GNUNET_TESTING_hostkeys_unload (struct GNUNET_TESTING_System *system); + + +/** + * Testing includes a number of pre-created hostkeys for + * faster peer startup. This function can be used to + * access the n-th key of those pre-created hostkeys; note + * that these keys are ONLY useful for testing and not + * secure as the private keys are part of the public + * GNUnet source code. + * + * This is primarily a helper function used internally + * by 'GNUNET_TESTING_peer_configure'. + * + * @param system the testing system handle + * @param key_number desired pre-created hostkey to obtain + * @param id set to the peer's identity (hash of the public + * key; if NULL, GNUNET_SYSERR is returned immediately + * @return GNUNET_SYSERR on error (not enough keys) + */ +int +GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system, + uint32_t key_number, + struct GNUNET_PeerIdentity *id); + + +/** + * Reserve a TCP or UDP port for a peer. + * + * @param system system to use for reservation tracking + * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP + * @return 0 if no free port was available + */ +uint16_t +GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system, + int is_tcp); + + +/** + * Release reservation of a TCP or UDP port for a peer + * (used during GNUNET_TESTING_peer_destroy). + * + * @param system system to use for reservation tracking + * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP + * @param port reserved port to release + */ +void +GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, + int is_tcp, + uint16_t port); + + +/** + * Create a new configuration using the given configuration + * as a template; ports and paths will be modified to select + * available ports on the local system. If we run + * out of "*port" numbers, return SYSERR. + * + * This is primarily a helper function used internally + * by 'GNUNET_TESTING_peer_configure'. + * + * @param system system to use to coordinate resource usage + * @param cfg template configuration to update + * @return GNUNET_OK on success, GNUNET_SYSERR on error - the configuration will + * be incomplete and should not be used there upon + */ +int +GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system, + struct GNUNET_CONFIGURATION_Handle *cfg); +// FIXME: add dual to 'release' ports again... + + +/** + * Configure a GNUnet peer. GNUnet must be installed on the local + * system and available in the PATH. + * + * @param system system to use to coordinate resource usage + * @param cfg configuration to use; will be UPDATED (to reflect needed + * changes in port numbers and paths) + * @param key_number number of the hostkey to use for the peer + * @param id identifier for the daemon, will be set, can be NULL + * @param emsg set to error message (set to NULL on success), can be NULL + * @return handle to the peer, NULL on error + */ +struct GNUNET_TESTING_Peer * +GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system, + struct GNUNET_CONFIGURATION_Handle *cfg, + uint32_t key_number, + struct GNUNET_PeerIdentity *id, + char **emsg); + + +/** + * Start the peer. + * + * @param peer peer to start + * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer already running) + */ +int +GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer); + + +/** + * Stop the peer. + * + * @param peer peer to stop + * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer not running) + */ +int +GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer); + + +/** + * Destroy the peer. Releases resources locked during peer configuration. + * If the peer is still running, it will be stopped AND a warning will be + * printed (users of the API should stop the peer explicitly first). + * + * @param peer peer to destroy + */ +void +GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer); + + +/** + * Signature of the 'main' function for a (single-peer) testcase that + * is run using 'GNUNET_TESTING_peer_run'. + * + * @param cls closure + * @param cfg configuration of the peer that was started + */ +typedef void (*GNUNET_TESTING_TestMain)(void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Start a single peer and run a test using the testing library. + * Starts a peer using the given configuration and then invokes the + * given callback. This function ALSO initializes the scheduler loop + * and should thus be called directly from "main". The testcase + * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'. + * + * @param tmppath path for storing temporary data for the test + * @param cfgfilename name of the configuration file to use; + * use NULL to only run with defaults + * @param tm main function of the testcase + * @param tm_cls closure for 'tm' + * @return 0 on success, 1 on error + */ +int +GNUNET_TESTING_peer_run (const char *tmppath, + const char *cfgfilename, + GNUNET_TESTING_TestMain tm, + void *tm_cls); + + + +/** + * Start a single service (no ARM, except of course if the given + * service name is 'arm') and run a test using the testing library. + * Starts a service using the given configuration and then invokes the + * given callback. This function ALSO initializes the scheduler loop + * and should thus be called directly from "main". The testcase + * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'. + * + * This function is useful if the testcase is for a single service + * and if that service doesn't itself depend on other services. + * + * @param tmppath path for storing temporary data for the test + * @param service_name name of the service to run + * @param cfgfilename name of the configuration file to use; + * use NULL to only run with defaults + * @param tm main function of the testcase + * @param tm_cls closure for 'tm' + * @return 0 on success, 1 on error + */ +int +GNUNET_TESTING_service_run (const char *tmppath, + const char *service_name, + const char *cfgfilename, + GNUNET_TESTING_TestMain tm, + void *tm_cls); + + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h index 03b8376..b170670 100644 --- a/src/include/gnunet_testing_lib.h +++ b/src/include/gnunet_testing_lib.h @@ -304,9 +304,34 @@ struct GNUNET_TESTING_Daemon void *update_cb_cls; /** - * PID of the process that we started last. + * PID of the process we used to run gnunet-arm or SSH to start the peer. */ - struct GNUNET_OS_Process *proc; + struct GNUNET_OS_Process *proc_arm_start; + + /** + * PID of the process we used to run gnunet-arm or SSH to stop the peer. + */ + struct GNUNET_OS_Process *proc_arm_stop; + + /** + * PID of the process we used to run gnunet-arm or SSH to manage services at the peer. + */ + struct GNUNET_OS_Process *proc_arm_srv_start; + + /** + * PID of the process we used to run gnunet-arm or SSH to manage services at the peer. + */ + struct GNUNET_OS_Process *proc_arm_srv_stop; + + /** + * PID of the process we used to run copy files + */ + struct GNUNET_OS_Process *proc_arm_copying; + + /** + * PID of the process we used to run gnunet-peerinfo. + */ + struct GNUNET_OS_Process *proc_arm_peerinfo; /** * Handle to the server. diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h index 7090c33..35d180c 100644 --- a/src/include/gnunet_time_lib.h +++ b/src/include/gnunet_time_lib.h @@ -90,32 +90,32 @@ GNUNET_NETWORK_STRUCT_END /** * Relative time zero. */ -#define GNUNET_TIME_UNIT_ZERO GNUNET_TIME_relative_get_zero() +#define GNUNET_TIME_UNIT_ZERO GNUNET_TIME_relative_get_zero_() /** * Absolute time zero. */ -#define GNUNET_TIME_UNIT_ZERO_ABS GNUNET_TIME_absolute_get_zero() +#define GNUNET_TIME_UNIT_ZERO_ABS GNUNET_TIME_absolute_get_zero_() /** * One millisecond, our basic time unit. */ -#define GNUNET_TIME_UNIT_MILLISECONDS GNUNET_TIME_relative_get_unit() +#define GNUNET_TIME_UNIT_MILLISECONDS GNUNET_TIME_relative_get_unit_() /** * One second. */ -#define GNUNET_TIME_UNIT_SECONDS GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 1000) +#define GNUNET_TIME_UNIT_SECONDS GNUNET_TIME_relative_get_second_() /** * One minute. */ -#define GNUNET_TIME_UNIT_MINUTES GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 60) +#define GNUNET_TIME_UNIT_MINUTES GNUNET_TIME_relative_get_minute_() /** * One hour. */ -#define GNUNET_TIME_UNIT_HOURS GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 60) +#define GNUNET_TIME_UNIT_HOURS GNUNET_TIME_relative_get_hour_() /** * One day. @@ -141,43 +141,70 @@ GNUNET_NETWORK_STRUCT_END * Constant used to specify "forever". This constant * will be treated specially in all time operations. */ -#define GNUNET_TIME_UNIT_FOREVER_REL GNUNET_TIME_relative_get_forever () +#define GNUNET_TIME_UNIT_FOREVER_REL GNUNET_TIME_relative_get_forever_ () /** * Constant used to specify "forever". This constant * will be treated specially in all time operations. */ -#define GNUNET_TIME_UNIT_FOREVER_ABS GNUNET_TIME_absolute_get_forever () +#define GNUNET_TIME_UNIT_FOREVER_ABS GNUNET_TIME_absolute_get_forever_ () + /** * Return relative time of 0ms. */ struct GNUNET_TIME_Relative -GNUNET_TIME_relative_get_zero (void); +GNUNET_TIME_relative_get_zero_ (void); + /** * Return absolute time of 0ms. */ struct GNUNET_TIME_Absolute -GNUNET_TIME_absolute_get_zero (void); +GNUNET_TIME_absolute_get_zero_ (void); + /** * Return relative time of 1ms. */ struct GNUNET_TIME_Relative -GNUNET_TIME_relative_get_unit (void); +GNUNET_TIME_relative_get_unit_ (void); + + +/** + * Return relative time of 1s. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_second_ (void); + + +/** + * Return relative time of 1 minute. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_minute_ (void); + + +/** + * Return relative time of 1 hour. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_hour_ (void); + /** * Return "forever". */ struct GNUNET_TIME_Relative -GNUNET_TIME_relative_get_forever (void); +GNUNET_TIME_relative_get_forever_ (void); + /** * Return "forever". */ struct GNUNET_TIME_Absolute -GNUNET_TIME_absolute_get_forever (void); +GNUNET_TIME_absolute_get_forever_ (void); + /** * Get the current time. @@ -187,6 +214,7 @@ GNUNET_TIME_absolute_get_forever (void); struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get (void); + /** * Convert relative time to an absolute time in the * future. @@ -197,6 +225,7 @@ GNUNET_TIME_absolute_get (void); struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel); + /** * Return the minimum of two relative time values. * @@ -209,6 +238,7 @@ GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2); + /** * Return the maximum of two relative time values. * @@ -220,6 +250,7 @@ struct GNUNET_TIME_Relative GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2); + /** * Return the minimum of two absolute time values. * @@ -231,6 +262,7 @@ struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2); + /** * Return the maximum of two absolute time values. * @@ -242,6 +274,7 @@ struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2); + /** * Given a timestamp in the future, how much time * remains until then? @@ -281,6 +314,7 @@ struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Absolute end); + /** * Get the duration of an operation as the * difference of the current time and the given start time "hence". @@ -317,6 +351,7 @@ struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration); + /** * Multiply relative time by a given factor. * @@ -328,6 +363,7 @@ struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel, unsigned int factor); + /** * Divide relative time by a given factor. * @@ -339,6 +375,7 @@ struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel, unsigned int factor); + /** * Add relative times together. * @@ -350,6 +387,7 @@ struct GNUNET_TIME_Relative GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2); + /** * Subtract relative timestamp from the other. * @@ -371,6 +409,7 @@ GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a); + /** * Convert relative time from network byte order. * @@ -380,6 +419,7 @@ GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a); struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a); + /** * Convert relative time to network byte order. * @@ -389,6 +429,7 @@ GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a); struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a); + /** * Convert relative time from network byte order. * @@ -398,6 +439,7 @@ GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a); struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a); + /** * Convert a relative time to a string. * NOT reentrant! @@ -409,6 +451,7 @@ GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a); const char * GNUNET_TIME_relative_to_string (struct GNUNET_TIME_Relative time); + /** * Set the timestamp offset for this instance. * @@ -417,6 +460,7 @@ GNUNET_TIME_relative_to_string (struct GNUNET_TIME_Relative time); void GNUNET_TIME_set_offset (long long offset); + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/include/gnunet_transport_plugin.h b/src/include/gnunet_transport_plugin.h index 9b39a41..d1e03d7 100644 --- a/src/include/gnunet_transport_plugin.h +++ b/src/include/gnunet_transport_plugin.h @@ -136,7 +136,7 @@ typedef struct * @param addrlen length of the address * @return ATS Information containing the network type */ -typedef const struct GNUNET_ATS_Information +typedef struct GNUNET_ATS_Information (*GNUNET_TRANSPORT_AddressToType) (void *cls, const struct sockaddr *addr, size_t addrlen); @@ -218,7 +218,11 @@ struct GNUNET_TRANSPORT_PluginEnvironment /** * Function that should be called by the transport plugin - * whenever a message is received. + * whenever a message is received. If this field is "NULL", + * the plugin should load in 'stub' mode and NOT fully + * initialize and instead only return an API with the + * 'address_pretty_printer', 'address_to_string' and + * 'string_to_address' functions. */ GNUNET_TRANSPORT_PluginReceiveCallback receive; @@ -309,11 +313,12 @@ typedef void (*GNUNET_TRANSPORT_TransmitContinuation) (void *cls, * and does NOT mean that the message was not transmitted (DV) */ typedef ssize_t (*GNUNET_TRANSPORT_TransmitFunction) (void *cls, - struct Session *session, - const char *msgbuf, size_t msgbuf_size, - unsigned int priority, - struct GNUNET_TIME_Relative to, - GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls); + struct Session *session, + const char *msgbuf, size_t msgbuf_size, + unsigned int priority, + struct GNUNET_TIME_Relative to, + GNUNET_TRANSPORT_TransmitContinuation cont, + void *cont_cls); /** @@ -423,6 +428,24 @@ typedef const char *(*GNUNET_TRANSPORT_AddressToString) (void *cls, const void *addr, size_t addrlen); +/** + * Function called to convert a string address to + * a binary address. + * + * @param cls closure ('struct Plugin*') + * @param addr string address + * @param addrlen length of the address + * @param buf location to store the buffer + * If the function returns GNUNET_SYSERR, its contents are undefined. + * @param added length of created address + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +typedef int (*GNUNET_TRANSPORT_StringToAddress) (void *cls, + const char *addr, + uint16_t addrlen, + void **buf, + size_t *added); + /** * Each plugin is required to return a pointer to a struct of this @@ -476,6 +499,12 @@ struct GNUNET_TRANSPORT_PluginFunctions */ GNUNET_TRANSPORT_AddressToString address_to_string; + /** + * Function that will be called to convert a string address + * to binary (numeric conversion only). + */ + GNUNET_TRANSPORT_StringToAddress string_to_address; + /** * Function that will be called tell the plugin to create a session * object diff --git a/src/include/gnunet_tun_lib.h b/src/include/gnunet_tun_lib.h index dac11d6..3bb1ea3 100644 --- a/src/include/gnunet_tun_lib.h +++ b/src/include/gnunet_tun_lib.h @@ -119,7 +119,7 @@ struct GNUNET_TUN_IPv4Header * Destination of the packet. */ struct in_addr destination_address GNUNET_PACKED; -}; +} GNUNET_GCC_STRUCT_LAYOUT; /** @@ -163,7 +163,7 @@ struct GNUNET_TUN_IPv6Header * Destination of the packet. */ struct in6_addr destination_address GNUNET_PACKED; -}; +} GNUNET_GCC_STRUCT_LAYOUT; /** @@ -224,7 +224,7 @@ struct GNUNET_TUN_TcpHeader * Urgent pointer. */ uint16_t urgent_pointer GNUNET_PACKED; -}; +} GNUNET_GCC_STRUCT_LAYOUT; /** diff --git a/src/include/platform.h b/src/include/platform.h index 7383e48..9a5d164 100644 --- a/src/include/platform.h +++ b/src/include/platform.h @@ -241,6 +241,14 @@ atoll (const char *nptr); #define O_LARGEFILE 0 #endif +/** + * AI_NUMERICSERV not defined in windows. Then we just do without. + */ +#ifndef AI_NUMERICSERV +#define AI_NUMERICSERV 0 +#endif + + #if defined(__sparc__) #define MAKE_UNALIGNED(val) ({ __typeof__((val)) __tmp; memmove(&__tmp, &(val), sizeof((val))); __tmp; }) #else diff --git a/src/include/plibc.h b/src/include/plibc.h index 70cbd9e..1cb84e6 100644 --- a/src/include/plibc.h +++ b/src/include/plibc.h @@ -22,7 +22,7 @@ * @brief PlibC header * @attention This file is usually not installed under Unix, * so ship it with your application - * @version $Revision$ + * @version $Revision: 84 $ */ #ifndef _PLIBC_H_ @@ -336,9 +336,13 @@ typedef struct #define SetErrnoFromWinError(e) _SetErrnoFromWinError(e, __FILE__, __LINE__) BOOL _plibc_CreateShortcut(const char *pszSrc, const char *pszDest); +BOOL _plibc_CreateShortcutW(const wchar_t *pwszSrc, const wchar_t *pwszDest); BOOL _plibc_DereferenceShortcut(char *pszShortcut); +BOOL _plibc_DereferenceShortcutW(wchar_t *pwszShortcut); char *plibc_ChooseDir(char *pszTitle, unsigned long ulFlags); +wchar_t *plibc_ChooseDirW(wchar_t *pwszTitle, unsigned long ulFlags); char *plibc_ChooseFile(char *pszTitle, unsigned long ulFlags); +wchar_t *plibc_ChooseFileW(wchar_t *pwszTitle, unsigned long ulFlags); long QueryRegistry(HKEY hMainKey, const char *pszKey, const char *pszSubKey, char *pszBuffer, long *pdLength); @@ -376,6 +380,7 @@ const char *inet_ntop(int af, const void *src, char *dst, size_t size); struct tm *gmtime_r(const time_t *clock, struct tm *result); int plibc_init(char *pszOrg, char *pszApp); +int plibc_init_utf8(char *pszOrg, char *pszApp, int utf8_mode); void plibc_shutdown(); int plibc_initialized(); diff --git a/src/integration-tests/Makefile.am b/src/integration-tests/Makefile.am index d948b3d..fb69e28 100644 --- a/src/integration-tests/Makefile.am +++ b/src/integration-tests/Makefile.am @@ -9,13 +9,17 @@ if USE_COVERAGE XLIB = -lgcov endif -bin_PROGRAMS = +#bin_PROGRAMS = \ +# connection_watchdog -check_PROGRAMS = +noinst_PROGRAMS = connection_watchdog noinst_SCRIPTS = \ gnunet_testing.py \ - gnunet_pyexpect.py + gnunet_pyexpect.py \ + test_integration_connection_values_tcp.py \ + test_integration_connection_values_tcp_udp.py \ + test_integration_connection_values_tcp_udp_http.py if HAVE_PYTHON_PEXPECT check_SCRIPTS = \ @@ -24,16 +28,28 @@ check_SCRIPTS = \ test_integration_bootstrap_and_connect_and_disconnect_nat.py \ test_integration_restart.py \ test_integration_clique.py \ - test_integration_clique_nat.py + test_integration_clique_nat.py \ + test_integration_connect_on_restart.py endif # test_integration_disconnect.py +check_PROGRAMS = \ + test_connection_stability + if ENABLE_TEST_RUN TESTS = \ $(check_SCRIPTS) endif +connection_watchdog_SOURCE = \ + connection_watchdog.c +connection_watchdog_LDADD = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la + do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' %.py: %.py.in Makefile @@ -81,13 +97,39 @@ test_integration_clique_nat.py: test_integration_clique_nat.py.in Makefile $(do_subst) < $(srcdir)/test_integration_clique_nat.py.in > test_integration_clique_nat.py chmod +x test_integration_clique_nat.py +test_integration_connect_on_restart.py: test_integration_connect_on_restart.py.in Makefile + $(do_subst) < $(srcdir)/test_integration_connect_on_restart.py.in > test_integration_connect_on_restart.py + chmod +x test_integration_connect_on_restart.py + +test_integration_connection_values_tcp.py: test_integration_connection_values_tcp.py.in Makefile + $(do_subst) < $(srcdir)/test_integration_connection_values_tcp.py.in > test_integration_connection_values_tcp.py + chmod +x test_integration_connection_values_tcp.py + +test_integration_connection_values_tcp_udp.py: test_integration_connection_values_tcp_udp.py.in Makefile + $(do_subst) < $(srcdir)/test_integration_connection_values_tcp_udp.py.in > test_integration_connection_values_tcp_udp.py + chmod +x test_integration_connection_values_tcp_udp.py + +test_integration_connection_values_tcp_udp_http.py: test_integration_connection_values_tcp_udp_http.py.in Makefile + $(do_subst) < $(srcdir)/test_integration_connection_values_tcp_udp_http.py.in > test_integration_connection_values_tcp_udp_http.py + chmod +x test_integration_connection_values_tcp_udp_http.py + +test_connection_stability_SOURCES = \ + test_connection_stability.c +test_connection_stability_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/util/libgnunetutil.la + EXTRA_DIST = \ gnunet_testing.py.in \ gnunet_pyexpect.py.in \ + test_integration_connection_values_tcp.py.in \ + test_integration_connection_values_tcp_udp.py.in \ + test_integration_connection_values_tcp_udp_http.py.in \ test_integration_bootstrap_and_connect.py.in \ test_integration_bootstrap_and_connect_and_disconnect.py.in \ test_integration_bootstrap_and_connect_and_disconnect_nat.py.in \ + test_integration_connect_on_restart.py.in \ test_integration_disconnect.py.in \ test_integration_restart.py.in \ test_integration_clique.py.in \ @@ -96,6 +138,16 @@ EXTRA_DIST = \ confs/c_nat_client.conf \ confs/c_no_nat_client_2.conf \ confs/c_no_nat_client.conf \ + confs/c_normal_client_tcp.conf \ + confs/c_normal_client_tcp_udp.conf \ + confs/c_normal_client_tcp_udp_http.conf \ + confs/c_no_nat_client_http.conf \ + confs/c_no_nat_client_http_2.conf\ + confs/c_no_nat_client_http.conf \ + confs/c_no_nat_client_http_2.conf \ + confs/c_no_nat_client_unix.conf \ + confs/c_no_nat_client_unix_2.conf \ + test_connection_stability.conf \ hostkeys/0000-hostkey \ hostkeys/0001-hostkey \ hostkeys/0002-hostkey \ diff --git a/src/integration-tests/Makefile.in b/src/integration-tests/Makefile.in index 20b13d6..3e5e7dc 100644 --- a/src/integration-tests/Makefile.in +++ b/src/integration-tests/Makefile.in @@ -36,8 +36,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -bin_PROGRAMS = -check_PROGRAMS = +noinst_PROGRAMS = connection_watchdog$(EXEEXT) +check_PROGRAMS = test_connection_stability$(EXEEXT) subdir = src/integration-tests DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -59,17 +59,56 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/gnunet_config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" -PROGRAMS = $(bin_PROGRAMS) +PROGRAMS = $(noinst_PROGRAMS) +connection_watchdog_SOURCES = connection_watchdog.c +connection_watchdog_OBJECTS = connection_watchdog.$(OBJEXT) +connection_watchdog_DEPENDENCIES = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +am_test_connection_stability_OBJECTS = \ + test_connection_stability.$(OBJEXT) +test_connection_stability_OBJECTS = \ + $(am_test_connection_stability_OBJECTS) +test_connection_stability_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/util/libgnunetutil.la SCRIPTS = $(noinst_SCRIPTS) -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ -SOURCES = -DIST_SOURCES = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = connection_watchdog.c $(test_connection_stability_SOURCES) +DIST_SOURCES = connection_watchdog.c \ + $(test_connection_stability_SOURCES) +ETAGS = etags +CTAGS = ctags am__tty_colors = \ red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -128,6 +167,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -161,6 +201,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -283,7 +324,10 @@ INCLUDES = -I$(top_srcdir)/src/include @USE_COVERAGE_TRUE@XLIB = -lgcov noinst_SCRIPTS = \ gnunet_testing.py \ - gnunet_pyexpect.py + gnunet_pyexpect.py \ + test_integration_connection_values_tcp.py \ + test_integration_connection_values_tcp_udp.py \ + test_integration_connection_values_tcp_udp_http.py @HAVE_PYTHON_PEXPECT_TRUE@check_SCRIPTS = \ @HAVE_PYTHON_PEXPECT_TRUE@ test_integration_bootstrap_and_connect.py \ @@ -291,19 +335,39 @@ noinst_SCRIPTS = \ @HAVE_PYTHON_PEXPECT_TRUE@ test_integration_bootstrap_and_connect_and_disconnect_nat.py \ @HAVE_PYTHON_PEXPECT_TRUE@ test_integration_restart.py \ @HAVE_PYTHON_PEXPECT_TRUE@ test_integration_clique.py \ -@HAVE_PYTHON_PEXPECT_TRUE@ test_integration_clique_nat.py +@HAVE_PYTHON_PEXPECT_TRUE@ test_integration_clique_nat.py \ +@HAVE_PYTHON_PEXPECT_TRUE@ test_integration_connect_on_restart.py -# test_integration_disconnect.py @ENABLE_TEST_RUN_TRUE@TESTS = \ @ENABLE_TEST_RUN_TRUE@ $(check_SCRIPTS) +connection_watchdog_SOURCE = \ + connection_watchdog.c + +connection_watchdog_LDADD = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la + do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' +test_connection_stability_SOURCES = \ + test_connection_stability.c + +test_connection_stability_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/util/libgnunetutil.la + EXTRA_DIST = \ gnunet_testing.py.in \ gnunet_pyexpect.py.in \ + test_integration_connection_values_tcp.py.in \ + test_integration_connection_values_tcp_udp.py.in \ + test_integration_connection_values_tcp_udp_http.py.in \ test_integration_bootstrap_and_connect.py.in \ test_integration_bootstrap_and_connect_and_disconnect.py.in \ test_integration_bootstrap_and_connect_and_disconnect_nat.py.in \ + test_integration_connect_on_restart.py.in \ test_integration_disconnect.py.in \ test_integration_restart.py.in \ test_integration_clique.py.in \ @@ -312,6 +376,16 @@ EXTRA_DIST = \ confs/c_nat_client.conf \ confs/c_no_nat_client_2.conf \ confs/c_no_nat_client.conf \ + confs/c_normal_client_tcp.conf \ + confs/c_normal_client_tcp_udp.conf \ + confs/c_normal_client_tcp_udp_http.conf \ + confs/c_no_nat_client_http.conf \ + confs/c_no_nat_client_http_2.conf\ + confs/c_no_nat_client_http.conf \ + confs/c_no_nat_client_http_2.conf \ + confs/c_no_nat_client_unix.conf \ + confs/c_no_nat_client_unix_2.conf \ + test_connection_stability.conf \ hostkeys/0000-hostkey \ hostkeys/0001-hostkey \ hostkeys/0002-hostkey \ @@ -331,6 +405,7 @@ CLEANFILES = \ all: all-am .SUFFIXES: +.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -361,43 +436,9 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p || test -f $$p1; \ - then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ @@ -405,26 +446,111 @@ clean-binPROGRAMS: echo " rm -f" $$list; \ rm -f $$list -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list +connection_watchdog$(EXEEXT): $(connection_watchdog_OBJECTS) $(connection_watchdog_DEPENDENCIES) + @rm -f connection_watchdog$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(connection_watchdog_OBJECTS) $(connection_watchdog_LDADD) $(LIBS) +test_connection_stability$(EXEEXT): $(test_connection_stability_OBJECTS) $(test_connection_stability_DEPENDENCIES) + @rm -f test_connection_stability$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_connection_stability_OBJECTS) $(test_connection_stability_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection_watchdog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_connection_stability.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique tags: TAGS -TAGS: +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi ctags: CTAGS -CTAGS: - +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ @@ -554,9 +680,6 @@ check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(SCRIPTS) installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done install: install-am install-exec: install-exec-am install-data: install-data-am @@ -585,12 +708,14 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libtool mostlyclean-am +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am + -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-generic +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags dvi: dvi-am @@ -610,7 +735,7 @@ install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-binPROGRAMS +install-exec-am: install-html: install-html-am @@ -633,12 +758,14 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-generic mostlyclean-libtool +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf: pdf-am @@ -648,22 +775,23 @@ ps: ps-am ps-am: -uninstall-am: uninstall-binPROGRAMS +uninstall-am: .MAKE: check-am install-am install-strip -.PHONY: all all-am check check-TESTS check-am clean clean-binPROGRAMS \ - clean-checkPROGRAMS clean-generic clean-libtool distclean \ - distclean-generic distclean-libtool distdir dvi dvi-am html \ - html-am info info-am install install-am install-binPROGRAMS \ +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ - uninstall-binPROGRAMS + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am %.py: %.py.in Makefile @@ -710,6 +838,22 @@ test_integration_clique_nat.py: test_integration_clique_nat.py.in Makefile $(do_subst) < $(srcdir)/test_integration_clique_nat.py.in > test_integration_clique_nat.py chmod +x test_integration_clique_nat.py +test_integration_connect_on_restart.py: test_integration_connect_on_restart.py.in Makefile + $(do_subst) < $(srcdir)/test_integration_connect_on_restart.py.in > test_integration_connect_on_restart.py + chmod +x test_integration_connect_on_restart.py + +test_integration_connection_values_tcp.py: test_integration_connection_values_tcp.py.in Makefile + $(do_subst) < $(srcdir)/test_integration_connection_values_tcp.py.in > test_integration_connection_values_tcp.py + chmod +x test_integration_connection_values_tcp.py + +test_integration_connection_values_tcp_udp.py: test_integration_connection_values_tcp_udp.py.in Makefile + $(do_subst) < $(srcdir)/test_integration_connection_values_tcp_udp.py.in > test_integration_connection_values_tcp_udp.py + chmod +x test_integration_connection_values_tcp_udp.py + +test_integration_connection_values_tcp_udp_http.py: test_integration_connection_values_tcp_udp_http.py.in Makefile + $(do_subst) < $(srcdir)/test_integration_connection_values_tcp_udp_http.py.in > test_integration_connection_values_tcp_udp_http.py + chmod +x test_integration_connection_values_tcp_udp_http.py + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/integration-tests/confs/c_bootstrap_server.conf b/src/integration-tests/confs/c_bootstrap_server.conf index 0b919f9..7235fca 100644 --- a/src/integration-tests/confs/c_bootstrap_server.conf +++ b/src/integration-tests/confs/c_bootstrap_server.conf @@ -353,3 +353,11 @@ UNIX_MATCH_GID = YES DATABASE = sqlite QUOTA = 1 MB +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[lockmanager] +AUTOSTART = NO \ No newline at end of file diff --git a/src/integration-tests/confs/c_nat_client.conf b/src/integration-tests/confs/c_nat_client.conf index 59fa0f7..4f6c578 100644 --- a/src/integration-tests/confs/c_nat_client.conf +++ b/src/integration-tests/confs/c_nat_client.conf @@ -8,6 +8,12 @@ HOSTKEY = hostkeys/0002-hostkey [client] HOME = $SERVICEHOME +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + [vpn] AUTOSTART = YES PORT = 0 @@ -351,4 +357,7 @@ UNIX_MATCH_GID = YES [dhtcache] DATABASE = sqlite -QUOTA = 1 MB \ No newline at end of file +QUOTA = 1 MB + +[lockmanager] +AUTOSTART = NO \ No newline at end of file diff --git a/src/integration-tests/confs/c_no_nat_client.conf b/src/integration-tests/confs/c_no_nat_client.conf index 4ec077c..0a24b5a 100644 --- a/src/integration-tests/confs/c_no_nat_client.conf +++ b/src/integration-tests/confs/c_no_nat_client.conf @@ -6,6 +6,12 @@ DEFAULTCONFIG = confs/c_no_nat_client.conf #HOSTKEY = $SERVICEHOME/.hostkey HOSTKEY = hostkeys/0001-hostkey +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + [vpn] AUTOSTART = YES PORT = 0 @@ -354,3 +360,5 @@ UNIX_MATCH_GID = YES DATABASE = sqlite QUOTA = 1 MB +[lockmanager] +AUTOSTART = NO diff --git a/src/integration-tests/confs/c_no_nat_client_2.conf b/src/integration-tests/confs/c_no_nat_client_2.conf index bd675d7..61a6a3b 100644 --- a/src/integration-tests/confs/c_no_nat_client_2.conf +++ b/src/integration-tests/confs/c_no_nat_client_2.conf @@ -342,3 +342,10 @@ UNIX_MATCH_GID = YES DATABASE = sqlite QUOTA = 1 MB +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + + diff --git a/src/integration-tests/confs/c_no_nat_client_http.conf b/src/integration-tests/confs/c_no_nat_client_http.conf new file mode 100644 index 0000000..718794e --- /dev/null +++ b/src/integration-tests/confs/c_no_nat_client_http.conf @@ -0,0 +1,363 @@ +[PATHS] +SERVICEHOME = /tmp/c_no_nat_client/ +DEFAULTCONFIG = confs/c_no_nat_client_http.conf + +[gnunetd] +#HOSTKEY = $SERVICEHOME/.hostkey +HOSTKEY = hostkeys/0001-hostkey + +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[vpn] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/gnunet-service-vpn-29 + +[resolver] +AUTOSTART = YES +PORT = 20035 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-resolver +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-resolver-28 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = NO + +[mesh] +AUTOSTART = YES +PORT = 20034 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-mesh +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-mesh-27 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nse] +AUTOSTART = YES +PORT = 20033 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-nse +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-nse-26 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PROOFFILE = $SERVICEHOME/.nse-proof +HISTOGRAM = $SERVICEHOME/nse-history.log +WORKDELAY = 5 ms +INTERVAL = 1 h +WORKBITS = 26 + +[topology] +MINIMUM-FRIENDS = 0 +FRIENDS-ONLY = NO +AUTOCONNECT = YES +TARGET-CONNECTION-COUNT = 16 +FRIENDS = $SERVICEHOME/friends +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-topology + +[datastore] +AUTOSTART = YES +UNIXPATH = /tmp/test-service-datastore-25 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PORT = 20032 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-datastore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +QUOTA = 100 MB +BLOOMFILTER = $SERVICEHOME/fs/bloomfilter +DATABASE = sqlite + +[datastore-sqlite] +FILENAME = $SERVICEHOME/datastore/sqlite.db + +[datastore-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[datastore-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[peerinfo] +AUTOSTART = YES +PORT = 20031 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-peerinfo +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-peerinfo-24 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTS = $SERVICEHOME/data/hosts/ + +[client] +HOME = $SERVICEHOME + +[TESTING] +WEAKRANDOM = NO +CONNECT_TIMEOUT = 30 s +CONNECT_ATTEMPTS = 3 +MAX_OUTSTANDING_CONNECTIONS = 50 +DELETE_FILES = YES + +[ats] +AUTOSTART = YES +PORT = 20030 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-ats +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-ats-23 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +WAN_QUOTA_IN = 65536 +WAN_QUOTA_OUT = 65536 +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 + +[transport] +PREFIX = valgrind --leak-check=full +#DEBUG = YES +AUTOSTART = YES +PORT = 20029 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-transport +NEIGHBOUR_LIMIT = 50 +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +PLUGINS = http +UNIXPATH = /tmp/test-service-transport-22 +BLACKLIST_FILE = $SERVICEHOME/blacklist +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[transport-tcp] +USE_LOCALADDR = YES +PORT = 20028 +ADVERTISED_PORT = 20028 +MAX_CONNECTIONS = 128 +TIMEOUT = 5 s + +[transport-udp] +USE_LOCALADDR = YES +PORT = 20027 +BROADCAST = YES +BROADCAST_INTERVAL = 30000 +MAX_BPS = 1000000 + +[transport-http] +PORT = 20026 +MAX_CONNECTIONS = 128 + +[transport-https] +PORT = 20025 +CRYPTO_INIT = NORMAL +KEY_FILE = https.key +CERT_FILE = https.cert +MAX_CONNECTIONS = 128 + +[transport-wlan] +INTERFACE = mon0 +TESTMODE = 0 + +[datacache-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[datacache-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[template] +AUTOSTART = NO +PORT = 20024 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-template +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-template-21 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[fs] +AUTOSTART = YES +INDEXDB = $SERVICEHOME/idxinfo.lst +TRUST = $SERVICEHOME/data/credit/ +IDENTITY_DIR = $SERVICEHOME/identities/ +STATE_DIR = $SERVICEHOME/persistence/ +UPDATE_DIR = $SERVICEHOME/updates/ +PORT = 20023 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-fs +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DELAY = YES +CONTENT_CACHING = YES +CONTENT_PUSHING = YES +UNIXPATH = /tmp/test-service-fs-20 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PENDING_REQUESTS = 65536 +MIN_MIGRATION_DELAY = 100 ms +EXPECTED_NEIGHBOUR_COUNT = 128 + +[vpn] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-vpn +IPV6ADDR = 1234::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.11.10.1 +IPV4MASK = 255.255.0.0 +VIRTDNS = 10.11.10.2 +VIRTDNS6 = 1234::17 +IFNAME = vpn-gnunet + +[exit] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-exit +IPV6ADDR = 1234:1::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.10.1.1 +IPV4MASK = 255.255.0.0 +IFNAME = exit-gnunet +ENABLE_UDP = NO +ENABLE_TCP = NO + +[dns] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-dns-19 +PROVIDE_EXIT = NO + +[arm] +PORT = 20022 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-arm +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DEFAULTSERVICES = topology hostlist fs core +UNIXPATH = /tmp/test-service-arm-18 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[hostlist] +HTTPPORT = 8080 +HOME = $SERVICEHOME +HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-hostlist +OPTIONS = -b +SERVERS = http://localhost:8080/ +HTTP-PROXY = + +[core] +AUTOSTART = YES +PORT = 20021 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-core +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-core-17 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nat] +EXTERNAL_ADDRESS = 127.0.0.1 +INTERNAL_ADDRESS = 127.0.0.1 +BINDTO = 127.0.0.1 +BEHIND_NAT = NO +PUNCHED_NAT = NO +ENABLE_UPNP = NO +USE_LOCALADDR = YES +USE_HOSTNAME = NO +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO +DISABLEV6 = YES +RETURN_LOCAL_ADDRESSES = NO +HOSTNAME_DNS_FREQUENCY = 1200000 +IFC_SCAN_FREQUENCY = 3000000 +DYNDNS_FREQUENCY = 140000 + +[gnunet-nat-server] +HOSTNAME = gnunet.org +PORT = 20020 + +[statistics] +AUTOSTART = YES +PORT = 20019 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-statistics +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-statistics-16 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES + +[dht] +AUTOSTART = YES +PORT = 20018 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dht +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +BUCKET_SIZE = 4 +UNIXPATH = /tmp/test-service-dht-15 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[dhtcache] +DATABASE = sqlite +QUOTA = 1 MB + diff --git a/src/integration-tests/confs/c_no_nat_client_http_2.conf b/src/integration-tests/confs/c_no_nat_client_http_2.conf new file mode 100644 index 0000000..3acb6b1 --- /dev/null +++ b/src/integration-tests/confs/c_no_nat_client_http_2.conf @@ -0,0 +1,352 @@ +[PATHS] +SERVICEHOME = /tmp/c_no_nat_client_2/ +DEFAULTCONFIG = confs/c_no_nat_client_http_2.conf + +[gnunetd] +#HOSTKEY = $SERVICEHOME/.hostkey +HOSTKEY = hostkeys/0002-hostkey + +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[resolver] +AUTOSTART = YES +PORT = 20053 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-resolver +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-resolver-42 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = NO + +[mesh] +AUTOSTART = YES +PORT = 20052 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-mesh +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-mesh-41 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nse] +AUTOSTART = YES +PORT = 20051 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-nse +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-nse-40 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PROOFFILE = $SERVICEHOME/.nse-proof +HISTOGRAM = $SERVICEHOME/nse-history.log +WORKDELAY = 5 ms +INTERVAL = 1 h +WORKBITS = 26 + +[topology] +MINIMUM-FRIENDS = 0 +FRIENDS-ONLY = NO +AUTOCONNECT = YES +TARGET-CONNECTION-COUNT = 16 +FRIENDS = $SERVICEHOME/friends +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-topology + +[datastore] +AUTOSTART = YES +UNIXPATH = /tmp/test-service-datastore-39 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PORT = 20050 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-datastore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +QUOTA = 100 MB +BLOOMFILTER = $SERVICEHOME/fs/bloomfilter +DATABASE = sqlite + +[datastore-sqlite] +FILENAME = $SERVICEHOME/datastore/sqlite.db + +[datastore-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[datastore-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[peerinfo] +AUTOSTART = YES +PORT = 20049 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-peerinfo +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-peerinfo-38 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTS = $SERVICEHOME/data/hosts/ + +[client] +HOME = $SERVICEHOME + +[TESTING] +WEAKRANDOM = NO +CONNECT_TIMEOUT = 30 s +CONNECT_ATTEMPTS = 3 +MAX_OUTSTANDING_CONNECTIONS = 50 +DELETE_FILES = YES + +[ats] +AUTOSTART = YES +PORT = 20048 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-ats +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-ats-37 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +WAN_QUOTA_IN = 65536 +WAN_QUOTA_OUT = 65536 +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 + +[transport] +PREFIX = valgrind --leak-check=full +#PREFIX = gdb --args +AUTOSTART = YES +PORT = 20047 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-transport +NEIGHBOUR_LIMIT = 50 +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +PLUGINS = http +UNIXPATH = /tmp/test-service-transport-36 +BLACKLIST_FILE = $SERVICEHOME/blacklist +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[transport-tcp] +PORT = 20046 +ADVERTISED_PORT = 20046 +MAX_CONNECTIONS = 128 +TIMEOUT = 5 s +USE_LOCALADDR = YES + +[transport-udp] +PORT = 20045 +BROADCAST = YES +BROADCAST_INTERVAL = 30000 +MAX_BPS = 1000000 +USE_LOCALADDR = YES + +[transport-http] +PORT = 20044 +MAX_CONNECTIONS = 128 + +[transport-https] +PORT = 20043 +CRYPTO_INIT = NORMAL +KEY_FILE = https.key +CERT_FILE = https.cert +MAX_CONNECTIONS = 128 + +[transport-wlan] +INTERFACE = mon0 +TESTMODE = 0 + +[datacache-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[datacache-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[template] +AUTOSTART = NO +PORT = 20042 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-template +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-template-35 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[fs] +AUTOSTART = YES +INDEXDB = $SERVICEHOME/idxinfo.lst +TRUST = $SERVICEHOME/data/credit/ +IDENTITY_DIR = $SERVICEHOME/identities/ +STATE_DIR = $SERVICEHOME/persistence/ +UPDATE_DIR = $SERVICEHOME/updates/ +PORT = 20041 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-fs +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DELAY = YES +CONTENT_CACHING = YES +CONTENT_PUSHING = YES +UNIXPATH = /tmp/test-service-fs-34 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PENDING_REQUESTS = 65536 +MIN_MIGRATION_DELAY = 100 ms +EXPECTED_NEIGHBOUR_COUNT = 128 + +[vpn] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-vpn +IPV6ADDR = 1234::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.11.10.1 +IPV4MASK = 255.255.0.0 +VIRTDNS = 10.11.10.2 +VIRTDNS6 = 1234::17 +IFNAME = vpn-gnunet + +[exit] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-exit +IPV6ADDR = 1234:1::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.10.1.1 +IPV4MASK = 255.255.0.0 +IFNAME = exit-gnunet +ENABLE_UDP = NO +ENABLE_TCP = NO + +[dns] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-dns-33 +PROVIDE_EXIT = NO + +[arm] +PORT = 20040 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-arm +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DEFAULTSERVICES = topology hostlist fs core +UNIXPATH = /tmp/test-service-arm-32 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[hostlist] +HTTPPORT = 8080 +HOME = $SERVICEHOME +HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-hostlist +OPTIONS = -b +SERVERS = http://localhost:8080/ +HTTP-PROXY = + +[core] +AUTOSTART = YES +PORT = 20039 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-core +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-core-31 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nat] +BEHIND_NAT = NO +PUNCHED_NAT = NO +ENABLE_UPNP = NO +USE_LOCALADDR = YES +USE_HOSTNAME = NO +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO +DISABLEV6 = YES +RETURN_LOCAL_ADDRESSES = NO +HOSTNAME_DNS_FREQUENCY = 1200000 +IFC_SCAN_FREQUENCY = 3000000 +DYNDNS_FREQUENCY = 140000 +EXTERNAL_ADDRESS = 127.0.0.1 +INTERNAL_ADDRESS = 127.0.0.1 +BINDTO = 127.0.0.1 + +[gnunet-nat-server] +HOSTNAME = gnunet.org +PORT = 20038 + +[statistics] +AUTOSTART = YES +PORT = 20037 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-statistics +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-statistics-30 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES + +[dht] +AUTOSTART = YES +PORT = 20036 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dht +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +BUCKET_SIZE = 4 +UNIXPATH = /tmp/test-service-dht-29 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[dhtcache] +DATABASE = sqlite +QUOTA = 1 MB + diff --git a/src/integration-tests/confs/c_no_nat_client_unix.conf b/src/integration-tests/confs/c_no_nat_client_unix.conf new file mode 100644 index 0000000..37c5ad6 --- /dev/null +++ b/src/integration-tests/confs/c_no_nat_client_unix.conf @@ -0,0 +1,366 @@ +[PATHS] +SERVICEHOME = /tmp/c_no_nat_client/ +DEFAULTCONFIG = confs/c_no_nat_client_unix.conf + +[gnunetd] +#HOSTKEY = $SERVICEHOME/.hostkey +HOSTKEY = hostkeys/0001-hostkey + +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[vpn] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/gnunet-service-vpn-29 + +[resolver] +AUTOSTART = YES +PORT = 20035 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-resolver +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-resolver-28 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = NO + +[mesh] +AUTOSTART = YES +PORT = 20034 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-mesh +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-mesh-27 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nse] +AUTOSTART = YES +PORT = 20033 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-nse +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-nse-26 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PROOFFILE = $SERVICEHOME/.nse-proof +HISTOGRAM = $SERVICEHOME/nse-history.log +WORKDELAY = 5 ms +INTERVAL = 1 h +WORKBITS = 26 + +[topology] +MINIMUM-FRIENDS = 0 +FRIENDS-ONLY = NO +AUTOCONNECT = YES +TARGET-CONNECTION-COUNT = 16 +FRIENDS = $SERVICEHOME/friends +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-topology + +[datastore] +AUTOSTART = YES +UNIXPATH = /tmp/test-service-datastore-25 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PORT = 20032 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-datastore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +QUOTA = 100 MB +BLOOMFILTER = $SERVICEHOME/fs/bloomfilter +DATABASE = sqlite + +[datastore-sqlite] +FILENAME = $SERVICEHOME/datastore/sqlite.db + +[datastore-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[datastore-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[peerinfo] +AUTOSTART = YES +PORT = 20031 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-peerinfo +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-peerinfo-24 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTS = $SERVICEHOME/data/hosts/ + +[client] +HOME = $SERVICEHOME + +[TESTING] +WEAKRANDOM = NO +CONNECT_TIMEOUT = 30 s +CONNECT_ATTEMPTS = 3 +MAX_OUTSTANDING_CONNECTIONS = 50 +DELETE_FILES = YES + +[ats] +AUTOSTART = YES +PORT = 20030 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-ats +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-ats-23 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +WAN_QUOTA_IN = 65536 +WAN_QUOTA_OUT = 65536 +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 + +[transport] +PREFIX = valgrind --leak-check=full +#DEBUG = YES +AUTOSTART = YES +PORT = 20029 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-transport +NEIGHBOUR_LIMIT = 50 +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +PLUGINS = unix tcp udp http +UNIXPATH = /tmp/test-service-transport-22 +BLACKLIST_FILE = $SERVICEHOME/blacklist +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[transport-unix] +PORT = 22087 + +[transport-tcp] +USE_LOCALADDR = YES +PORT = 20028 +ADVERTISED_PORT = 20028 +MAX_CONNECTIONS = 128 +TIMEOUT = 5 s + +[transport-udp] +USE_LOCALADDR = YES +PORT = 20027 +BROADCAST = YES +BROADCAST_INTERVAL = 30000 +MAX_BPS = 1000000 + +[transport-http] +PORT = 0 +MAX_CONNECTIONS = 128 + +[transport-https] +PORT = 20025 +CRYPTO_INIT = NORMAL +KEY_FILE = https.key +CERT_FILE = https.cert +MAX_CONNECTIONS = 128 + +[transport-wlan] +INTERFACE = mon0 +TESTMODE = 0 + +[datacache-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[datacache-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[template] +AUTOSTART = NO +PORT = 20024 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-template +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-template-21 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[fs] +AUTOSTART = YES +INDEXDB = $SERVICEHOME/idxinfo.lst +TRUST = $SERVICEHOME/data/credit/ +IDENTITY_DIR = $SERVICEHOME/identities/ +STATE_DIR = $SERVICEHOME/persistence/ +UPDATE_DIR = $SERVICEHOME/updates/ +PORT = 20023 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-fs +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DELAY = YES +CONTENT_CACHING = YES +CONTENT_PUSHING = YES +UNIXPATH = /tmp/test-service-fs-20 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PENDING_REQUESTS = 65536 +MIN_MIGRATION_DELAY = 100 ms +EXPECTED_NEIGHBOUR_COUNT = 128 + +[vpn] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-vpn +IPV6ADDR = 1234::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.11.10.1 +IPV4MASK = 255.255.0.0 +VIRTDNS = 10.11.10.2 +VIRTDNS6 = 1234::17 +IFNAME = vpn-gnunet + +[exit] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-exit +IPV6ADDR = 1234:1::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.10.1.1 +IPV4MASK = 255.255.0.0 +IFNAME = exit-gnunet +ENABLE_UDP = NO +ENABLE_TCP = NO + +[dns] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-dns-19 +PROVIDE_EXIT = NO + +[arm] +PORT = 20022 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-arm +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DEFAULTSERVICES = topology hostlist fs core +UNIXPATH = /tmp/test-service-arm-18 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[hostlist] +HTTPPORT = 8080 +HOME = $SERVICEHOME +HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-hostlist +OPTIONS = -b +SERVERS = http://localhost:8080/ +HTTP-PROXY = + +[core] +AUTOSTART = YES +PORT = 20021 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-core +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-core-17 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nat] +EXTERNAL_ADDRESS = 127.0.0.1 +INTERNAL_ADDRESS = 127.0.0.1 +BINDTO = 127.0.0.1 +BEHIND_NAT = NO +PUNCHED_NAT = NO +ENABLE_UPNP = NO +USE_LOCALADDR = YES +USE_HOSTNAME = NO +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO +DISABLEV6 = YES +RETURN_LOCAL_ADDRESSES = NO +HOSTNAME_DNS_FREQUENCY = 1200000 +IFC_SCAN_FREQUENCY = 3000000 +DYNDNS_FREQUENCY = 140000 + +[gnunet-nat-server] +HOSTNAME = gnunet.org +PORT = 20020 + +[statistics] +AUTOSTART = YES +PORT = 20019 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-statistics +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-statistics-16 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES + +[dht] +AUTOSTART = YES +PORT = 20018 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dht +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +BUCKET_SIZE = 4 +UNIXPATH = /tmp/test-service-dht-15 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[dhtcache] +DATABASE = sqlite +QUOTA = 1 MB + diff --git a/src/integration-tests/confs/c_no_nat_client_unix_2.conf b/src/integration-tests/confs/c_no_nat_client_unix_2.conf new file mode 100644 index 0000000..6bf8e8b --- /dev/null +++ b/src/integration-tests/confs/c_no_nat_client_unix_2.conf @@ -0,0 +1,355 @@ +[PATHS] +SERVICEHOME = /tmp/c_no_nat_client_2/ +DEFAULTCONFIG = confs/c_no_nat_client_unix_2.conf + +[gnunetd] +#HOSTKEY = $SERVICEHOME/.hostkey +HOSTKEY = hostkeys/0002-hostkey + +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[resolver] +AUTOSTART = YES +PORT = 20053 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-resolver +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-resolver-42 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = NO + +[mesh] +AUTOSTART = YES +PORT = 20052 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-mesh +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-mesh-41 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nse] +AUTOSTART = YES +PORT = 20051 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-nse +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-nse-40 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PROOFFILE = $SERVICEHOME/.nse-proof +HISTOGRAM = $SERVICEHOME/nse-history.log +WORKDELAY = 5 ms +INTERVAL = 1 h +WORKBITS = 26 + +[topology] +MINIMUM-FRIENDS = 0 +FRIENDS-ONLY = NO +AUTOCONNECT = YES +TARGET-CONNECTION-COUNT = 16 +FRIENDS = $SERVICEHOME/friends +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-topology + +[datastore] +AUTOSTART = YES +UNIXPATH = /tmp/test-service-datastore-39 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PORT = 20050 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-datastore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +QUOTA = 100 MB +BLOOMFILTER = $SERVICEHOME/fs/bloomfilter +DATABASE = sqlite + +[datastore-sqlite] +FILENAME = $SERVICEHOME/datastore/sqlite.db + +[datastore-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[datastore-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[peerinfo] +AUTOSTART = YES +PORT = 20049 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-peerinfo +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-peerinfo-38 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTS = $SERVICEHOME/data/hosts/ + +[client] +HOME = $SERVICEHOME + +[TESTING] +WEAKRANDOM = NO +CONNECT_TIMEOUT = 30 s +CONNECT_ATTEMPTS = 3 +MAX_OUTSTANDING_CONNECTIONS = 50 +DELETE_FILES = YES + +[ats] +AUTOSTART = YES +PORT = 20048 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-ats +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-ats-37 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +WAN_QUOTA_IN = 65536 +WAN_QUOTA_OUT = 65536 +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 + +[transport] +PREFIX = valgrind --leak-check=full +#PREFIX = gdb --args +AUTOSTART = YES +PORT = 20047 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-transport +NEIGHBOUR_LIMIT = 50 +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +PLUGINS = unix tcp udp http +UNIXPATH = /tmp/test-service-transport-36 +BLACKLIST_FILE = $SERVICEHOME/blacklist +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[transport-unix] +PORT = 22086 + +[transport-tcp] +PORT = 20046 +ADVERTISED_PORT = 20046 +MAX_CONNECTIONS = 128 +TIMEOUT = 5 s +USE_LOCALADDR = YES + +[transport-udp] +PORT = 20045 +BROADCAST = YES +BROADCAST_INTERVAL = 30000 +MAX_BPS = 1000000 +USE_LOCALADDR = YES + +[transport-http] +PORT = 20044 +MAX_CONNECTIONS = 128 + +[transport-https] +PORT = 20043 +CRYPTO_INIT = NORMAL +KEY_FILE = https.key +CERT_FILE = https.cert +MAX_CONNECTIONS = 128 + +[transport-wlan] +INTERFACE = mon0 +TESTMODE = 0 + +[datacache-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[datacache-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[template] +AUTOSTART = NO +PORT = 20042 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-template +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-template-35 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[fs] +AUTOSTART = YES +INDEXDB = $SERVICEHOME/idxinfo.lst +TRUST = $SERVICEHOME/data/credit/ +IDENTITY_DIR = $SERVICEHOME/identities/ +STATE_DIR = $SERVICEHOME/persistence/ +UPDATE_DIR = $SERVICEHOME/updates/ +PORT = 20041 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-fs +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DELAY = YES +CONTENT_CACHING = YES +CONTENT_PUSHING = YES +UNIXPATH = /tmp/test-service-fs-34 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PENDING_REQUESTS = 65536 +MIN_MIGRATION_DELAY = 100 ms +EXPECTED_NEIGHBOUR_COUNT = 128 + +[vpn] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-vpn +IPV6ADDR = 1234::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.11.10.1 +IPV4MASK = 255.255.0.0 +VIRTDNS = 10.11.10.2 +VIRTDNS6 = 1234::17 +IFNAME = vpn-gnunet + +[exit] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-exit +IPV6ADDR = 1234:1::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.10.1.1 +IPV4MASK = 255.255.0.0 +IFNAME = exit-gnunet +ENABLE_UDP = NO +ENABLE_TCP = NO + +[dns] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-dns-33 +PROVIDE_EXIT = NO + +[arm] +PORT = 20040 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-arm +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DEFAULTSERVICES = topology hostlist fs core +UNIXPATH = /tmp/test-service-arm-32 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[hostlist] +HTTPPORT = 8080 +HOME = $SERVICEHOME +HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-hostlist +OPTIONS = -b +SERVERS = http://localhost:8080/ +HTTP-PROXY = + +[core] +AUTOSTART = YES +PORT = 20039 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-core +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-core-31 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nat] +BEHIND_NAT = NO +PUNCHED_NAT = NO +ENABLE_UPNP = NO +USE_LOCALADDR = YES +USE_HOSTNAME = NO +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO +DISABLEV6 = YES +RETURN_LOCAL_ADDRESSES = NO +HOSTNAME_DNS_FREQUENCY = 1200000 +IFC_SCAN_FREQUENCY = 3000000 +DYNDNS_FREQUENCY = 140000 +EXTERNAL_ADDRESS = 127.0.0.1 +INTERNAL_ADDRESS = 127.0.0.1 +BINDTO = 127.0.0.1 + +[gnunet-nat-server] +HOSTNAME = gnunet.org +PORT = 20038 + +[statistics] +AUTOSTART = YES +PORT = 20037 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-statistics +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-statistics-30 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES + +[dht] +AUTOSTART = YES +PORT = 20036 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dht +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +BUCKET_SIZE = 4 +UNIXPATH = /tmp/test-service-dht-29 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[dhtcache] +DATABASE = sqlite +QUOTA = 1 MB + diff --git a/src/integration-tests/confs/c_normal_client_tcp.conf b/src/integration-tests/confs/c_normal_client_tcp.conf new file mode 100644 index 0000000..45acdaf --- /dev/null +++ b/src/integration-tests/confs/c_normal_client_tcp.conf @@ -0,0 +1,360 @@ +[PATHS] +SERVICEHOME = /tmp/c_normal_client +DEFAULTCONFIG = confs/c_normal_client_tcp.conf + +[gnunetd] +HOSTKEY = hostkeys/0002-hostkey + +[client] +HOME = $SERVICEHOME + +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[vpn] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/gnunet-service-vpn-57 + + +[resolver] +AUTOSTART = YES +PORT = 20071 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-resolver +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-resolver-56 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = NO + +[mesh] +AUTOSTART = YES +PORT = 20070 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-mesh +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-mesh-55 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nse] +AUTOSTART = YES +PORT = 20069 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-nse +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-nse-54 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PROOFFILE = $SERVICEHOME/.nse-proof +HISTOGRAM = $SERVICEHOME/nse-history.log +WORKDELAY = 5 ms +INTERVAL = 1 h +WORKBITS = 26 + +[topology] +MINIMUM-FRIENDS = 0 +FRIENDS-ONLY = NO +AUTOCONNECT = YES +TARGET-CONNECTION-COUNT = 16 +FRIENDS = $SERVICEHOME/friends +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-topology + +[datastore] +AUTOSTART = YES +UNIXPATH = /tmp/test-service-datastore-53 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PORT = 20068 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-datastore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +QUOTA = 100 MB +BLOOMFILTER = $SERVICEHOME/fs/bloomfilter +DATABASE = sqlite + +[datastore-sqlite] +FILENAME = $SERVICEHOME/datastore/sqlite.db + +[datastore-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[datastore-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[peerinfo] +AUTOSTART = YES +PORT = 20067 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-peerinfo +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-peerinfo-52 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTS = $SERVICEHOME/data/hosts/ + +[TESTING] +WEAKRANDOM = NO +CONNECT_TIMEOUT = 30 s +CONNECT_ATTEMPTS = 3 +MAX_OUTSTANDING_CONNECTIONS = 50 +DELETE_FILES = YES + +[ats] +AUTOSTART = YES +PORT = 20066 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-ats +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-ats-51 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +WAN_QUOTA_IN = 65536 +WAN_QUOTA_OUT = 65536 +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 + +[transport] +AUTOSTART = YES +PORT = 20065 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-transport +NEIGHBOUR_LIMIT = 50 +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +PLUGINS = tcp +UNIXPATH = /tmp/test-service-transport-50 +BLACKLIST_FILE = $SERVICEHOME/blacklist +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[transport-tcp] +PORT = 0 +ADVERTISED_PORT = 20064 +MAX_CONNECTIONS = 128 +TIMEOUT = 5 s +USE_LOCALADDR = YES + +[transport-udp] +PORT = 0 +BROADCAST = YES +BROADCAST_INTERVAL = 30000 +MAX_BPS = 1000000 +USE_LOCALADDR = YES + +[transport-http] +PORT = 0 +MAX_CONNECTIONS = 128 + +[transport-https] +PORT = 0 +CRYPTO_INIT = NORMAL +KEY_FILE = https.key +CERT_FILE = https.cert +MAX_CONNECTIONS = 128 + +[transport-wlan] +INTERFACE = mon0 +TESTMODE = 0 + +[datacache-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[datacache-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[template] +AUTOSTART = NO +PORT = 20060 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-template +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-template-49 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[fs] +AUTOSTART = YES +INDEXDB = $SERVICEHOME/idxinfo.lst +TRUST = $SERVICEHOME/data/credit/ +IDENTITY_DIR = $SERVICEHOME/identities/ +STATE_DIR = $SERVICEHOME/persistence/ +UPDATE_DIR = $SERVICEHOME/updates/ +PORT = 20059 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-fs +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DELAY = YES +CONTENT_CACHING = YES +CONTENT_PUSHING = YES +UNIXPATH = /tmp/test-service-fs-48 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PENDING_REQUESTS = 65536 +MIN_MIGRATION_DELAY = 100 ms +EXPECTED_NEIGHBOUR_COUNT = 128 + +[vpn] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-vpn +IPV6ADDR = 1234::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.11.10.1 +IPV4MASK = 255.255.0.0 +VIRTDNS = 10.11.10.2 +VIRTDNS6 = 1234::17 +IFNAME = vpn-gnunet + +[exit] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-exit +IPV6ADDR = 1234:1::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.10.1.1 +IPV4MASK = 255.255.0.0 +IFNAME = exit-gnunet +ENABLE_UDP = NO +ENABLE_TCP = NO + +[dns] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-dns-47 +PROVIDE_EXIT = NO + +[arm] +PORT = 20058 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-arm +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DEFAULTSERVICES = topology hostlist fs +UNIXPATH = /tmp/test-service-arm-46 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[hostlist] +HTTPPORT = 8080 +HOME = $SERVICEHOME +HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-hostlist +OPTIONS = -b +SERVERS = http://v9.gnunet.org/hostlist http://ioerror.gnunet.org:65535/ +HTTP-PROXY = + +[core] +AUTOSTART = YES +PORT = 20057 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-core +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-core-45 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nat] +BEHIND_NAT = YES +PUNCHED_NAT = NO +ENABLE_UPNP = NO +USE_LOCALADDR = YES +USE_HOSTNAME = NO +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO +DISABLEV6 = YES +RETURN_LOCAL_ADDRESSES = NO +HOSTNAME_DNS_FREQUENCY = 1200000 +IFC_SCAN_FREQUENCY = 3000000 +DYNDNS_FREQUENCY = 140000 +EXTERNAL_ADDRESS = 127.0.0.1 +INTERNAL_ADDRESS = 127.0.0.1 +BINDTO = 127.0.0.1 + +[gnunet-nat-server] +HOSTNAME = gnunet.org +PORT = 20056 + +[statistics] +AUTOSTART = YES +PORT = 20055 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-statistics +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-statistics-44 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES + +[dht] +AUTOSTART = YES +PORT = 20054 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dht +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +BUCKET_SIZE = 4 +UNIXPATH = /tmp/test-service-dht-43 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[dhtcache] +DATABASE = sqlite +QUOTA = 1 MB \ No newline at end of file diff --git a/src/integration-tests/confs/c_normal_client_tcp_udp.conf b/src/integration-tests/confs/c_normal_client_tcp_udp.conf new file mode 100644 index 0000000..e568f12 --- /dev/null +++ b/src/integration-tests/confs/c_normal_client_tcp_udp.conf @@ -0,0 +1,360 @@ +[PATHS] +SERVICEHOME = /tmp/c_normal_client +DEFAULTCONFIG = confs/c_normal_client_tcp_udp.conf + +[gnunetd] +HOSTKEY = hostkeys/0002-hostkey + +[client] +HOME = $SERVICEHOME + +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[vpn] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/gnunet-service-vpn-57 + + +[resolver] +AUTOSTART = YES +PORT = 20071 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-resolver +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-resolver-56 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = NO + +[mesh] +AUTOSTART = YES +PORT = 20070 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-mesh +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-mesh-55 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nse] +AUTOSTART = YES +PORT = 20069 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-nse +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-nse-54 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PROOFFILE = $SERVICEHOME/.nse-proof +HISTOGRAM = $SERVICEHOME/nse-history.log +WORKDELAY = 5 ms +INTERVAL = 1 h +WORKBITS = 26 + +[topology] +MINIMUM-FRIENDS = 0 +FRIENDS-ONLY = NO +AUTOCONNECT = YES +TARGET-CONNECTION-COUNT = 16 +FRIENDS = $SERVICEHOME/friends +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-topology + +[datastore] +AUTOSTART = YES +UNIXPATH = /tmp/test-service-datastore-53 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PORT = 20068 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-datastore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +QUOTA = 100 MB +BLOOMFILTER = $SERVICEHOME/fs/bloomfilter +DATABASE = sqlite + +[datastore-sqlite] +FILENAME = $SERVICEHOME/datastore/sqlite.db + +[datastore-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[datastore-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[peerinfo] +AUTOSTART = YES +PORT = 20067 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-peerinfo +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-peerinfo-52 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTS = $SERVICEHOME/data/hosts/ + +[TESTING] +WEAKRANDOM = NO +CONNECT_TIMEOUT = 30 s +CONNECT_ATTEMPTS = 3 +MAX_OUTSTANDING_CONNECTIONS = 50 +DELETE_FILES = YES + +[ats] +AUTOSTART = YES +PORT = 20066 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-ats +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-ats-51 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +WAN_QUOTA_IN = 65536 +WAN_QUOTA_OUT = 65536 +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 + +[transport] +AUTOSTART = YES +PORT = 20065 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-transport +NEIGHBOUR_LIMIT = 50 +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +PLUGINS = tcp udp +UNIXPATH = /tmp/test-service-transport-50 +BLACKLIST_FILE = $SERVICEHOME/blacklist +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[transport-tcp] +PORT = 0 +ADVERTISED_PORT = 20064 +MAX_CONNECTIONS = 128 +TIMEOUT = 5 s +USE_LOCALADDR = YES + +[transport-udp] +PORT = 0 +BROADCAST = YES +BROADCAST_INTERVAL = 30000 +MAX_BPS = 1000000 +USE_LOCALADDR = YES + +[transport-http] +PORT = 0 +MAX_CONNECTIONS = 128 + +[transport-https] +PORT = 0 +CRYPTO_INIT = NORMAL +KEY_FILE = https.key +CERT_FILE = https.cert +MAX_CONNECTIONS = 128 + +[transport-wlan] +INTERFACE = mon0 +TESTMODE = 0 + +[datacache-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[datacache-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[template] +AUTOSTART = NO +PORT = 20060 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-template +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-template-49 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[fs] +AUTOSTART = YES +INDEXDB = $SERVICEHOME/idxinfo.lst +TRUST = $SERVICEHOME/data/credit/ +IDENTITY_DIR = $SERVICEHOME/identities/ +STATE_DIR = $SERVICEHOME/persistence/ +UPDATE_DIR = $SERVICEHOME/updates/ +PORT = 20059 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-fs +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DELAY = YES +CONTENT_CACHING = YES +CONTENT_PUSHING = YES +UNIXPATH = /tmp/test-service-fs-48 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PENDING_REQUESTS = 65536 +MIN_MIGRATION_DELAY = 100 ms +EXPECTED_NEIGHBOUR_COUNT = 128 + +[vpn] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-vpn +IPV6ADDR = 1234::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.11.10.1 +IPV4MASK = 255.255.0.0 +VIRTDNS = 10.11.10.2 +VIRTDNS6 = 1234::17 +IFNAME = vpn-gnunet + +[exit] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-exit +IPV6ADDR = 1234:1::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.10.1.1 +IPV4MASK = 255.255.0.0 +IFNAME = exit-gnunet +ENABLE_UDP = NO +ENABLE_TCP = NO + +[dns] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-dns-47 +PROVIDE_EXIT = NO + +[arm] +PORT = 20058 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-arm +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DEFAULTSERVICES = topology hostlist fs +UNIXPATH = /tmp/test-service-arm-46 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[hostlist] +HTTPPORT = 8080 +HOME = $SERVICEHOME +HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-hostlist +OPTIONS = -b +SERVERS = http://v9.gnunet.org/hostlist http://ioerror.gnunet.org:65535/ +HTTP-PROXY = + +[core] +AUTOSTART = YES +PORT = 20057 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-core +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-core-45 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nat] +BEHIND_NAT = YES +PUNCHED_NAT = NO +ENABLE_UPNP = NO +USE_LOCALADDR = YES +USE_HOSTNAME = NO +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO +DISABLEV6 = YES +RETURN_LOCAL_ADDRESSES = NO +HOSTNAME_DNS_FREQUENCY = 1200000 +IFC_SCAN_FREQUENCY = 3000000 +DYNDNS_FREQUENCY = 140000 +EXTERNAL_ADDRESS = 127.0.0.1 +INTERNAL_ADDRESS = 127.0.0.1 +BINDTO = 127.0.0.1 + +[gnunet-nat-server] +HOSTNAME = gnunet.org +PORT = 20056 + +[statistics] +AUTOSTART = YES +PORT = 20055 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-statistics +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-statistics-44 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES + +[dht] +AUTOSTART = YES +PORT = 20054 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dht +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +BUCKET_SIZE = 4 +UNIXPATH = /tmp/test-service-dht-43 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[dhtcache] +DATABASE = sqlite +QUOTA = 1 MB \ No newline at end of file diff --git a/src/integration-tests/confs/c_normal_client_tcp_udp_http.conf b/src/integration-tests/confs/c_normal_client_tcp_udp_http.conf new file mode 100644 index 0000000..93275bf --- /dev/null +++ b/src/integration-tests/confs/c_normal_client_tcp_udp_http.conf @@ -0,0 +1,360 @@ +[PATHS] +SERVICEHOME = /tmp/c_normal_client +DEFAULTCONFIG = confs/c_normal_client_tcp_udp_http.conf + +[gnunetd] +HOSTKEY = hostkeys/0002-hostkey + +[client] +HOME = $SERVICEHOME + +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[vpn] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/gnunet-service-vpn-57 + + +[resolver] +AUTOSTART = YES +PORT = 20071 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-resolver +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-resolver-56 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = NO + +[mesh] +AUTOSTART = YES +PORT = 20070 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-mesh +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-mesh-55 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nse] +AUTOSTART = YES +PORT = 20069 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-nse +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-nse-54 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PROOFFILE = $SERVICEHOME/.nse-proof +HISTOGRAM = $SERVICEHOME/nse-history.log +WORKDELAY = 5 ms +INTERVAL = 1 h +WORKBITS = 26 + +[topology] +MINIMUM-FRIENDS = 0 +FRIENDS-ONLY = NO +AUTOCONNECT = YES +TARGET-CONNECTION-COUNT = 16 +FRIENDS = $SERVICEHOME/friends +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-topology + +[datastore] +AUTOSTART = YES +UNIXPATH = /tmp/test-service-datastore-53 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +PORT = 20068 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-datastore +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +QUOTA = 100 MB +BLOOMFILTER = $SERVICEHOME/fs/bloomfilter +DATABASE = sqlite + +[datastore-sqlite] +FILENAME = $SERVICEHOME/datastore/sqlite.db + +[datastore-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[datastore-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[peerinfo] +AUTOSTART = YES +PORT = 20067 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-peerinfo +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-peerinfo-52 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +HOSTS = $SERVICEHOME/data/hosts/ + +[TESTING] +WEAKRANDOM = NO +CONNECT_TIMEOUT = 30 s +CONNECT_ATTEMPTS = 3 +MAX_OUTSTANDING_CONNECTIONS = 50 +DELETE_FILES = YES + +[ats] +AUTOSTART = YES +PORT = 20066 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-ats +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-ats-51 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES +WAN_QUOTA_IN = 65536 +WAN_QUOTA_OUT = 65536 +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 + +[transport] +AUTOSTART = YES +PORT = 20065 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-transport +NEIGHBOUR_LIMIT = 50 +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +PLUGINS = tcp udp http +UNIXPATH = /tmp/test-service-transport-50 +BLACKLIST_FILE = $SERVICEHOME/blacklist +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[transport-tcp] +PORT = 0 +ADVERTISED_PORT = 20064 +MAX_CONNECTIONS = 128 +TIMEOUT = 5 s +USE_LOCALADDR = YES + +[transport-udp] +PORT = 0 +BROADCAST = YES +BROADCAST_INTERVAL = 30000 +MAX_BPS = 1000000 +USE_LOCALADDR = YES + +[transport-http] +PORT = 0 +MAX_CONNECTIONS = 128 + +[transport-https] +PORT = 0 +CRYPTO_INIT = NORMAL +KEY_FILE = https.key +CERT_FILE = https.cert +MAX_CONNECTIONS = 128 + +[transport-wlan] +INTERFACE = mon0 +TESTMODE = 0 + +[datacache-mysql] +DATABASE = gnunet +CONFIG = ~/.my.cnf + +[datacache-postgres] +CONFIG = connect_timeout=10; dbname=gnunet + +[template] +AUTOSTART = NO +PORT = 20060 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-template +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-template-49 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[fs] +AUTOSTART = YES +INDEXDB = $SERVICEHOME/idxinfo.lst +TRUST = $SERVICEHOME/data/credit/ +IDENTITY_DIR = $SERVICEHOME/identities/ +STATE_DIR = $SERVICEHOME/persistence/ +UPDATE_DIR = $SERVICEHOME/updates/ +PORT = 20059 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-fs +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DELAY = YES +CONTENT_CACHING = YES +CONTENT_PUSHING = YES +UNIXPATH = /tmp/test-service-fs-48 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES +MAX_PENDING_REQUESTS = 65536 +MIN_MIGRATION_DELAY = 100 ms +EXPECTED_NEIGHBOUR_COUNT = 128 + +[vpn] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-vpn +IPV6ADDR = 1234::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.11.10.1 +IPV4MASK = 255.255.0.0 +VIRTDNS = 10.11.10.2 +VIRTDNS6 = 1234::17 +IFNAME = vpn-gnunet + +[exit] +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-exit +IPV6ADDR = 1234:1::1 +IPV6PREFIX = 32 +IPV4ADDR = 10.10.1.1 +IPV4MASK = 255.255.0.0 +IFNAME = exit-gnunet +ENABLE_UDP = NO +ENABLE_TCP = NO + +[dns] +AUTOSTART = YES +PORT = 0 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dns +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-dns-47 +PROVIDE_EXIT = NO + +[arm] +PORT = 20058 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-arm +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +DEFAULTSERVICES = topology hostlist fs +UNIXPATH = /tmp/test-service-arm-46 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[hostlist] +HTTPPORT = 8080 +HOME = $SERVICEHOME +HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-hostlist +OPTIONS = -b +SERVERS = http://v9.gnunet.org/hostlist http://ioerror.gnunet.org:65535/ +HTTP-PROXY = + +[core] +AUTOSTART = YES +PORT = 20057 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-core +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-core-45 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[nat] +BEHIND_NAT = YES +PUNCHED_NAT = NO +ENABLE_UPNP = NO +USE_LOCALADDR = YES +USE_HOSTNAME = NO +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO +DISABLEV6 = YES +RETURN_LOCAL_ADDRESSES = NO +HOSTNAME_DNS_FREQUENCY = 1200000 +IFC_SCAN_FREQUENCY = 3000000 +DYNDNS_FREQUENCY = 140000 +EXTERNAL_ADDRESS = 127.0.0.1 +INTERNAL_ADDRESS = 127.0.0.1 +BINDTO = 127.0.0.1 + +[gnunet-nat-server] +HOSTNAME = gnunet.org +PORT = 20056 + +[statistics] +AUTOSTART = YES +PORT = 20055 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-statistics +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/test-service-statistics-44 +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES + +[dht] +AUTOSTART = YES +PORT = 20054 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-dht +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +BUCKET_SIZE = 4 +UNIXPATH = /tmp/test-service-dht-43 +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +[dhtcache] +DATABASE = sqlite +QUOTA = 1 MB \ No newline at end of file diff --git a/src/integration-tests/connection_watchdog.c b/src/integration-tests/connection_watchdog.c new file mode 100644 index 0000000..ac19338 --- /dev/null +++ b/src/integration-tests/connection_watchdog.c @@ -0,0 +1,1099 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file integration-tests/connection_watchdog.c + * @brief tool to monitor core and transport connections for consistency + * @author Matthias Wachs + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_constants.h" +#include "gnunet_arm_service.h" +#include "gnunet_core_service.h" +#include "gnunet_getopt_lib.h" +#include "gnunet_os_lib.h" +#include "gnunet_program_lib.h" +#include "gnunet_scheduler_lib.h" +#include "gnunet_transport_service.h" +#include "gnunet_statistics_service.h" + + +#define CHECK_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) +#define STATS_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) +#define REPEATED_STATS_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) +#define STATS_VALUES 4 + +/** + * Final status code. + */ +static int ret; +static int ping; + +static int have_tcp; +static int have_udp; +static int have_http; +static int have_https; +static int have_unix; + +static struct GNUNET_TRANSPORT_Handle *th; +static struct GNUNET_CORE_Handle *ch; +static struct GNUNET_PeerIdentity my_peer_id; +static const struct GNUNET_CONFIGURATION_Handle *mycfg; +static struct GNUNET_STATISTICS_Handle *stats; + + +static unsigned int transport_connections; +static unsigned int core_connections; + +static GNUNET_SCHEDULER_TaskIdentifier check_task; +static GNUNET_SCHEDULER_TaskIdentifier statistics_task; + +static uint64_t statistics_transport_connections; +static uint64_t statistics_transport_tcp_connections; +static uint64_t statistics_core_neighbour_entries; +static uint64_t statistics_core_entries_session_map; + +int stat_check_running; + +static struct GNUNET_CONTAINER_MultiHashMap *peers; + +struct PeerContainer +{ + struct GNUNET_PeerIdentity id; + int transport_connected; + int core_connected; + struct GNUNET_TRANSPORT_TransmitHandle *th_ping; + struct GNUNET_CORE_TransmitHandle *ch_ping; + + struct GNUNET_TRANSPORT_TransmitHandle *th_pong; + struct GNUNET_CORE_TransmitHandle *ch_pong; +}; + + +enum protocol +{ + tcp, + udp, + unixdomain +}; + +struct TransportPlugin +{ + /** + * This is a doubly-linked list. + */ + struct TransportPlugin *next; + + /** + * This is a doubly-linked list. + */ + struct TransportPlugin *prev; + + /** + * Short name for the plugin (i.e. "tcp"). + */ + char *short_name; + + int port; + + int protocol; +}; + +struct TransportPlugin *phead; +struct TransportPlugin *ptail; + +static int +map_check_it (void *cls, + const GNUNET_HashCode * key, + void *value) +{ + int *fail = cls; + struct PeerContainer *pc = value; + if (pc->core_connected != pc->transport_connected) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Inconsistent peer `%s': TRANSPORT %s <-> CORE %s\n", + GNUNET_i2s (&pc->id), + (GNUNET_YES == pc->transport_connected) ? "YES" : "NO", + (GNUNET_YES == pc->core_connected) ? "YES" : "NO"); + (*fail) ++; + } + + return GNUNET_OK; +} + + +static int +map_cleanup_it (void *cls, + const GNUNET_HashCode * key, + void *value) +{ + struct PeerContainer *pc = value; + GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove(peers, key, value)); + if (NULL != pc->th_ping) + { + GNUNET_TRANSPORT_notify_transmit_ready_cancel(pc->th_ping); + pc->th_ping = NULL; + } + if (NULL != pc->th_pong) + { + GNUNET_TRANSPORT_notify_transmit_ready_cancel(pc->th_pong); + pc->th_pong = NULL; + } + if (NULL != pc->ch_ping) + { + GNUNET_CORE_notify_transmit_ready_cancel (pc->ch_ping); + pc->ch_ping = NULL; + } + if (NULL != pc->ch_pong) + { + GNUNET_CORE_notify_transmit_ready_cancel(pc->ch_pong); + pc->ch_pong = NULL; + } + GNUNET_free (pc); + return GNUNET_OK; +} + +static void +map_cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_CONTAINER_multihashmap_iterate (peers, &map_cleanup_it, NULL); + GNUNET_CONTAINER_multihashmap_destroy(peers); +} + +static void +map_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + int fail = 0; + check_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_CONTAINER_multihashmap_iterate (peers, &map_check_it, &fail); + if (0 > fail) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Inconsistent peers after connection consistency check: %u\n", fail); + else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Inconsistent peers after connection consistency check: %u\n", fail); + + + if (NULL != cls) + { + GNUNET_SCHEDULER_add_now (cls, NULL); + } +} + + +static void +stats_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + +static int +check_lowlevel_connections (int port, int protocol) +{ + FILE *f; + char * cmdline; + char * proto; + char line[1024]; + int count = -1; +#ifdef MINGW + /* not supported */ + return count; +#else + + switch (protocol) { + case tcp: + proto = "-t"; + break; + case udp: + proto = "-u"; + break; + case unixdomain: + proto = "-x"; + break; + default: + proto = ""; + break; + } + + /* Use netstat to get a numeric list of all connections on port 'port' in state 'ESTABLISHED' */ + GNUNET_asprintf(&cmdline, "netstat -n %s | grep %u | grep ESTABLISHED", proto, port); + + if (system ("netstat -n > /dev/null 2> /dev/null")) + if (system ("netstat -n > /dev/null 2> /dev/null") == 0) + f = popen (cmdline, "r"); + else + f = NULL; + else + f = popen (cmdline, "r"); + if (!f) + { + GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "ss"); + GNUNET_free (cmdline); + return -1; + } + + count = 0; + while (NULL != fgets (line, sizeof (line), f)) + { + /* read */ + //printf ("%s", line); + count ++; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i TCP connections established with port %u\n", + count, port); + + pclose (f); + GNUNET_free (cmdline); + return count; +#endif +} + + +static struct TransportPlugin * +find_plugin (char * name) +{ + struct TransportPlugin *cur = NULL; + + for (cur = phead; cur != NULL; cur = cur->next) + { + if (0 == strcmp(name, cur->short_name)) + return cur; + } + return cur; +} + +static int +stats_check_cb (void *cls, const char *subsystem, + const char *name, uint64_t value, + int is_persistent) +{ + static int counter; + + uint64_t *val = cls; + + if (NULL != val) + (*val) = value; + + counter ++; + if ((STATS_VALUES == counter) || ((GNUNET_NO == have_tcp) && (STATS_VALUES - 1 == counter))) + { + int fail = GNUNET_NO; + + + + int low_level_connections_udp = check_lowlevel_connections (2086, udp); + + if (transport_connections != core_connections) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%u transport notifications <-> %u core notifications\n", + transport_connections, core_connections); + fail = GNUNET_YES; + } + + if (transport_connections != statistics_transport_connections) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%u transport notifications <-> %u in statistics (peers connected)\n", + transport_connections, statistics_transport_connections); + fail = GNUNET_YES; + } + + if (core_connections != statistics_core_entries_session_map) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%u core notifications <-> %u in statistics (entries session map)\n", + core_connections, statistics_core_entries_session_map); + fail = GNUNET_YES; + } + + if (core_connections != statistics_core_neighbour_entries) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%u core notifications <-> %u in statistics (neighbour entries allocated)\n", + core_connections, statistics_core_neighbour_entries); + fail = GNUNET_YES; + } + + if (GNUNET_NO == fail) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Check successful : (%u transport / %u core) connections established\n", transport_connections, core_connections); + + /* TCP plugin specific checks */ + if (GNUNET_YES == have_tcp) + { + struct TransportPlugin * p = find_plugin ("tcp"); + int low_level_connections_tcp = check_lowlevel_connections (p->port, p->protocol); + + if (low_level_connections_tcp != -1) + { + if (statistics_transport_tcp_connections > low_level_connections_tcp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%u transport tcp sessions <-> %i established tcp connections\n", + statistics_transport_tcp_connections, low_level_connections_tcp); + fail = GNUNET_YES; + } + else if (low_level_connections_tcp != -1) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "%u TCP connections, %u UDP connections \n", + low_level_connections_tcp, low_level_connections_udp); + } + } + if (transport_connections > statistics_transport_tcp_connections) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%u transport notifications <-> %u in statistics (statistics_transport_tcp_connections)\n", + transport_connections, statistics_transport_tcp_connections); + fail = GNUNET_YES; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " %u transport notifications <-> %u in statistics (statistics_transport_tcp_connections)\n", + transport_connections, statistics_transport_tcp_connections); + } + } + + if (GNUNET_SCHEDULER_NO_TASK == statistics_task) + statistics_task = GNUNET_SCHEDULER_add_delayed(REPEATED_STATS_DELAY, &stats_check, NULL); + + stat_check_running = GNUNET_NO; + counter = 0; + } + + return GNUNET_OK; +} + +GNUNET_NETWORK_STRUCT_BEGIN + +struct PING +{ + struct GNUNET_MessageHeader header; + + uint16_t src; +}; + +struct PONG +{ + struct GNUNET_MessageHeader header; + + uint16_t src; +}; +GNUNET_NETWORK_STRUCT_END + + +static size_t +send_transport_ping_cb (void *cls, size_t size, void *buf) +{ + struct PeerContainer * pc = cls; + struct PING ping; + size_t mlen = sizeof (struct PING); + + if (size < mlen) + { + GNUNET_break (0); + return 0; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending transport ping to `%s'\n", GNUNET_i2s (&pc->id)); + ping.header.size = htons (mlen); + ping.header.type = htons (1234); + ping.src = htons (0); + + pc->th_ping = NULL; + + memcpy (buf, &ping, mlen); + return mlen; +} + +size_t send_core_ping_cb (void *cls, size_t size, void *buf) +{ +struct PeerContainer * pc = cls; +struct PING ping; +size_t mlen = sizeof (struct PING); + +if (size < mlen) +{ + GNUNET_break (0); + return 0; +} + +GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending core ping to `%s'\n", GNUNET_i2s (&pc->id)); +ping.header.size = htons (mlen); +ping.header.type = htons (1234); +ping.src = htons (1); + +pc->ch_ping = NULL; + +memcpy (buf, &ping, mlen); +return mlen; +} + + +int map_ping_it (void *cls, + const GNUNET_HashCode * key, + void *value) +{ + struct PeerContainer *pc = value; + + if (ping == GNUNET_YES) + { + if ((GNUNET_YES == pc->transport_connected) && (NULL == pc->th_ping)) + pc->th_ping = GNUNET_TRANSPORT_notify_transmit_ready(th, &pc->id, + sizeof (struct PING), UINT_MAX, + GNUNET_TIME_UNIT_FOREVER_REL, &send_transport_ping_cb, pc); + else + GNUNET_break(0); + + if ((GNUNET_YES == pc->core_connected) && (NULL == pc->ch_ping)) + pc->ch_ping = GNUNET_CORE_notify_transmit_ready(ch, + GNUNET_NO, UINT_MAX, + GNUNET_TIME_UNIT_FOREVER_REL, + &pc->id, + sizeof (struct PING), + send_core_ping_cb, pc); + else + GNUNET_break (0); + } + return GNUNET_OK; +} + + +static void +stats_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + statistics_task = GNUNET_SCHEDULER_NO_TASK; + + if (GNUNET_YES == stat_check_running) + { + statistics_task = GNUNET_SCHEDULER_add_delayed(STATS_DELAY, &stats_check, NULL); + } + + GNUNET_CONTAINER_multihashmap_iterate (peers, &map_ping_it, NULL); + + stat_check_running = GNUNET_YES; + + statistics_transport_connections = 0 ; + statistics_core_entries_session_map = 0; + statistics_core_neighbour_entries = 0; + + GNUNET_STATISTICS_get (stats, "transport", "# peers connected", GNUNET_TIME_UNIT_MINUTES, NULL, &stats_check_cb, &statistics_transport_connections); + GNUNET_STATISTICS_get (stats, "core", "# neighbour entries allocated", GNUNET_TIME_UNIT_MINUTES, NULL, &stats_check_cb, &statistics_core_neighbour_entries); + GNUNET_STATISTICS_get (stats, "core", "# peers connected", GNUNET_TIME_UNIT_MINUTES, NULL, &stats_check_cb, &statistics_core_entries_session_map); + + /* TCP plugin specific checks */ + if (GNUNET_YES == have_tcp) + GNUNET_STATISTICS_get (stats, "transport", "# TCP sessions active", GNUNET_TIME_UNIT_MINUTES, NULL, &stats_check_cb, &statistics_transport_tcp_connections); +} + + + +size_t send_transport_pong_cb (void *cls, size_t size, void *buf) +{ + struct PeerContainer * pc = cls; + struct PING ping; + size_t mlen = sizeof (struct PING); + + if (size < mlen) + { + GNUNET_break (0); + return 0; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending transport pong to `%s'\n", GNUNET_i2s (&pc->id)); + ping.header.size = htons (mlen); + ping.header.type = htons (4321); + ping.src = htons (0); + + pc->th_pong = NULL; + + memcpy (buf, &ping, mlen); + return mlen; +} + +static size_t +send_core_pong_cb (void *cls, size_t size, void *buf) +{ +struct PeerContainer * pc = cls; +struct PING ping; +size_t mlen = sizeof (struct PING); + +if (size < mlen) +{ + GNUNET_break (0); + return 0; +} + +GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending core pong to `%s'\n", GNUNET_i2s (&pc->id)); +ping.header.size = htons (mlen); +ping.header.type = htons (4321); +ping.src = htons (1); + +pc->ch_pong = NULL; + +memcpy (buf, &ping, mlen); +return mlen; +} + + +static void +map_connect (const struct GNUNET_PeerIdentity *peer, void * source) +{ + struct PeerContainer * pc; + if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(peers, &peer->hashPubKey)) + { + pc = GNUNET_malloc (sizeof (struct PeerContainer)); + pc->id = *peer; + pc->core_connected = GNUNET_NO; + pc->transport_connected = GNUNET_NO; + GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(peers, &peer->hashPubKey, pc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + } + + pc = GNUNET_CONTAINER_multihashmap_get(peers, &peer->hashPubKey); + if (source == th) + { + if (GNUNET_NO == pc->transport_connected) + { + pc->transport_connected = GNUNET_YES; + if (GNUNET_YES == ping) + { + if (NULL == pc->th_ping) + pc->th_ping = GNUNET_TRANSPORT_notify_transmit_ready(th, peer, sizeof (struct PING), UINT_MAX, GNUNET_TIME_UNIT_FOREVER_REL, &send_transport_ping_cb, pc); + else + GNUNET_break(0); + } + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%s notified multiple times about for peers `%s' (%s : %s)\n", + "TRANSPORT", + GNUNET_i2s (&pc->id), + "CORE", (pc->core_connected == GNUNET_YES) ? "yes" : "no"); + GNUNET_break (0); + } + } + if (source == ch) + { + if (GNUNET_NO == pc->core_connected) + { + pc->core_connected = GNUNET_YES; + if (GNUNET_YES == ping) + { + if (NULL == pc->ch_ping) + pc->ch_ping = GNUNET_CORE_notify_transmit_ready(ch, + GNUNET_NO, UINT_MAX, + GNUNET_TIME_UNIT_FOREVER_REL, + peer, + sizeof (struct PING), + send_core_ping_cb, pc); + else + GNUNET_break (0); + } + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%s notified multiple times about for peers `%s' (%s : %s)\n", + "CORE", + GNUNET_i2s (&pc->id), + "TRANSPORT", (pc->transport_connected == GNUNET_YES) ? "yes" : "no"); + GNUNET_break (0); + } + } + if (GNUNET_SCHEDULER_NO_TASK != check_task) + GNUNET_SCHEDULER_cancel(check_task); + check_task = GNUNET_SCHEDULER_add_delayed(CHECK_DELAY, &map_check, NULL); + + if (GNUNET_SCHEDULER_NO_TASK != statistics_task) + GNUNET_SCHEDULER_cancel(statistics_task); + statistics_task = GNUNET_SCHEDULER_add_delayed(STATS_DELAY, &stats_check, NULL); +} + + +static void +map_disconnect (const struct GNUNET_PeerIdentity * peer, void * source) +{ + + struct PeerContainer * pc; + if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(peers, &peer->hashPubKey)) + { + if (source == th) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%s disconnect notification for unknown peer `%s'\n", + "TRANSPORT", GNUNET_i2s (peer)); + GNUNET_break (0); + return; + } + if (source == ch) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%s disconnect notification for unknown peer `%s'\n", + "CORE", GNUNET_i2s (peer)); + return; + } + } + + pc = GNUNET_CONTAINER_multihashmap_get(peers, &peer->hashPubKey); + if (source == th) + { + if (NULL != pc->th_ping) + { + GNUNET_TRANSPORT_notify_transmit_ready_cancel(pc->th_ping); + pc->th_ping = NULL; + } + if (NULL != pc->th_pong) + { + GNUNET_TRANSPORT_notify_transmit_ready_cancel(pc->th_pong); + pc->th_pong = NULL; + } + + if (GNUNET_YES == pc->transport_connected) + { + pc->transport_connected = GNUNET_NO; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%s notified for not connected peer `%s' (%s : %s)\n", + "TRANSPORT", + GNUNET_i2s (&pc->id), + "CORE", (pc->core_connected == GNUNET_YES) ? "yes" : "no"); + GNUNET_break (0); + } + } + if (source == ch) + { + if (NULL != pc->ch_ping) + { + GNUNET_CORE_notify_transmit_ready_cancel (pc->ch_ping); + pc->ch_ping = NULL; + } + if (NULL != pc->ch_pong) + { + GNUNET_CORE_notify_transmit_ready_cancel (pc->ch_pong); + pc->ch_pong = NULL; + } + + if (GNUNET_YES == pc->core_connected) + { + pc->core_connected = GNUNET_NO; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "%s notified for not connected peer `%s' (%s : %s)\n", + "CORE", + GNUNET_i2s (&pc->id), + "TRANSPORT", (pc->transport_connected == GNUNET_YES) ? "yes" : "no"); + GNUNET_break (0); + } + } + + if ((GNUNET_NO == pc->core_connected) && (GNUNET_NO == pc->transport_connected)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing peer `%s'\n", GNUNET_i2s (&pc->id)); + GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (peers, &peer->hashPubKey, pc)); + + + GNUNET_free (pc); + } + + if (GNUNET_SCHEDULER_NO_TASK != check_task) + GNUNET_SCHEDULER_cancel(check_task); + check_task = GNUNET_SCHEDULER_add_delayed(CHECK_DELAY, &map_check, NULL); + + if (GNUNET_SCHEDULER_NO_TASK != statistics_task) + GNUNET_SCHEDULER_cancel(statistics_task); + statistics_task = GNUNET_SCHEDULER_add_delayed(STATS_DELAY, &stats_check, NULL); +} + + +static void +cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct TransportPlugin * cur = phead; + + if (NULL != th) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Disconnecting from transport service\n"); + GNUNET_TRANSPORT_disconnect (th); + th = NULL; + } + + + if (NULL != ch) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Disconnecting from core service\n"); + GNUNET_CORE_disconnect (ch); + ch = NULL; + } + + if (GNUNET_SCHEDULER_NO_TASK != statistics_task) + { + GNUNET_SCHEDULER_cancel(statistics_task); + statistics_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (GNUNET_SCHEDULER_NO_TASK != check_task) + { + GNUNET_SCHEDULER_cancel(check_task); + check_task = GNUNET_SCHEDULER_NO_TASK; + } + + for (cur = phead; cur != NULL; cur = phead) + { + GNUNET_CONTAINER_DLL_remove(phead, ptail, cur); + GNUNET_free (cur->short_name); + GNUNET_free (cur); + } + + check_task = GNUNET_SCHEDULER_add_now (&map_check, &map_cleanup); +} + +static void +transport_notify_connect_cb (void *cls, + const struct GNUNET_PeerIdentity + * peer, + const struct + GNUNET_ATS_Information * ats, + uint32_t ats_count) +{ + transport_connections ++; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "TRANSPORT connect for peer `%s' (%u total)\n", + GNUNET_i2s (peer), transport_connections); + map_connect (peer, th); +} + +/** + * Function called to notify transport users that another + * peer disconnected from us. + * + * @param cls closure + * @param peer the peer that disconnected + */ +static void +transport_notify_disconnect_cb (void *cls, + const struct + GNUNET_PeerIdentity * peer) +{ + GNUNET_assert (transport_connections > 0); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "TRANSPORT disconnect for peer `%s' (%u total)\n", + GNUNET_i2s (peer), transport_connections) ; + map_disconnect (peer, th); + transport_connections --; + +} + +static void +transport_notify_receive_cb (void *cls, + const struct + GNUNET_PeerIdentity * peer, + const struct + GNUNET_MessageHeader * + message, + const struct + GNUNET_ATS_Information * ats, + uint32_t ats_count) +{ + + + struct PeerContainer *pc = NULL; + + pc = GNUNET_CONTAINER_multihashmap_get(peers, &peer->hashPubKey); + + if (NULL == pc) + { + GNUNET_break (0); + return; + } + + if ((message->size == ntohs (sizeof (struct PING))) && (message->type == ntohs (1234))) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received %s %s from peer `%s'\n", + "TRANSPORT", + "PING", + GNUNET_i2s (peer)) ; + if (GNUNET_YES == ping) + { + if (NULL == pc->th_pong) + pc->th_pong = GNUNET_TRANSPORT_notify_transmit_ready(th, + peer, sizeof (struct PONG), + UINT_MAX, GNUNET_TIME_UNIT_FOREVER_REL, + &send_transport_pong_cb, pc); + else + GNUNET_break (0); + } + + } + if ((message->size == ntohs (sizeof (struct PONG))) && (message->type == ntohs (4321))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received %s %s from peer `%s'\n", + "TRANSPORT", + "PONG", + GNUNET_i2s (peer)); + } +} + +static int +core_notify_receive_cb (void *cls, + const struct GNUNET_PeerIdentity * peer, + const struct GNUNET_MessageHeader * message, + const struct GNUNET_ATS_Information* atsi, + unsigned int atsi_count) +{ + struct PeerContainer *pc = NULL; + + pc = GNUNET_CONTAINER_multihashmap_get(peers, &peer->hashPubKey); + + if (NULL == pc) + { + if (0 == memcmp (peer, &my_peer_id, sizeof (my_peer_id))) + return GNUNET_OK; + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received unexpected message type %u from unknown peer `%s'\n", + ntohs (message->type), + GNUNET_i2s (peer)); + + GNUNET_break (0); + return GNUNET_OK; + } + + if ((message->size == ntohs (sizeof (struct PING))) && (message->type == ntohs (1234))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received %s %s from peer `%s'\n", + "CORE", + "PING", + GNUNET_i2s (peer)); + if (GNUNET_YES == ping) + { + if (NULL == pc->ch_pong) + pc->ch_pong = GNUNET_CORE_notify_transmit_ready(ch, + GNUNET_NO, UINT_MAX, + GNUNET_TIME_UNIT_FOREVER_REL, + peer, + sizeof (struct PONG), + send_core_pong_cb, pc); + else + GNUNET_break (0); + } + } + + if ((message->size == ntohs (sizeof (struct PONG))) && (message->type == ntohs (4321))) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received %s %s from peer `%s'\n", + "CORE", + "PONG", + GNUNET_i2s (peer)); + + } + + return GNUNET_OK; +} + +static void +core_connect_cb (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count) +{ + if (0 != memcmp (peer, &my_peer_id, sizeof (struct GNUNET_PeerIdentity))) + { + core_connections ++; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CORE connect for peer `%s' (%u total)\n", + GNUNET_i2s (peer), core_connections); + map_connect (peer, ch); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CORE connect for myself `%s' (%u total)\n", + GNUNET_i2s (peer), core_connections); + } +} + +static void +core_disconnect_cb (void *cls, + const struct + GNUNET_PeerIdentity * peer) +{ + if (0 != memcmp (peer, &my_peer_id, sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_assert (core_connections > 0); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CORE disconnect for peer `%s' (%u total)\n", + GNUNET_i2s (peer), core_connections); + map_disconnect (peer, ch); + core_connections --; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CORE disconnect for myself `%s' (%u total)\n", + GNUNET_i2s (peer), core_connections); + } + +} + +static void +core_init_cb (void *cls, struct GNUNET_CORE_Handle *server, + const struct GNUNET_PeerIdentity *my_identity) +{ + my_peer_id = *my_identity; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to core service\n"); +} + + +static void +init () +{ + struct TransportPlugin * cur; + char *plugs; + char *pos; + char *secname; + int counter; + unsigned long long port; + + have_tcp = GNUNET_NO; + have_udp = GNUNET_NO; + have_http = GNUNET_NO; + have_https = GNUNET_NO; + have_unix = GNUNET_NO; + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (mycfg, "TRANSPORT", "PLUGINS", &plugs)) + return; + counter = 0; + for (pos = strtok (plugs, " "); pos != NULL; pos = strtok (NULL, " ")) + { + counter++; + + GNUNET_asprintf(&secname, "transport-%s", pos); + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (mycfg, secname, "PORT", &port)) + { + GNUNET_free (secname); + continue; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transport plugin: `%s' port %llu\n"), pos, port); + cur = GNUNET_malloc(sizeof (struct TransportPlugin)); + cur->short_name = GNUNET_strdup (pos); + cur->port = port; + if (0 == strcmp("tcp", pos)) + { + have_tcp = GNUNET_YES; + cur->protocol = tcp; + } + if (0 == strcmp("udp", pos)) + { + have_udp = GNUNET_YES; + cur->protocol = udp; + } + if (0 == strcmp("http", pos)) + { + have_http = GNUNET_YES; + cur->protocol = tcp; + } + if (0 == strcmp("https", pos)) + { + have_https = GNUNET_YES; + cur->protocol = tcp; + } + if (0 == strcmp("unix", pos)) + { + have_unix = GNUNET_YES; + cur->protocol = unixdomain; + } + + GNUNET_CONTAINER_DLL_insert(phead, ptail, cur); + GNUNET_free (secname); + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Found %u transport plugins: `%s'\n"), + counter, plugs); + + GNUNET_free (plugs); +} + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + transport_connections = 0; + core_connections = 0; + mycfg = cfg; + + init(); + + stats = GNUNET_STATISTICS_create ("watchdog", cfg); + peers = GNUNET_CONTAINER_multihashmap_create (20); + + th = GNUNET_TRANSPORT_connect(cfg, NULL, NULL, + &transport_notify_receive_cb, + &transport_notify_connect_cb, + &transport_notify_disconnect_cb); + GNUNET_assert (th != NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to transport service\n"); + ch = GNUNET_CORE_connect (cfg, 1, NULL, + &core_init_cb, + &core_connect_cb, + &core_disconnect_cb, + &core_notify_receive_cb, GNUNET_NO, + NULL, GNUNET_NO, + NULL); + GNUNET_assert (ch != NULL); + + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, NULL); + +} + + +/** + * The main function. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + ping = GNUNET_NO; + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'p', "ping", NULL, gettext_noop ("Send ping messages to test connectivity (default == NO)"), + GNUNET_NO, &GNUNET_GETOPT_set_one, &ping}, + GNUNET_GETOPT_OPTION_END + }; + return (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "cn", + gettext_noop ("help text"), options, &run, + NULL)) ? ret : 1; +} + +/* end of connection_watchdog.c */ diff --git a/src/integration-tests/gnunet_testing.py.in b/src/integration-tests/gnunet_testing.py.in index 79cbfe9..41e709f 100644 --- a/src/integration-tests/gnunet_testing.py.in +++ b/src/integration-tests/gnunet_testing.py.in @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!@PYTHON@ # This file is part of GNUnet. # (C) 2010 Christian Grothoff (and other contributing authors) # @@ -42,7 +42,6 @@ class Check: neg += 1 else: pos += 1 - self.test.p (str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled') return fulfilled def run_blocking (self, timeout, pos_cont, neg_cont): execs = 0; @@ -51,10 +50,23 @@ class Check: res = self.run() time.sleep(1) execs += 1 - if (res == False): - neg_cont (self) + if ((False == res) and (execs >= timeout)): + print ('Check had timeout after ' +str(timeout)+ ' seconds') + neg_cont (self) + elif ((False == res) and (execs >= timeout)): + neg_cont (self) else: pos_cont (self) + return res + def run_once (self, pos_cont, neg_cont): + execs = 0; + res = False + res = self.run() + if ((res == False) and (neg_cont != None)): + neg_cont (self) + if ((res == True) and (pos_cont != None)): + pos_cont (self) + return res def evaluate (self, failed_only): pos = 0 neg = 0 @@ -65,6 +77,10 @@ class Check: pos += 1 print (str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled') return self.fulfilled + def reset (self): + self.fulfilled = False + for c in self.conditions: + c.fulfilled = False class Condition: def __init__(self): @@ -115,7 +131,7 @@ class StatisticsCondition (Condition): self.result = -1; def check(self): if (self.fulfilled == False): - self.result = self.peer.get_statistics_value (self.subsystem, self.name); + self.result = self.peer.get_statistics_value (self.subsystem, self.name) if (str(self.result) == str(self.value)): self.fulfilled = True return True @@ -134,11 +150,52 @@ class StatisticsCondition (Condition): else: fail = "" op = " == " - if ((self.fulfilled == False) and (failed_only == True)): + if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)): print self.peer.id[:4] + " " +self.peer.cfg + " " + str(self.type) + ' condition in subsystem "' + self.subsystem.ljust(12) +'" : "' + self.name.ljust(30) +'" : (expected/real value) ' + str(self.value) + op + res + fail - elif (failed_only == False): - print self.peer.id[:4] + " " +self.peer.cfg + " " + str(self.type) + ' condition in subsystem "' + self.subsystem.ljust(12) +'" : "' + self.name.ljust(30) +'" : (expected/real value) ' + str(self.value) + op + res + fail return self.fulfilled + +# Specify two statistic values and check if they are equal +class EqualStatisticsCondition (Condition): + def __init__(self, peer, subsystem, name, peer2, subsystem2, name2): + self.fulfilled = False + self.type = 'equalstatistics' + self.peer = peer; + self.subsystem = subsystem; + self.name = name; + self.result = -1; + self.peer2 = peer2; + self.subsystem2 = subsystem2; + self.name2 = name2; + self.result2 = -1; + def check(self): + if (self.fulfilled == False): + self.result = self.peer.get_statistics_value (self.subsystem, self.name); + self.result2 = self.peer2.get_statistics_value (self.subsystem2, self.name2); + if (str(self.result) == str(self.result2)): + self.fulfilled = True + return True + else: + return False + else: + return True + def evaluate (self, failed_only): + if (self.result == -1): + res = 'NaN' + else: + res = str(self.result) + if (self.result2 == -1): + res2 = 'NaN' + else: + res2 = str(self.result2) + if (self.fulfilled == False): + fail = " FAIL!" + op = " != " + else: + fail = "" + op = " == " + if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)): + print self.peer.id[:4] + ' "' + self.subsystem.ljust(12) + '" "' + self.name.ljust(30) + '" == ' + str(self.result) +" " + self.peer2.id[:4] + ' "' + self.subsystem2.ljust(12) + '" '+ self.name2.ljust(30) + '" ' + str(self.result2) + return self.fulfilled class Test: def __init__(self, testname, verbose): @@ -224,7 +281,11 @@ class Peer: server.spawn (None, [self.test.gnunetstatistics, '-c', self.cfg ,'-q','-n', name, '-s', subsystem ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) #server.expect ("stdout", re.compile (r"")) test = server.read("stdout", 10240) - tests = test.partition('\n')[0] + tests = test.partition('\n') + # On W32 GNUnet outputs with \r\n, rather than \n + if os.name == 'nt' and tests[1] == '\n' and tests[0][-1] == '\r': + tests = (tests[0][:-1], tests[1], tests[2]) + tests = tests[0] if (tests.isdigit() == True): return tests else: diff --git a/src/integration-tests/test_connection_stability.c b/src/integration-tests/test_connection_stability.c new file mode 100644 index 0000000..ce6568b --- /dev/null +++ b/src/integration-tests/test_connection_stability.c @@ -0,0 +1,126 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file integretion-tests/test_connection_stability.c + * @brief testcase for connection stability + */ +#include "platform.h" +#include "gnunet_testing_lib.h" + +#define VERBOSE GNUNET_YES + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) + +static int ok; + +static void +end_cb (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Ending with error: %s\n", emsg); + ok = 1; + } + else + { +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon terminated, will now exit.\n"); +#endif + ok = 0; + } +} + + + +void +do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_TESTING_Daemon *d = cls; + + GNUNET_TESTING_daemon_stop (d, TIMEOUT, &end_cb, NULL, GNUNET_YES, GNUNET_NO); +} + + +static void +my_cb (void *cls, const struct GNUNET_PeerIdentity *id, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Daemon *d, const char *emsg) +{ + GNUNET_assert (id != NULL); +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Daemon `%s' started, will now stop it.\n", GNUNET_i2s (id)); +#endif + GNUNET_SCHEDULER_add_now (&do_shutdown, d); +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_TESTING_Daemon *d; + + ok = 1; +#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemon.\n"); +#endif + d = GNUNET_TESTING_daemon_start (cfg, TIMEOUT, GNUNET_NO, NULL, NULL, 0, NULL, + NULL, NULL, &my_cb, NULL); + GNUNET_assert (d != NULL); +} + +static int +check () +{ + char *const argv[] = { "test_connection_stability", + "-c", + "test_connection_stability.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, + "test-testing", "nohelp", options, &run, &ok); + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_log_setup ("test_connection_stability", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + + return ret; +} + +/* end of test_connection_stability.c */ diff --git a/src/integration-tests/test_connection_stability.conf b/src/integration-tests/test_connection_stability.conf new file mode 100644 index 0000000..ba2ae05 --- /dev/null +++ b/src/integration-tests/test_connection_stability.conf @@ -0,0 +1,82 @@ +[PATHS] +SERVICEHOME = /tmp/test_connection_stability/ +DEFAULTCONFIG = test_connection_stability.conf + +[resolver] +PORT = 2564 + +[transport] +PORT = 2565 +PLUGINS = tcp + +[arm] +PORT = 2566 +DEFAULTSERVICES = + +[statistics] +PORT = 2567 + +[transport-tcp] +PORT = 2568 +BINDTO = 127.0.0.1 + +[peerinfo] +PORT = 2569 + +[core] +PORT = 2570 + +[testing] +NUM_PEERS = 5 +WEAKRANDOM = YES +F2F = YES +HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat + +[dht] +AUTOSTART = NO + +[nat] +DISABLEV6 = YES +ENABLE_UPNP = NO +BEHIND_NAT = NO +ALLOW_NAT = NO +INTERNAL_ADDRESS = 127.0.0.1 +EXTERNAL_ADDRESS = 127.0.0.1 +USE_LOCALADDR = NO + +[dns] +AUTOSTART = NO + +[nse] +AUTOSTART = NO + +[mesh] +AUTOSTART = NO + +[datastore] +AUTOSTART = NO + +[fs] +AUTOSTART = NO + +[dv] +AUTOSTART = NO + +[chat] +AUTOSTART = NO + +[vpn] +AUTOSTART = NO + +[gns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[lockmanager] +AUTOSTART = NO + +[arm] +DEFAULTSERVICES = core + diff --git a/src/integration-tests/test_integration_bootstrap_and_connect.py.in b/src/integration-tests/test_integration_bootstrap_and_connect.py.in index 32995d2..1e71488 100755 --- a/src/integration-tests/test_integration_bootstrap_and_connect.py.in +++ b/src/integration-tests/test_integration_bootstrap_and_connect.py.in @@ -50,7 +50,7 @@ from gnunet_testing import * testname = "test_integration_bootstrap_and_connect" verbose = True -check_timeout = 30 +check_timeout = 180 def cleanup (): @@ -74,14 +74,14 @@ def check (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) check.add (StatisticsCondition (server, 'transport', '# peers connected',1)) check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (server, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (server, 'core', '# peers connected',1)) check.add (StatisticsCondition (server, 'topology', '# peers connected',1)) check.add (StatisticsCondition (server, 'fs', '# peers connected',1)) diff --git a/src/integration-tests/test_integration_bootstrap_and_connect_and_disconnect.py.in b/src/integration-tests/test_integration_bootstrap_and_connect_and_disconnect.py.in index b426182..aefb9cd 100755 --- a/src/integration-tests/test_integration_bootstrap_and_connect_and_disconnect.py.in +++ b/src/integration-tests/test_integration_bootstrap_and_connect_and_disconnect.py.in @@ -50,7 +50,7 @@ from gnunet_testing import * testname = "test_integration_bootstrap_and_connect" verbose = True -check_timeout = 30 +check_timeout = 180 def cleanup (): @@ -71,7 +71,7 @@ def success_cont (check): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',0)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',0)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',0)) + check.add (StatisticsCondition (client, 'core', '# peers connected',0)) check.add (StatisticsCondition (client, 'topology', '# peers connected',0)) check.add (StatisticsCondition (client, 'fs', '# peers connected',0)) @@ -86,14 +86,14 @@ def check (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) check.add (StatisticsCondition (server, 'transport', '# peers connected',1)) check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (server, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (server, 'core', '# peers connected',1)) check.add (StatisticsCondition (server, 'topology', '# peers connected',1)) check.add (StatisticsCondition (server, 'fs', '# peers connected',1)) diff --git a/src/integration-tests/test_integration_bootstrap_and_connect_and_disconnect_nat.py.in b/src/integration-tests/test_integration_bootstrap_and_connect_and_disconnect_nat.py.in index f055e79..88327bf 100755 --- a/src/integration-tests/test_integration_bootstrap_and_connect_and_disconnect_nat.py.in +++ b/src/integration-tests/test_integration_bootstrap_and_connect_and_disconnect_nat.py.in @@ -50,7 +50,7 @@ from gnunet_testing import * testname = "test_integration_bootstrap_and_connect" verbose = True -check_timeout = 30 +check_timeout = 180 def cleanup (): @@ -71,7 +71,7 @@ def success_cont (check): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',0)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',0)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',0)) + check.add (StatisticsCondition (client, 'core', '# peers connected',0)) check.add (StatisticsCondition (client, 'topology', '# peers connected',0)) check.add (StatisticsCondition (client, 'fs', '# peers connected',0)) @@ -86,14 +86,14 @@ def check (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) check.add (StatisticsCondition (server, 'transport', '# peers connected',1)) check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (server, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (server, 'core', '# peers connected',1)) check.add (StatisticsCondition (server, 'topology', '# peers connected',1)) check.add (StatisticsCondition (server, 'fs', '# peers connected',1)) diff --git a/src/integration-tests/test_integration_clique.py.in b/src/integration-tests/test_integration_clique.py.in index 49a2c59..65c9341 100755 --- a/src/integration-tests/test_integration_clique.py.in +++ b/src/integration-tests/test_integration_clique.py.in @@ -42,7 +42,7 @@ from gnunet_testing import * testname = "test_integration_clique" verbose = True -check_timeout = 30 +check_timeout = 180 def cleanup (): @@ -73,7 +73,7 @@ def check_disconnect_client (): check.add (StatisticsCondition (client2, 'transport', '# peers connected',0)) check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',0)) - check.add (StatisticsCondition (client2, 'core', '# entries in session map',0)) + check.add (StatisticsCondition (client2, 'core', '# peers connected',0)) check.add (StatisticsCondition (client2, 'topology', '# peers connected',0)) check.add (StatisticsCondition (client2, 'fs', '# peers connected',0)) @@ -96,13 +96,13 @@ def check_disconnect_server (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) check.add (StatisticsCondition (client2, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client2, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client2, 'core', '# peers connected',1)) check.add (StatisticsCondition (client2, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client2, 'fs', '# peers connected',1)) @@ -123,19 +123,19 @@ def check_connect (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',2)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',2)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',2)) + check.add (StatisticsCondition (client, 'core', '# peers connected',2)) check.add (StatisticsCondition (client, 'topology', '# peers connected',2)) check.add (StatisticsCondition (client, 'fs', '# peers connected',2)) check.add (StatisticsCondition (client2, 'transport', '# peers connected',2)) check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',2)) - check.add (StatisticsCondition (client2, 'core', '# entries in session map',2)) + check.add (StatisticsCondition (client2, 'core', '# peers connected',2)) check.add (StatisticsCondition (client2, 'topology', '# peers connected',2)) check.add (StatisticsCondition (client2, 'fs', '# peers connected',2)) check.add (StatisticsCondition (server, 'transport', '# peers connected',2)) check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',2)) - check.add (StatisticsCondition (server, 'core', '# entries in session map',2)) + check.add (StatisticsCondition (server, 'core', '# peers connected',2)) check.add (StatisticsCondition (server, 'topology', '# peers connected',2)) check.add (StatisticsCondition (server, 'fs', '# peers connected',2)) diff --git a/src/integration-tests/test_integration_clique_nat.py.in b/src/integration-tests/test_integration_clique_nat.py.in index e8f7719..59d1179 100755 --- a/src/integration-tests/test_integration_clique_nat.py.in +++ b/src/integration-tests/test_integration_clique_nat.py.in @@ -42,7 +42,7 @@ from gnunet_testing import * #definitions testname = "test_integration_clique_nat" verbose = True -check_timeout = 30 +check_timeout = 180 def cleanup (): @@ -73,7 +73,7 @@ def check_disconnect_client (): check.add (StatisticsCondition (client2, 'transport', '# peers connected',0)) check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',0)) - check.add (StatisticsCondition (client2, 'core', '# entries in session map',0)) + check.add (StatisticsCondition (client2, 'core', '# peers connected',0)) check.add (StatisticsCondition (client2, 'topology', '# peers connected',0)) check.add (StatisticsCondition (client2, 'fs', '# peers connected',0)) @@ -96,13 +96,13 @@ def check_disconnect_server (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) check.add (StatisticsCondition (client2, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client2, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client2, 'core', '# peers connected',1)) check.add (StatisticsCondition (client2, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client2, 'fs', '# peers connected',1)) @@ -123,19 +123,19 @@ def check_connect (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',2)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',2)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',2)) + check.add (StatisticsCondition (client, 'core', '# peers connected',2)) check.add (StatisticsCondition (client, 'topology', '# peers connected',2)) check.add (StatisticsCondition (client, 'fs', '# peers connected',2)) check.add (StatisticsCondition (client2, 'transport', '# peers connected',2)) check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',2)) - check.add (StatisticsCondition (client2, 'core', '# entries in session map',2)) + check.add (StatisticsCondition (client2, 'core', '# peers connected',2)) check.add (StatisticsCondition (client2, 'topology', '# peers connected',2)) check.add (StatisticsCondition (client2, 'fs', '# peers connected',2)) check.add (StatisticsCondition (server, 'transport', '# peers connected',2)) check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',2)) - check.add (StatisticsCondition (server, 'core', '# entries in session map',2)) + check.add (StatisticsCondition (server, 'core', '# peers connected',2)) check.add (StatisticsCondition (server, 'topology', '# peers connected',2)) check.add (StatisticsCondition (server, 'fs', '# peers connected',2)) diff --git a/src/integration-tests/test_integration_connect_on_restart.py.in b/src/integration-tests/test_integration_connect_on_restart.py.in new file mode 100755 index 0000000..f77fd1c --- /dev/null +++ b/src/integration-tests/test_integration_connect_on_restart.py.in @@ -0,0 +1,180 @@ +#!@PYTHON@ +# This file is part of GNUnet. +# (C) 2010 Christian Grothoff (and other contributing authors) +# +# GNUnet is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2, or (at your +# option) any later version. +# +# GNUnet is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNUnet; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# +# +# This test starts 3 peers and expects bootstrap and a connected clique +# After a successful clique it shuts down all peers and starts the non-bootstrap +# peers, expecting them to reconnect +# +# Conditions for successful exit: +# Both peers have 1 connected peer in transport, core, topology, fs + +import sys +import os +import subprocess +import re +import shutil +import time +import pexpect +from gnunet_testing import Peer +from gnunet_testing import Test +from gnunet_testing import Check +from gnunet_testing import Condition +from gnunet_testing import * + + +#definitions + +testname = "test_integration_clique" +verbose = True +check_timeout = 180 + + +def cleanup (): + if os.name == "nt": + shutil.rmtree (os.path.join (os.getenv ("TEMP"), "c_bootstrap_server"), True) + shutil.rmtree (os.path.join (os.getenv ("TEMP"), "c_no_nat_client"), True) + shutil.rmtree (os.path.join (os.getenv ("TEMP"), "c_no_nat_client_2"), True) + else: + shutil.rmtree ("/tmp/c_bootstrap_server/", True) + shutil.rmtree ("/tmp/c_no_nat_client/", True) + shutil.rmtree ("/tmp/c_no_nat_client_2/", True) + + +def success_cont (check): + global success + success = True; + check.evaluate(True) + +def fail_cont (check): + global success + success = False; + check.evaluate(False) + + +def success_connect_cont (check): + check.evaluate(True) + print "Connected clique, shutdown" + server.stop () + client.stop () + client2.stop () + time.sleep (3) + client.start () + client2.start () + + check = Check (test) + check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) + check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) + check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) + check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) + + check.add (StatisticsCondition (client2, 'transport', '# peers connected',1)) + check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',1)) + check.add (StatisticsCondition (client2, 'core', '# peers connected',1)) + check.add (StatisticsCondition (client2, 'topology', '# peers connected',1)) + check.add (StatisticsCondition (client2, 'fs', '# peers connected',1)) + + check.run_blocking (check_timeout, success_cont, fail_cont) + + +def fail_connect_cont (check): + global success + print "Failed to connect clique, shutdown" + success = False; + check.evaluate(False) + + +def check_connect (): + check = Check (test) + check.add (StatisticsCondition (client, 'transport', '# peers connected',2)) + check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',2)) + check.add (StatisticsCondition (client, 'core', '# peers connected',2)) + check.add (StatisticsCondition (client, 'topology', '# peers connected',2)) + check.add (StatisticsCondition (client, 'fs', '# peers connected',2)) + + check.add (StatisticsCondition (client2, 'transport', '# peers connected',2)) + check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',2)) + check.add (StatisticsCondition (client2, 'core', '# peers connected',2)) + check.add (StatisticsCondition (client2, 'topology', '# peers connected',2)) + check.add (StatisticsCondition (client2, 'fs', '# peers connected',2)) + + check.add (StatisticsCondition (server, 'transport', '# peers connected',2)) + check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',2)) + check.add (StatisticsCondition (server, 'core', '# peers connected',2)) + check.add (StatisticsCondition (server, 'topology', '# peers connected',2)) + check.add (StatisticsCondition (server, 'fs', '# peers connected',2)) + + check.run_blocking (check_timeout, success_connect_cont, fail_connect_cont) + +# +# Test execution +# +def run (): + global success + global test + global server + global client + global client2 + + success = False + + test = Test ('test_integration_disconnect', verbose) + + server = Peer(test, './confs/c_bootstrap_server.conf'); + server.start(); + + client = Peer(test, './confs/c_no_nat_client.conf'); + client.start(); + + client2 = Peer(test, './confs/c_no_nat_client_2.conf'); + client2.start(); + + if ((client.started == True) and (client2.started == True) and (server.started == True)): + test.p ('Peers started, running check') + check_connect () + + server.stop () + client.stop () + client2.stop () + + cleanup () + + if (success == False): + print ('Test failed') + return False + else: + return True + + +try: + run () +except (KeyboardInterrupt, SystemExit): + print 'Test interrupted' + server.stop () + client.stop () + client2.stop () + cleanup () +if (success == False): + sys.exit(1) +else: + sys.exit(0) + + diff --git a/src/integration-tests/test_integration_connection_values_tcp.py.in b/src/integration-tests/test_integration_connection_values_tcp.py.in new file mode 100755 index 0000000..d8a92ba --- /dev/null +++ b/src/integration-tests/test_integration_connection_values_tcp.py.in @@ -0,0 +1,124 @@ +#!@PYTHON@ +# This file is part of GNUnet. +# (C) 2010 Christian Grothoff (and other contributing authors) +# +# GNUnet is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2, or (at your +# option) any later version. +# +# GNUnet is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNUnet; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# +# +# This test starts 3 peers and expects bootstrap and a connected clique +# +# Conditions for successful exit: +# Both peers have 1 connected peer in transport, core, topology, fs + +import sys +import os +import subprocess +import re +import shutil +import time +import pexpect +from gnunet_testing import Peer +from gnunet_testing import Test +from gnunet_testing import Check +from gnunet_testing import Condition +from gnunet_testing import * + + +#definitions + +testname = "test_integration_connection_value" +verbose = True +check_timeout = 180 + + +def cleanup (): + if os.name == "nt": + shutil.rmtree (os.path.join (os.getenv ("TEMP"), "c_normal_client"), True) + else: + shutil.rmtree ("/tmp/c_normal_client/", True) + + +def success_cont (check): + global success + success = True; + +def fail_cont (check): + global success + success= False; + check.evaluate(True) + + +def check_connect (): + check = Check (test) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'core', '# neighbour entries allocated')) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'core', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'core', '# neighbour entries allocated', client, 'core', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'topology', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'topology', '# peers connected', client, 'core', '# peers connected')) + + while True: + check.reset() + res = check.run_once (None, None) + print "Values are equal" + check.evaluate (False) +#if (False == res): +# break + time.sleep (5) + +# +# Test execution +# +def run (): + global success + global test + global client + + + success = False + + test = Test ('test_integration_connection_value', verbose) + + client = Peer(test, './confs/c_normal_client_tcp.conf'); + client.start(); + + if (client.started == True): + test.p ('Peers started, running check') + check_connect () + + client.stop () + + cleanup () + + if (success == False): + print ('Test failed') + return False + else: + return True + + +try: + run () +except (KeyboardInterrupt, SystemExit): + print 'Test interrupted' + client.stop () + cleanup () +if (success == False): + sys.exit(1) +else: + sys.exit(0) + + diff --git a/src/integration-tests/test_integration_connection_values_tcp_udp.py.in b/src/integration-tests/test_integration_connection_values_tcp_udp.py.in new file mode 100755 index 0000000..11b8266 --- /dev/null +++ b/src/integration-tests/test_integration_connection_values_tcp_udp.py.in @@ -0,0 +1,124 @@ +#!@PYTHON@ +# This file is part of GNUnet. +# (C) 2010 Christian Grothoff (and other contributing authors) +# +# GNUnet is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2, or (at your +# option) any later version. +# +# GNUnet is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNUnet; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# +# +# This test starts 3 peers and expects bootstrap and a connected clique +# +# Conditions for successful exit: +# Both peers have 1 connected peer in transport, core, topology, fs + +import sys +import os +import subprocess +import re +import shutil +import time +import pexpect +from gnunet_testing import Peer +from gnunet_testing import Test +from gnunet_testing import Check +from gnunet_testing import Condition +from gnunet_testing import * + + +#definitions + +testname = "test_integration_connection_value" +verbose = True +check_timeout = 180 + + +def cleanup (): + if os.name == "nt": + shutil.rmtree (os.path.join (os.getenv ("TEMP"), "c_normal_client"), True) + else: + shutil.rmtree ("/tmp/c_normal_client/", True) + + +def success_cont (check): + global success + success = True; + +def fail_cont (check): + global success + success= False; + check.evaluate(True) + + +def check_connect (): + check = Check (test) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'core', '# neighbour entries allocated')) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'core', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'core', '# neighbour entries allocated', client, 'core', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'topology', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'topology', '# peers connected', client, 'core', '# peers connected')) + + while True: + check.reset() + res = check.run_once (None, None) + print "Values are equal" + check.evaluate (False) +#if (False == res): +# break + time.sleep (5) + +# +# Test execution +# +def run (): + global success + global test + global client + + + success = False + + test = Test ('test_integration_connection_value', verbose) + + client = Peer(test, './confs/c_normal_client_tcp_udp.conf'); + client.start(); + + if (client.started == True): + test.p ('Peers started, running check') + check_connect () + + client.stop () + + cleanup () + + if (success == False): + print ('Test failed') + return False + else: + return True + + +try: + run () +except (KeyboardInterrupt, SystemExit): + print 'Test interrupted' + client.stop () + cleanup () +if (success == False): + sys.exit(1) +else: + sys.exit(0) + + diff --git a/src/integration-tests/test_integration_connection_values_tcp_udp_http.py.in b/src/integration-tests/test_integration_connection_values_tcp_udp_http.py.in new file mode 100755 index 0000000..69184a2 --- /dev/null +++ b/src/integration-tests/test_integration_connection_values_tcp_udp_http.py.in @@ -0,0 +1,124 @@ +#!@PYTHON@ +# This file is part of GNUnet. +# (C) 2010 Christian Grothoff (and other contributing authors) +# +# GNUnet is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2, or (at your +# option) any later version. +# +# GNUnet is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNUnet; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# +# +# This test starts 3 peers and expects bootstrap and a connected clique +# +# Conditions for successful exit: +# Both peers have 1 connected peer in transport, core, topology, fs + +import sys +import os +import subprocess +import re +import shutil +import time +import pexpect +from gnunet_testing import Peer +from gnunet_testing import Test +from gnunet_testing import Check +from gnunet_testing import Condition +from gnunet_testing import * + + +#definitions + +testname = "test_integration_connection_value" +verbose = True +check_timeout = 180 + + +def cleanup (): + if os.name == "nt": + shutil.rmtree (os.path.join (os.getenv ("TEMP"), "c_normal_client"), True) + else: + shutil.rmtree ("/tmp/c_normal_client/", True) + + +def success_cont (check): + global success + success = True; + +def fail_cont (check): + global success + success= False; + check.evaluate(True) + + +def check_connect (): + check = Check (test) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'core', '# neighbour entries allocated')) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'core', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'core', '# neighbour entries allocated', client, 'core', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'transport', '# peers connected', client, 'topology', '# peers connected')) + check.add (EqualStatisticsCondition (client, 'topology', '# peers connected', client, 'core', '# peers connected')) + + while True: + check.reset() + res = check.run_once (None, None) + print "Values are equal" + check.evaluate (False) +#if (False == res): +# break + time.sleep (5) + +# +# Test execution +# +def run (): + global success + global test + global client + + + success = False + + test = Test ('test_integration_connection_value', verbose) + + client = Peer(test, './confs/c_normal_client_tcp_udp_http.conf'); + client.start(); + + if (client.started == True): + test.p ('Peers started, running check') + check_connect () + + client.stop () + + cleanup () + + if (success == False): + print ('Test failed') + return False + else: + return True + + +try: + run () +except (KeyboardInterrupt, SystemExit): + print 'Test interrupted' + client.stop () + cleanup () +if (success == False): + sys.exit(1) +else: + sys.exit(0) + + diff --git a/src/integration-tests/test_integration_disconnect.py.in b/src/integration-tests/test_integration_disconnect.py.in index 5e137cf..6f84f37 100755 --- a/src/integration-tests/test_integration_disconnect.py.in +++ b/src/integration-tests/test_integration_disconnect.py.in @@ -44,7 +44,7 @@ from gnunet_testing import * testname = "test_integration_disconnect" verbose = True -check_timeout = 30 +check_timeout = 180 def cleanup (): @@ -73,7 +73,7 @@ def check_disconnect (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',0)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',0)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',0)) + check.add (StatisticsCondition (client, 'core', '# peers connected',0)) check.add (StatisticsCondition (client, 'topology', '# peers connected',0)) check.add (StatisticsCondition (client, 'fs', '# peers connected',0)) check.run_blocking (check_timeout, success_disconnect_cont, fail_disconnect_cont) @@ -93,13 +93,13 @@ def check_connect (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) check.add (StatisticsCondition (server, 'transport', '# peers connected',1)) check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (server, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (server, 'core', '# peers connected',1)) check.add (StatisticsCondition (server, 'topology', '# peers connected',1)) check.add (StatisticsCondition (server, 'fs', '# peers connected',1)) diff --git a/src/integration-tests/test_integration_restart.py.in b/src/integration-tests/test_integration_restart.py.in index e2a72e7..26917d0 100755 --- a/src/integration-tests/test_integration_restart.py.in +++ b/src/integration-tests/test_integration_restart.py.in @@ -45,7 +45,7 @@ from gnunet_testing import * testname = "test_integration_restart" verbose = False -check_timeout = 30 +check_timeout = 180 def cleanup (): @@ -85,13 +85,13 @@ def success_connect_cont (check): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) check.add (StatisticsCondition (server, 'transport', '# peers connected',1)) check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (server, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (server, 'core', '# peers connected',1)) check.add (StatisticsCondition (server, 'topology', '# peers connected',1)) check.add (StatisticsCondition (server, 'fs', '# peers connected',1)) @@ -108,13 +108,13 @@ def check_connect (): check = Check (test) check.add (StatisticsCondition (client, 'transport', '# peers connected',1)) check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (client, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (client, 'core', '# peers connected',1)) check.add (StatisticsCondition (client, 'topology', '# peers connected',1)) check.add (StatisticsCondition (client, 'fs', '# peers connected',1)) check.add (StatisticsCondition (server, 'transport', '# peers connected',1)) check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',1)) - check.add (StatisticsCondition (server, 'core', '# entries in session map',1)) + check.add (StatisticsCondition (server, 'core', '# peers connected',1)) check.add (StatisticsCondition (server, 'topology', '# peers connected',1)) check.add (StatisticsCondition (server, 'fs', '# peers connected',1)) diff --git a/src/lockmanager/Makefile.am b/src/lockmanager/Makefile.am new file mode 100644 index 0000000..0fbc20b --- /dev/null +++ b/src/lockmanager/Makefile.am @@ -0,0 +1,68 @@ +INCLUDES = -I$(top_srcdir)/src/include + +if MINGW + WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +endif + +if USE_COVERAGE + AM_CFLAGS = --coverage -O0 + XLIB = -lgcov +endif + +pkgcfgdir= $(pkgdatadir)/config.d/ + +pkgcfg_DATA = \ + lockmanager.conf + +bin_PROGRAMS = \ + gnunet-service-lockmanager + +lib_LTLIBRARIES = \ + libgnunetlockmanager.la + +gnunet_service_lockmanager_SOURCES = \ + gnunet-service-lockmanager.c \ + lockmanager.h +gnunet_service_lockmanager_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la +gnunet_service_lockmanager_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunetlockmanager_la_SOURCES = \ + lockmanager_api.c lockmanager.h +libgnunetlockmanager_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(XLIB) +libgnunetlockmanager_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) $(WINFLAGS) \ + -version-info 0:0:0 + +check_PROGRAMS = \ + test-lockmanager-api \ + test-lockmanager-api-lockrelease \ + test-lockmanager-api-servercrash + +EXTRA_DIST = \ + test_lockmanager_api.conf + +if ENABLE_TEST_RUN +TESTS = $(check_PROGRAMS) +endif + +test_lockmanager_api_SOURCES = \ + test_lockmanager_api.c +test_lockmanager_api_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la + +test_lockmanager_api_lockrelease_SOURCES = \ + test_lockmanager_api_lockrelease.c +test_lockmanager_api_lockrelease_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la + +test_lockmanager_api_servercrash_SOURCES = \ + test_lockmanager_api_servercrash.c +test_lockmanager_api_servercrash_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la \ No newline at end of file diff --git a/src/lockmanager/Makefile.in b/src/lockmanager/Makefile.in new file mode 100644 index 0000000..6a90407 --- /dev/null +++ b/src/lockmanager/Makefile.in @@ -0,0 +1,933 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = gnunet-service-lockmanager$(EXEEXT) +check_PROGRAMS = test-lockmanager-api$(EXEEXT) \ + test-lockmanager-api-lockrelease$(EXEEXT) \ + test-lockmanager-api-servercrash$(EXEEXT) +subdir = src/lockmanager +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/lockmanager.conf.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ + $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ + $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/gnunet_config.h +CONFIG_CLEAN_FILES = lockmanager.conf +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(pkgcfgdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libgnunetlockmanager_la_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(am__DEPENDENCIES_1) +am_libgnunetlockmanager_la_OBJECTS = lockmanager_api.lo +libgnunetlockmanager_la_OBJECTS = \ + $(am_libgnunetlockmanager_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libgnunetlockmanager_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libgnunetlockmanager_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +PROGRAMS = $(bin_PROGRAMS) +am_gnunet_service_lockmanager_OBJECTS = \ + gnunet-service-lockmanager.$(OBJEXT) +gnunet_service_lockmanager_OBJECTS = \ + $(am_gnunet_service_lockmanager_OBJECTS) +am_test_lockmanager_api_OBJECTS = test_lockmanager_api.$(OBJEXT) +test_lockmanager_api_OBJECTS = $(am_test_lockmanager_api_OBJECTS) +test_lockmanager_api_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la +am_test_lockmanager_api_lockrelease_OBJECTS = \ + test_lockmanager_api_lockrelease.$(OBJEXT) +test_lockmanager_api_lockrelease_OBJECTS = \ + $(am_test_lockmanager_api_lockrelease_OBJECTS) +test_lockmanager_api_lockrelease_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la +am_test_lockmanager_api_servercrash_OBJECTS = \ + test_lockmanager_api_servercrash.$(OBJEXT) +test_lockmanager_api_servercrash_OBJECTS = \ + $(am_test_lockmanager_api_servercrash_OBJECTS) +test_lockmanager_api_servercrash_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libgnunetlockmanager_la_SOURCES) \ + $(gnunet_service_lockmanager_SOURCES) \ + $(test_lockmanager_api_SOURCES) \ + $(test_lockmanager_api_lockrelease_SOURCES) \ + $(test_lockmanager_api_servercrash_SOURCES) +DIST_SOURCES = $(libgnunetlockmanager_la_SOURCES) \ + $(gnunet_service_lockmanager_SOURCES) \ + $(test_lockmanager_api_SOURCES) \ + $(test_lockmanager_api_lockrelease_SOURCES) \ + $(test_lockmanager_api_servercrash_SOURCES) +DATA = $(pkgcfg_DATA) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_INTERFACE = @DEFAULT_INTERFACE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLDIR = @DLLDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXT_LIBS = @EXT_LIBS@ +EXT_LIB_PATH = @EXT_LIB_PATH@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ +GN_DAEMON_CONFIG_DIR = @GN_DAEMON_CONFIG_DIR@ +GN_DAEMON_HOME_DIR = @GN_DAEMON_HOME_DIR@ +GN_INTLINCL = @GN_INTLINCL@ +GN_LIBINTL = @GN_LIBINTL@ +GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ +GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ +GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GREP = @GREP@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBPREFIX = @LIBPREFIX@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNISTRING = @LIBUNISTRING@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ +POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CPPFLAGS = @SQLITE_CPPFLAGS@ +SQLITE_LDFLAGS = @SQLITE_LDFLAGS@ +STRIP = @STRIP@ +SUDO_BINARY = @SUDO_BINARY@ +UNIXONLY = @UNIXONLY@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_OBJC = @ac_ct_OBJC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_target = @build_target@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/src/include +@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0 +@USE_COVERAGE_TRUE@XLIB = -lgcov +pkgcfgdir = $(pkgdatadir)/config.d/ +pkgcfg_DATA = \ + lockmanager.conf + +lib_LTLIBRARIES = \ + libgnunetlockmanager.la + +gnunet_service_lockmanager_SOURCES = \ + gnunet-service-lockmanager.c \ + lockmanager.h + +gnunet_service_lockmanager_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + +gnunet_service_lockmanager_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunetlockmanager_la_SOURCES = \ + lockmanager_api.c lockmanager.h + +libgnunetlockmanager_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(XLIB) + +libgnunetlockmanager_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) $(WINFLAGS) \ + -version-info 0:0:0 + +EXTRA_DIST = \ + test_lockmanager_api.conf + +@ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) +test_lockmanager_api_SOURCES = \ + test_lockmanager_api.c + +test_lockmanager_api_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la + +test_lockmanager_api_lockrelease_SOURCES = \ + test_lockmanager_api_lockrelease.c + +test_lockmanager_api_lockrelease_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la + +test_lockmanager_api_servercrash_SOURCES = \ + test_lockmanager_api_servercrash.c + +test_lockmanager_api_servercrash_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetlockmanager.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lockmanager/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/lockmanager/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +lockmanager.conf: $(top_builddir)/config.status $(srcdir)/lockmanager.conf.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgnunetlockmanager.la: $(libgnunetlockmanager_la_OBJECTS) $(libgnunetlockmanager_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunetlockmanager_la_LINK) -rpath $(libdir) $(libgnunetlockmanager_la_OBJECTS) $(libgnunetlockmanager_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +gnunet-service-lockmanager$(EXEEXT): $(gnunet_service_lockmanager_OBJECTS) $(gnunet_service_lockmanager_DEPENDENCIES) + @rm -f gnunet-service-lockmanager$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_service_lockmanager_OBJECTS) $(gnunet_service_lockmanager_LDADD) $(LIBS) +test-lockmanager-api$(EXEEXT): $(test_lockmanager_api_OBJECTS) $(test_lockmanager_api_DEPENDENCIES) + @rm -f test-lockmanager-api$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_lockmanager_api_OBJECTS) $(test_lockmanager_api_LDADD) $(LIBS) +test-lockmanager-api-lockrelease$(EXEEXT): $(test_lockmanager_api_lockrelease_OBJECTS) $(test_lockmanager_api_lockrelease_DEPENDENCIES) + @rm -f test-lockmanager-api-lockrelease$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_lockmanager_api_lockrelease_OBJECTS) $(test_lockmanager_api_lockrelease_LDADD) $(LIBS) +test-lockmanager-api-servercrash$(EXEEXT): $(test_lockmanager_api_servercrash_OBJECTS) $(test_lockmanager_api_servercrash_DEPENDENCIES) + @rm -f test-lockmanager-api-servercrash$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_lockmanager_api_servercrash_OBJECTS) $(test_lockmanager_api_servercrash_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-lockmanager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockmanager_api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lockmanager_api.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lockmanager_api_lockrelease.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lockmanager_api_servercrash.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-pkgcfgDATA: $(pkgcfg_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" + @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcfgdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcfgdir)" || exit $$?; \ + done + +uninstall-pkgcfgDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pkgcfgDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ + uninstall-pkgcfgDATA + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-pkgcfgDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ + uninstall-pkgcfgDATA + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/lockmanager/gnunet-service-lockmanager.c b/src/lockmanager/gnunet-service-lockmanager.c new file mode 100644 index 0000000..8ec9889 --- /dev/null +++ b/src/lockmanager/gnunet-service-lockmanager.c @@ -0,0 +1,899 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file lockmanager/gnunet-service-lockmanager.c + * @brief implementation of the LOCKMANAGER service + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_container_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_service_lib.h" +#include "gnunet_server_lib.h" + +#include "lockmanager.h" + + +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +#define TIME_REL_MINS(min) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, min) + +#define TIMEOUT TIME_REL_MINS(3) + + +/** + * Doubly linked list of clients having connections to us + */ +struct ClientList; + + +/** + * Doubly linked list of clients waiting for a lock + */ +struct WaitList +{ + /** + * The next client structure + */ + struct WaitList *next; + + /** + * The prev client structure + */ + struct WaitList *prev; + + /** + * Pointer to the client + */ + struct ClientList *cl_entry; +}; + + +/** + * Structure representing a Lock + */ +struct Lock +{ + /** + * List head of clients waiting for this lock + */ + struct WaitList *wl_head; + + /** + * List tail of clients waiting for this lock + */ + struct WaitList *wl_tail; + + /** + * The client which is currently holding this lock + */ + struct ClientList *cl_entry; + + /** + * The name of the locking domain this lock belongs to + */ + char *domain_name; + + /** + * The number of this lock + */ + uint32_t lock_num; +}; + + +/** + * A Lock element for a doubly linked list + */ +struct LockList +{ + /** + * The next element pointer + */ + struct LockList *next; + + /** + * Pointer to the previous element + */ + struct LockList *prev; + + /** + * Pointer to the Lock + */ + struct Lock *lock; +}; + + +/** + * Doubly linked list of clients having connections to us + */ +struct ClientList +{ + + /** + * The next client structure + */ + struct ClientList *next; + + /** + * The previous client structure + */ + struct ClientList *prev; + + /** + * Head of the doubly linked list of the currently held locks by this client + */ + struct LockList *ll_head; + + /** + * Tail of the doubly linked list of the currently held locks by this client + */ + struct LockList *ll_tail; + + /** + * Pointer to the client + */ + struct GNUNET_SERVER_Client *client; +}; + + +/** + * Structure for matching a lock + */ +struct LockMatch +{ + /** + * The matched LockingRequest entry; Should be NULL if no entry is found + */ + struct Lock *matched_entry; + + /** + * The locking domain name of the lock + */ + const char *domain_name; + + /** + * The lock number + */ + uint32_t lock_num; +}; + + +/** + * Map of lock-keys to the 'struct LockList' entry for the key. + */ +static struct GNUNET_CONTAINER_MultiHashMap *lock_map; + +/** + * Head of the doubly linked list of clients currently connected + */ +static struct ClientList *cl_head; + +/** + * Tail of the doubly linked list of clients currently connected + */ +static struct ClientList *cl_tail; + + +/** + * Get the key for the given lock in the 'lock_map'. + * + * @param domain_name + * @param lock_number + * @param key set to the key + */ +static void +get_key (const char *domain_name, + uint32_t lock_number, + struct GNUNET_HashCode *key) +{ + uint32_t *last_32; + + GNUNET_CRYPTO_hash (domain_name, + strlen (domain_name), + key); + last_32 = (uint32_t *) key; + *last_32 ^= lock_number; +} + + +/** + * Hashmap iterator for matching a lock + * + * @param cls the LockMatch structure + * @param key current key code + * @param value value in the hash map (struct Lock) + * @return GNUNET_YES if we should continue to + * iterate, + * GNUNET_NO if not. + */ +static int +match_iterator (void *cls, const GNUNET_HashCode *key, void *value) +{ + struct LockMatch *match = cls; + struct Lock *lock = value; + + if ( (match->lock_num == lock->lock_num) + && (0 == strcmp (match->domain_name, lock->domain_name)) ) + { + match->matched_entry = lock; + return GNUNET_NO; + } + return GNUNET_YES; +} + + +/** + * Function to search for a lock in the global lock hashmap + * + * @param domain_name the name of the locking domain + * @param lock_num the number of the lock + * @return the lock if found; NULL if not + */ +static struct Lock * +find_lock (const char *domain_name, + const uint32_t lock_num) + +{ + struct LockMatch match; + struct GNUNET_HashCode key; + + match.lock_num = lock_num; + match.domain_name = domain_name; + match.matched_entry = NULL; + get_key (domain_name, lock_num, &key); + GNUNET_CONTAINER_multihashmap_get_multiple (lock_map, + &key, + &match_iterator, + &match); + return match.matched_entry; +} + + +/** + * Adds a lock to the global lock hashmap + * + * @param domain_name the name of the lock's locking domain + * @param lock_num the lock number + * @return pointer to the lock structure which is added to lock map + */ +static struct Lock * +add_lock (const char *domain_name, + uint32_t lock_num) +{ + struct Lock *lock; + struct GNUNET_HashCode key; + size_t domain_name_len; + + lock = GNUNET_malloc (sizeof (struct Lock)); + domain_name_len = strlen (domain_name) + 1; + lock->domain_name = GNUNET_malloc (domain_name_len); + strncpy (lock->domain_name, domain_name, domain_name_len); + lock->lock_num = lock_num; + get_key (domain_name, lock_num, &key); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Adding a lock with num: %d and domain: %s to the lock map\n", + lock->lock_num, lock->domain_name); + GNUNET_CONTAINER_multihashmap_put (lock_map, + &key, + lock, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + return lock; +} + + +/** + * Removes a lock from the lock map. The WaitList of the lock should be empty + * + * @param lock the lock to remove + */ +static void +remove_lock (struct Lock *lock) +{ + struct GNUNET_HashCode key; + + GNUNET_assert (NULL == lock->wl_head); + get_key (lock->domain_name, + lock->lock_num, + &key); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Removing lock with num: %u, domain: %s from lock map\n", + lock->lock_num, lock->domain_name); + GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove + (lock_map, &key, lock)); + GNUNET_free (lock->domain_name); + GNUNET_free (lock); +} + + +/** + * Find the LockList entry corresponding to the given Lock in a ClientList + * entry + * + * @param cl_entry the ClientList entry whose lock list has to be searched + * @param lock the lock which has to be matched + * @return the matching LockList entry; NULL if no match is found + */ +static struct LockList * +cl_ll_find_lock (struct ClientList *cl_entry, + const struct Lock *lock) +{ + struct LockList *ll_entry; + + for (ll_entry = cl_entry->ll_head; + NULL != ll_entry; ll_entry = ll_entry->next) + { + if (lock == ll_entry->lock) + return ll_entry; + } + return NULL; +} + + +/** + * Function to append a lock to the lock list of a ClientList entry + * + * @param cl_entry the client which currently owns this lock + * @param lock the lock to be added to the cl_entry's lock list + */ +static void +cl_ll_add_lock (struct ClientList *cl_entry, + struct Lock *lock) +{ + struct LockList *ll_entry; + + ll_entry = GNUNET_malloc (sizeof (struct LockList)); + ll_entry->lock = lock; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Adding a lock with num: %u and domain: %s to lock list\n", + lock->lock_num, lock->domain_name); + GNUNET_CONTAINER_DLL_insert_tail (cl_entry->ll_head, + cl_entry->ll_tail, + ll_entry); +} + + +/** + * Function to delete a lock from the lock list of the given ClientList entry + * + * @param cl_entry the ClientList entry + * @param ll_entry the LockList entry to be deleted + */ +static void +cl_ll_remove_lock (struct ClientList *cl_entry, + struct LockList *ll_entry) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Removing lock with num: %u, domain: %s from lock list of a client\n", + ll_entry->lock->lock_num, + ll_entry->lock->domain_name); + GNUNET_assert (NULL != cl_entry->ll_head); + GNUNET_CONTAINER_DLL_remove (cl_entry->ll_head, + cl_entry->ll_tail, + ll_entry); + GNUNET_free (ll_entry); +} + + +/** + * Find a WaitList entry in the waiting list of a lock + * + * @param lock the lock whose wait list has to be searched + * @param cl_entry the ClientList entry to be searched + * @return the WaitList entry matching the given cl_entry; NULL if not match + * was found + */ +static struct WaitList * +lock_wl_find (const struct Lock *lock, + const struct ClientList *cl_entry) +{ + struct WaitList *wl_entry; + + for (wl_entry = lock->wl_head; + NULL != wl_entry; + wl_entry = wl_entry->next) + { + if (cl_entry == wl_entry->cl_entry) + return wl_entry; + } + return NULL; +} + + +/** + * Add a client to the wait list of given lock + * + * @param lock the lock list entry of a lock + * @param cl_entry the client to queue for the lock's wait list + */ +static void +lock_wl_add_client (struct Lock *lock, + struct ClientList *cl_entry) +{ + struct WaitList *wl_entry; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Adding a client to lock's wait list (lock num: %u, domain: %s)\n", + lock->lock_num, + lock->domain_name); + wl_entry = GNUNET_malloc (sizeof (struct WaitList)); + wl_entry->cl_entry = cl_entry; + GNUNET_CONTAINER_DLL_insert_tail (lock->wl_head, + lock->wl_tail, + wl_entry); +} + + +/** + * Remove an entry from the wait list of the given lock + * + * @param lock the lock + * @param wl_entry the wait list entry to be removed + */ +static void +lock_wl_remove (struct Lock *lock, + struct WaitList *wl_entry) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Removing client from wait list of lock with num: %u, domain: %s\n", + lock->lock_num, lock->domain_name); + GNUNET_CONTAINER_DLL_remove (lock->wl_head, + lock->wl_tail, + wl_entry); + GNUNET_free (wl_entry); +} + + +/** + * Search for a client in the client list + * + * @param client the client to be searched for + * @return the ClientList entry; NULL if the client is not found + */ +static struct ClientList * +cl_find_client (const struct GNUNET_SERVER_Client *client) +{ + struct ClientList *current; + + for (current = cl_head; NULL != current; current = current->next) + if (client == current->client) + return current; + return NULL; +} + + +/** + * Append a client to the client list + * + * @param client the client to be appended to the list + * @return the client list entry which is added to the client list + */ +static struct ClientList * +cl_add_client (struct GNUNET_SERVER_Client *client) +{ + struct ClientList *new_client; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Adding a client to the client list\n"); + new_client = GNUNET_malloc (sizeof (struct ClientList)); + GNUNET_SERVER_client_keep (client); + new_client->client = client; + GNUNET_CONTAINER_DLL_insert_tail (cl_head, + cl_tail, + new_client); + return new_client; +} + + +/** + * Delete the given client from the client list. The LockList should be empty + * + * @param cl_entry the client list entry to delete + */ +static void +cl_remove_client (struct ClientList *cl_entry) +{ + GNUNET_assert (NULL == cl_entry->ll_head); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Removing a client from the client list\n"); + GNUNET_SERVER_client_drop (cl_entry->client); + GNUNET_CONTAINER_DLL_remove (cl_head, + cl_tail, + cl_entry); + GNUNET_free (cl_entry); +} + + +/** + * Transmit notify for sending message to client + * + * @param cls the message to send + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_notify (void *cls, size_t size, void *buf) +{ + struct GNUNET_LOCKMANAGER_Message *msg = cls; + uint16_t msg_size; + + if ((0 == size) || (NULL == buf)) + { + /* FIXME: Timed out -- requeue? */ + return 0; + } + msg_size = ntohs (msg->header.size); + GNUNET_assert (size >= msg_size); + memcpy (buf, msg, msg_size); + GNUNET_free (msg); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Message of size %u sent\n", msg_size); + return msg_size; +} + + +/** + * Send SUCCESS message to the client + * + * @param client the client to which the message has to be sent + * @param domain_name the locking domain of the successfully acquried lock + * @param lock_num the number of the successfully acquired lock + */ +static void +send_success_msg (struct GNUNET_SERVER_Client *client, + const char *domain_name, + int lock_num) +{ + struct GNUNET_LOCKMANAGER_Message *reply; + size_t domain_name_len; + uint16_t reply_size; + + domain_name_len = strlen (domain_name) + 1; + reply_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_len; + reply = GNUNET_malloc (reply_size); + reply->header.size = htons (reply_size); + reply->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS); + reply->lock = htonl (lock_num); + strncpy ((char *) &reply[1], domain_name, domain_name_len); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Sending SUCCESS message for lock with num: %u, domain: %s\n", + lock_num, domain_name); + GNUNET_SERVER_notify_transmit_ready (client, + reply_size, + TIMEOUT, + &transmit_notify, + reply); +} + + +/** + * Handler for GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE + * + * @param cls NULL + * @param client the client sending this message + * @param message GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE message + */ +static void +handle_acquire (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct GNUNET_LOCKMANAGER_Message *request; + const char *domain_name; + struct Lock *lock; + struct ClientList *cl_entry; + uint32_t lock_num; + uint16_t msize; + + msize = htons (message->size); + if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + request = (struct GNUNET_LOCKMANAGER_Message *) message; + domain_name = (const char *) &request[1]; + msize -= sizeof (struct GNUNET_LOCKMANAGER_Message); + if ('\0' != domain_name[msize]) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + lock_num = ntohl (request->lock); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received an ACQUIRE message for lock num: %u domain: %s\n", + lock_num, domain_name); + if (NULL == (cl_entry = cl_find_client (client))) + cl_entry = cl_add_client (client); /* Add client if not in client list */ + if (NULL != (lock = find_lock (domain_name,lock_num))) + { + if (lock->cl_entry == cl_entry) + { /* Client is requesting a lock it already owns */ + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + lock_wl_add_client (lock, cl_entry); + cl_ll_add_lock (cl_entry, lock); + } + else /* Lock not present */ + { + lock = add_lock (domain_name, lock_num); + lock->cl_entry = cl_entry; + cl_ll_add_lock (cl_entry, lock); + send_success_msg (cl_entry->client, domain_name, lock_num); + } + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + +/** + * This function gives the lock to the first client in the wait list of the + * lock. If no clients are currently waiting for this lock, the lock is then + * destroyed. + * + * @param lock the lock which has to be processed for release + */ +static void +process_lock_release (struct Lock *lock) +{ + struct WaitList *wl_entry; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Processing lock release for lock with num: %u, domain: %s\n", + lock->lock_num, lock->domain_name); + wl_entry = lock->wl_head; + if (NULL == wl_entry) + { + remove_lock (lock); /* No clients waiting for this lock - delete */ + return; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Giving lock to a client from wait list\n"); + lock->cl_entry = wl_entry->cl_entry; + lock_wl_remove(lock, wl_entry); + send_success_msg (lock->cl_entry->client, + lock->domain_name, + lock->lock_num); + return; +} + + +/** + * Handle for GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE + * + * @param cls NULL + * @param client the client sending this message + * @param message the LOCKMANAGER_RELEASE message + */ +static void +handle_release (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct GNUNET_LOCKMANAGER_Message *request; + struct ClientList *cl_entry; + struct WaitList *wl_entry; + struct LockList *ll_entry; + const char *domain_name; + struct Lock *lock; + uint32_t lock_num; + uint16_t msize; + + msize = ntohs (message->size); + if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + request = (const struct GNUNET_LOCKMANAGER_Message *) message; + domain_name = (const char *) &request[1]; + msize -= sizeof (struct GNUNET_LOCKMANAGER_Message); + if ('\0' != domain_name[msize-1]) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + + + } + lock_num = ntohl (request->lock); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received RELEASE message for lock with num: %d, domain: %s\n", + lock_num, domain_name); + if (NULL == (cl_entry = cl_find_client (client))) + { + GNUNET_break(0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + lock = find_lock (domain_name, lock_num); + if(NULL == lock) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + if (NULL == (ll_entry = cl_ll_find_lock (cl_entry, lock))) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + cl_ll_remove_lock (cl_entry, ll_entry); + if (cl_entry == lock->cl_entry) + { + process_lock_release (lock); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + /* remove 'client' from wait list (check that it is not there...) */ + if (NULL != (wl_entry = lock_wl_find (lock, cl_entry))) + { + lock_wl_remove (lock, wl_entry); + } + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + +/** + * Callback for client disconnect + * + * @param cls NULL + * @param client the client which has disconnected + */ +static void +client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) +{ + struct ClientList *cl_entry; + struct LockList *ll_entry; + struct Lock *lock; + + if (NULL == client) + return; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "A client has been disconnected -- freeing its locks and resources\n"); + cl_entry = cl_find_client (client); + if (NULL == cl_entry) + return; + while (NULL != (ll_entry = cl_entry->ll_head)) + { + lock = ll_entry->lock; + cl_ll_remove_lock (cl_entry, ll_entry); + process_lock_release (lock); + } + cl_remove_client (cl_entry); +} + + +/** + * Hashmap Iterator to delete lock entries in hash map + * + * @param cls NULL + * @param key current key code + * @param value value in the hash map + * @return GNUNET_YES if we should continue to + * iterate, + * GNUNET_NO if not. + */ +static int +lock_delete_iterator (void *cls, + const GNUNET_HashCode * key, + void *value) +{ + struct Lock *lock = value; + + GNUNET_assert (NULL != lock); + while (NULL != lock->wl_head) + { + lock_wl_remove (lock, lock->wl_head); + } + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove(lock_map, + key, + lock)); + GNUNET_free (lock->domain_name); + GNUNET_free (lock); + return GNUNET_YES; +} + + +/** + * Task to clean up and shutdown nicely + * + * @param cls NULL + * @param tc the TaskContext from scheduler + */ +static void +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Shutting down lock manager\n"); + /* Clean the global ClientList */ + while (NULL != cl_head) + { + while (NULL != cl_head->ll_head) /* Clear the LockList */ + { + cl_ll_remove_lock (cl_head, cl_head->ll_head); + } + cl_remove_client (cl_head); + } + /* Clean the global hash table */ + GNUNET_CONTAINER_multihashmap_iterate (lock_map, + &lock_delete_iterator, + NULL); + GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (lock_map)); + GNUNET_CONTAINER_multihashmap_destroy (lock_map); +} + + +/** + * Lock manager setup + * + * @param cls closure + * @param server the initialized server + * @param cfg configuration to use + */ +static void +lockmanager_run (void *cls, + struct GNUNET_SERVER_Handle * server, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + static const struct GNUNET_SERVER_MessageHandler message_handlers[] = + { + {&handle_acquire, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE, 0}, + {&handle_release, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE, 0}, + {NULL} + }; + GNUNET_SERVER_add_handlers (server, + message_handlers); + GNUNET_SERVER_disconnect_notify (server, + &client_disconnect_cb, + NULL); + lock_map = GNUNET_CONTAINER_multihashmap_create (30); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &shutdown_task, + NULL); +} + + +/** + * The starting point of execution + */ +int main (int argc, char *const *argv) +{ + return + (GNUNET_OK == + GNUNET_SERVICE_run (argc, + argv, + "lockmanager", + GNUNET_SERVICE_OPTION_NONE, + &lockmanager_run, + NULL)) ? 0 : 1; +} diff --git a/src/lockmanager/lockmanager.conf.in b/src/lockmanager/lockmanager.conf.in new file mode 100644 index 0000000..75b9244 --- /dev/null +++ b/src/lockmanager/lockmanager.conf.in @@ -0,0 +1,13 @@ +[lockmanager] +AUTOSTART = YES +@UNIXONLY@ PORT = 2100 +HOSTNAME = localhost +HOME = $SERVICEHOME +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-service-lockmanager +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = /tmp/gnunet-service-lockmanager.sock +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + diff --git a/src/lockmanager/lockmanager.h b/src/lockmanager/lockmanager.h new file mode 100644 index 0000000..346c43e --- /dev/null +++ b/src/lockmanager/lockmanager.h @@ -0,0 +1,71 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file lockmanager/lockmanager.h + * @brief client-server protocol messages for LOCKMANAGER service + * @author Sree Harsha Totakura + */ + +#ifndef LOCKMANAGER_H +#define LOCKMANAGER_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +#include "gnunet_common.h" + +/** + * Structure of Lockmanager message + */ +struct GNUNET_LOCKMANAGER_Message +{ + /** + * The generic message header + */ + struct GNUNET_MessageHeader header; + + /** + * The lock + */ + uint32_t lock; + + /** + * The locking domain name(NULL terminated string of characters) should + * follow here. The size of the header should include the size of this string + * with its trailing NULL + */ +}; + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef LOCKMANAGER_H */ +#endif +/* end of lockmanager.h */ diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c new file mode 100644 index 0000000..99f5ab5 --- /dev/null +++ b/src/lockmanager/lockmanager_api.c @@ -0,0 +1,677 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file lockmanager/lockmanager_api.c + * @brief API implementation of gnunet_lockmanager_service.h + * @author Sree Harsha Totakura + */ + +/** + * To be fixed: + * Should the handle be freed when the connection to service is lost? + * Should cancel_request have a call back (else simultaneous calls break) + */ + +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_container_lib.h" +#include "gnunet_client_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_lockmanager_service.h" +#include "gnunet_protocols.h" + +#include "lockmanager.h" + +#define LOG(kind,...) \ + GNUNET_log_from (kind, "lockmanager-api",__VA_ARGS__) + +#define TIME_REL_MINS(min) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, min) + +#define TIMEOUT TIME_REL_MINS(3) + + +/** + * The message queue + */ +struct MessageQueue +{ + /** + * The next pointer for doubly linked list + */ + struct MessageQueue *next; + + /** + * The prev pointer for doubly linked list + */ + struct MessageQueue *prev; + + /** + * The LOCKMANAGER Message + */ + struct GNUNET_LOCKMANAGER_Message *msg; +}; + + +/** + * Handler for the lockmanager service + */ +struct GNUNET_LOCKMANAGER_Handle +{ + /** + * The client connection to the service + */ + struct GNUNET_CLIENT_Connection *conn; + + /** + * The transmit handle for transmissions using conn + */ + struct GNUNET_CLIENT_TransmitHandle *transmit_handle; + + /** + * Hashmap handle + */ + struct GNUNET_CONTAINER_MultiHashMap *hashmap; + + /** + * Double linked list head for message queue + */ + struct MessageQueue *mq_head; + + /** + * Double linked list tail for message queue + */ + struct MessageQueue *mq_tail; +}; + + +/** + * Structure for Locking Request + */ +struct GNUNET_LOCKMANAGER_LockingRequest +{ + /** + * The handle associated with this request + */ + struct GNUNET_LOCKMANAGER_Handle *handle; + + /** + * The status callback + */ + GNUNET_LOCKMANAGER_StatusCallback status_cb; + + /** + * Closure for the status callback + */ + void *status_cb_cls; + + /** + * The locking domain of this request + */ + char *domain; + + /** + * The lock + */ + uint32_t lock; + + /** + * The status of the lock + */ + enum GNUNET_LOCKMANAGER_Status status; +}; + + +/** + * Structure for matching a lock + */ +struct LockingRequestMatch +{ + /** + * The matched LockingRequest entry; Should be NULL if no entry is found + */ + struct GNUNET_LOCKMANAGER_LockingRequest *matched_entry; + + /** + * The locking domain name of the lock + */ + const char *domain; + + /** + * The lock number + */ + uint32_t lock; +}; + + +/** + * Transmit notify for sending message to server + * + * @param cls the lockmanager handle + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_notify (void *cls, size_t size, void *buf) +{ + struct GNUNET_LOCKMANAGER_Handle *handle = cls; + struct MessageQueue *queue_entity; + uint16_t msg_size; + + handle->transmit_handle = NULL; + if ((0 == size) || (NULL == buf)) + { + /* FIXME: Timed out -- requeue? */ + return 0; + } + queue_entity = handle->mq_head; + GNUNET_assert (NULL != queue_entity); + msg_size = ntohs (queue_entity->msg->header.size); + GNUNET_assert (size >= msg_size); + memcpy (buf, queue_entity->msg, msg_size); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Message of size %u sent\n", msg_size); + GNUNET_free (queue_entity->msg); + GNUNET_CONTAINER_DLL_remove (handle->mq_head, + handle->mq_tail, + queue_entity); + GNUNET_free (queue_entity); + queue_entity = handle->mq_head; + if (NULL != queue_entity) + { + handle->transmit_handle = + GNUNET_CLIENT_notify_transmit_ready (handle->conn, + ntohs + (queue_entity->msg->header.size), + TIMEOUT, + GNUNET_YES, + &transmit_notify, + handle); + } + return msg_size; +} + + +/** + * Queues a message into handle's send message queue + * + * @param handle the lockmanager handle whose queue will be used + * @param msg the message to be queued + */ +static void +queue_message (struct GNUNET_LOCKMANAGER_Handle *handle, + struct GNUNET_LOCKMANAGER_Message *msg) +{ + struct MessageQueue *queue_entity; + + GNUNET_assert (NULL != msg); + queue_entity = GNUNET_malloc (sizeof (struct MessageQueue)); + queue_entity->msg = msg; + GNUNET_CONTAINER_DLL_insert_tail (handle->mq_head, + handle->mq_tail, + queue_entity); + if (NULL == handle->transmit_handle) + { + handle->transmit_handle = + GNUNET_CLIENT_notify_transmit_ready (handle->conn, + ntohs (msg->header.size), + TIMEOUT, + GNUNET_YES, + &transmit_notify, + handle); + } +} + + +/** + * Get the key for the given lock in the 'lock_map'. + * + * @param domain_name + * @param lock_number + * @param key set to the key + */ +static void +get_key (const char *domain_name, + uint32_t lock_number, + struct GNUNET_HashCode *key) +{ + uint32_t *last_32; + + GNUNET_CRYPTO_hash (domain_name, + strlen (domain_name), + key); + last_32 = (uint32_t *) key; + *last_32 ^= lock_number; +} + + +/** + * Hashmap iterator for matching a LockingRequest + * + * @param cls the LockingRequestMatch structure + * @param key current key code + * @param value value in the hash map (struct GNUNET_LOCKMANAGER_LockingRequest) + * @return GNUNET_YES if we should continue to + * iterate, + * GNUNET_NO if not. + */ +static int +match_iterator (void *cls, const GNUNET_HashCode *key, void *value) +{ + struct LockingRequestMatch *match = cls; + struct GNUNET_LOCKMANAGER_LockingRequest *lr = value; + + if ( (match->lock == lr->lock) && (0 == strcmp (match->domain, lr->domain)) ) + { + match->matched_entry = lr; + return GNUNET_NO; + } + return GNUNET_YES; +} + + +/** + * Function to find a LockingRequest associated with the given domain and lock + * attributes in the map + * + * @param map the map where the LockingRequests are stored + * @param domain the locking domain name + * @param lock the lock number + * @return the found LockingRequest; NULL if a matching LockingRequest wasn't + * found + */ +static struct GNUNET_LOCKMANAGER_LockingRequest * +hashmap_find_lockingrequest (const struct GNUNET_CONTAINER_MultiHashMap *map, + const char *domain, + uint32_t lock) +{ + struct GNUNET_HashCode hash; + struct LockingRequestMatch lock_match; + + lock_match.matched_entry = NULL; + lock_match.domain = domain; + lock_match.lock = lock; + get_key (domain, lock, &hash); + GNUNET_CONTAINER_multihashmap_get_multiple (map, + &hash, + &match_iterator, + &lock_match); + return lock_match.matched_entry; +} + + +/** + * Task for calling status change callback for a lock + * + * @param cls the LockingRequest associated with this lock + * @param tc the TaskScheduler context + */ +static void +call_status_cb_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls; + + if (NULL != r->status_cb) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Calling status change for SUCCESS on lock num: %d, domain: %s\n", + r->lock, r->domain); + r->status_cb (r->status_cb_cls, + r->domain, + r->lock, + r->status); + } +} + + +/** + * Iterator to call relase and free all LockingRequest entries + * + * @param cls the lockmanager handle + * @param key current key code + * @param value the Locking request + * @return GNUNET_YES if we should continue to + * iterate, + * GNUNET_NO if not. + */ +static int +release_iterator(void *cls, + const GNUNET_HashCode * key, + void *value) +{ + struct GNUNET_LOCKMANAGER_Handle *h = cls; + struct GNUNET_LOCKMANAGER_LockingRequest *r = value; + + if (NULL != r->status_cb) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Calling status change for RELEASE on lock num: %d, domain: %s\n", + r->lock, r->domain); + r->status_cb (r->status_cb_cls, + r->domain, + r->lock, + GNUNET_LOCKMANAGER_RELEASE); + } + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (h->hashmap, + key, + value)); + GNUNET_free (r->domain); + GNUNET_free (r); + return GNUNET_YES; +} + + +/** + * Handler for server replies + * + * @param cls the LOCKMANAGER_Handle + * @param msg received message, NULL on timeout or fatal error + */ +static void +handle_replies (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_LOCKMANAGER_Handle *handle = cls; + const struct GNUNET_LOCKMANAGER_Message *m; + struct GNUNET_LOCKMANAGER_LockingRequest *lr; + const char *domain; + struct GNUNET_HashCode hash; + uint32_t lock; + uint16_t msize; + + if (NULL == msg) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Lockmanager service not available or went down\n"); + /* Should release all locks and free its locking requests */ + GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, + &release_iterator, + handle); + return; + } + GNUNET_CLIENT_receive (handle->conn, + &handle_replies, + handle, + GNUNET_TIME_UNIT_FOREVER_REL); + if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS != ntohs(msg->type)) + { + GNUNET_break (0); + return; + } + msize = ntohs (msg->size); + if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message)) + { + GNUNET_break (0); + return; + } + m = (const struct GNUNET_LOCKMANAGER_Message *) msg; + domain = (const char *) &m[1]; + msize -= sizeof (struct GNUNET_LOCKMANAGER_Message); + if ('\0' != domain[msize-1]) + { + GNUNET_break (0); + return; + } + + lock = ntohl (m->lock); + get_key (domain, lock, &hash); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received SUCCESS message for lock: %d, domain %s\n", + lock, domain); + if (NULL == (lr = hashmap_find_lockingrequest (handle->hashmap, + domain, + lock))) + { + GNUNET_break (0); + return; + } + if (GNUNET_LOCKMANAGER_SUCCESS == lr->status) + { + GNUNET_break (0); + return; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Changing status for lock: %d in domain: %s to SUCCESS\n", + lr->lock, lr->domain); + lr->status = GNUNET_LOCKMANAGER_SUCCESS; + GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, + lr, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); +} + + +/** + * Iterator to free hash map entries. + * + * @param cls the lockmanger handle + * @param key current key code + * @param value the Locking request + * @return GNUNET_YES if we should continue to + * iterate, + * GNUNET_NO if not. + */ +static int +free_iterator(void *cls, + const GNUNET_HashCode * key, + void *value) +{ + struct GNUNET_LOCKMANAGER_Handle *h = cls; + struct GNUNET_LOCKMANAGER_LockingRequest *r = value; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Clearing locking request\n"); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (h->hashmap, + key, + value)); + GNUNET_free (r->domain); + GNUNET_free (r); + return GNUNET_YES; +} + + +/*******************/ +/* API Definitions */ +/*******************/ + + +/** + * Connect to the lockmanager service + * + * @param cfg the configuration to use + * + * @return upon success the handle to the service; NULL upon error + */ +struct GNUNET_LOCKMANAGER_Handle * +GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_LOCKMANAGER_Handle *h; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); + h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle)); + h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg); + if (NULL == h->conn) + { + GNUNET_free (h); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); + return NULL; + } + h->hashmap = GNUNET_CONTAINER_multihashmap_create (15); + GNUNET_assert (NULL != h->hashmap); + GNUNET_CLIENT_receive (h->conn, + &handle_replies, + h, + GNUNET_TIME_UNIT_FOREVER_REL); + + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); + return h; +} + + +/** + * Disconnect from the lockmanager service + * + * @param handle the handle to the lockmanager service + */ +void +GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle) +{ + struct MessageQueue *head; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); + if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap)) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Some locking requests are still present. Cancel them before " + "calling %s\n", __func__); + GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, + &free_iterator, + handle); + } + GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap); + /* Clear the message queue */ + if (NULL != handle->transmit_handle) + { + GNUNET_CLIENT_notify_transmit_ready_cancel (handle->transmit_handle); + } + head = handle->mq_head; + while (NULL != head) + { + GNUNET_CONTAINER_DLL_remove (handle->mq_head, + handle->mq_tail, + head); + GNUNET_free (head->msg); + GNUNET_free (head); + head = handle->mq_head; + } + GNUNET_CLIENT_disconnect (handle->conn); + GNUNET_free (handle); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); +} + + +/** + * Tries to acquire the given lock(even if the lock has been lost) until the + * request is called. If the lock is available the status_cb will be + * called. If the lock is busy then the request is queued and status_cb + * will be called when the lock has been made available and acquired by us. + * + * @param handle the handle to the lockmanager service + * + * @param domain_name name of the locking domain. Clients who want to share + * locks must use the same name for the locking domain. Also the + * domain_name should be selected with the prefix + * "GNUNET__" to avoid domain name collisions. + * + * + * @param lock which lock to lock + * + * @param status_cb the callback for signalling when the lock is acquired and + * when it is lost + * + * @param status_cb_cls the closure to the above callback + * + * @return the locking request handle for this request + */ +struct GNUNET_LOCKMANAGER_LockingRequest * +GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, + const char *domain_name, + uint32_t lock, + GNUNET_LOCKMANAGER_StatusCallback + status_cb, + void *status_cb_cls) +{ + struct GNUNET_LOCKMANAGER_LockingRequest *r; + struct GNUNET_LOCKMANAGER_Message *msg; + struct GNUNET_HashCode hash; + uint16_t msg_size; + size_t domain_name_length; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); + r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest)); + domain_name_length = strlen (domain_name) + 1; + r->handle = handle; + r->lock = lock; + r->domain = GNUNET_malloc (domain_name_length); + r->status = GNUNET_LOCKMANAGER_RELEASE; + r->status_cb = status_cb; + r->status_cb_cls = status_cb_cls; + memcpy (r->domain, domain_name, domain_name_length); + msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_length; + msg = GNUNET_malloc (msg_size); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE); + msg->header.size = htons (msg_size); + msg->lock = htonl (lock); + memcpy (&msg[1], r->domain, domain_name_length); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n"); + queue_message (handle, msg); + get_key (r->domain, r->lock, &hash); + GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, + &hash, + r, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); + return r; +} + + + +/** + * Function to cancel the locking request generated by + * GNUNET_LOCKMANAGER_acquire_lock. If the lock is acquired us then the lock is + * released. GNUNET_LOCKMANAGER_StatusCallback will not be called upon any + * status changes resulting due to this call. + * + * @param request the LockingRequest to cancel + */ +void +GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest + *request) +{ + struct GNUNET_LOCKMANAGER_Message *msg; + struct GNUNET_HashCode hash; + uint16_t msg_size; + size_t domain_name_length; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); + /* FIXME: Stop ACQUIRE retransmissions */ + if (GNUNET_LOCKMANAGER_SUCCESS == request->status) + { + domain_name_length = strlen (request->domain) + 1; + msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + + domain_name_length; + msg = GNUNET_malloc (msg_size); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE); + msg->header.size = htons (msg_size); + msg->lock = htonl (request->lock); + memcpy (&msg[1], request->domain, domain_name_length); + queue_message (request->handle, msg); + } + get_key (request->domain, request->lock, &hash); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove + (request->handle->hashmap, &hash, request)); + GNUNET_free (request->domain); + GNUNET_free (request); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); +} diff --git a/src/lockmanager/test_lockmanager_api.c b/src/lockmanager/test_lockmanager_api.c new file mode 100644 index 0000000..e8d0412 --- /dev/null +++ b/src/lockmanager/test_lockmanager_api.c @@ -0,0 +1,279 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file lockmanager/test_lockmanager_api.c + * @brief Test cases for lockmanager_api.c + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_lockmanager_service.h" + +#define VERBOSE GNUNET_YES + +#define VERBOSE_ARM 1 + +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +#define TIME_REL_SECONDS(min) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, min) + + +/** + * Enumeration of testing steps + */ +enum Test + { + TEST_FAIL, + + TEST_INIT, + + LOCK1_ACQUIRE, + + LOCK2_ACQUIRE + }; + + +/** + * The testing result + */ +static enum Test result; + +/** + * The process id of the GNUNET ARM process + */ +static struct GNUNET_OS_Process *arm_pid = NULL; + +/** + * Configuration Handle + */ +static struct GNUNET_CONFIGURATION_Handle *config; + +/** + * The handle to the lockmanager service + */ +static struct GNUNET_LOCKMANAGER_Handle *handle; + +/** + * The locking request + */ +static struct GNUNET_LOCKMANAGER_LockingRequest *request; + +/** + * The second locking request + */ +static struct GNUNET_LOCKMANAGER_LockingRequest *request2; + +/** + * Abort task identifier + */ +static GNUNET_SCHEDULER_TaskIdentifier abort_task_id; + +/** + * Shutdown nicely + * + * @param cls + * @param tc the task context + */ +static void +do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (GNUNET_SCHEDULER_NO_TASK != abort_task_id) + { + GNUNET_SCHEDULER_cancel (abort_task_id); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != request) + GNUNET_LOCKMANAGER_cancel_request (request); + if (NULL != request2) + GNUNET_LOCKMANAGER_cancel_request (request2); + GNUNET_LOCKMANAGER_disconnect (handle); + if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Kill gnunet-service-arm manually\n"); + } + GNUNET_OS_process_wait (arm_pid); + GNUNET_OS_process_destroy (arm_pid); + + if (NULL != config) + GNUNET_CONFIGURATION_destroy (config); +} + + +/** + * Shutdown nicely + * + * @param cls + * @param tc the task context + */ +static void +do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Aborting test...\n"); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + result = TEST_FAIL; + do_shutdown (cls, tc); +} + +/** + * Callback for lock status changes + * + * @param cls the closure from GNUNET_LOCKMANAGER_lock call + * + * @param domain_name the locking domain of the lock + * + * @param lock the lock for which this status is relevant + * + * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully + * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost + */ +static void +status_cb (void *cls, + const char *domain_name, + uint32_t lock, + enum GNUNET_LOCKMANAGER_Status status) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Status change callback called on lock: %d of domain: %s\n", + lock, domain_name); + switch (result) + { + case LOCK1_ACQUIRE: + GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status); + GNUNET_assert (NULL != request); + //GNUNET_LOCKMANAGER_cancel_request (request); + //request = NULL; + result = LOCK2_ACQUIRE; + request2 = GNUNET_LOCKMANAGER_acquire_lock (handle, + "GNUNET_LOCKMANAGER_TESTING", + 100, + &status_cb, + NULL); + GNUNET_assert (NULL != request2); + break; + case LOCK2_ACQUIRE: + GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status); + GNUNET_assert (NULL != request); + GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), + &do_shutdown, + NULL); + break; + default: + GNUNET_break (0); + } +} + + +/** + * Testing function + * + * @param cls NULL + * @param tc the task context + */ +static void +test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + handle = GNUNET_LOCKMANAGER_connect (config); + GNUNET_assert (NULL != handle); + result = LOCK1_ACQUIRE; + request = GNUNET_LOCKMANAGER_acquire_lock (handle, + "GNUNET_LOCKMANAGER_TESTING", + 99, + &status_cb, + NULL); + abort_task_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (10), + &do_abort, + NULL); +} + + +/** + * Main point of test execution + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting test...\n"); + config = GNUNET_CONFIGURATION_dup (cfg); + arm_pid = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", +#if VERBOSE_ARM + "-L", "DEBUG", +#endif + "-c", "test_lockmanager_api.conf", NULL); + + GNUNET_assert (NULL != arm_pid); + GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (3), + &test, + NULL); +} + + +/** + * Main function + */ +int main (int argc, char **argv) +{ + int ret; + + char *const argv2[] = { "test-lockmanager-api", + "-c", "test_lockmanager_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_log_setup ("test-lockmanager-api", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + + ret = + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test-lockmanager-api", "nohelp", options, &run, NULL); + + if (GNUNET_OK != ret) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", + ret); + return 1; + } + if (TEST_FAIL == result) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); + return 1; + } + LOG (GNUNET_ERROR_TYPE_INFO, "test OK\n"); + return 0; +} diff --git a/src/lockmanager/test_lockmanager_api.conf b/src/lockmanager/test_lockmanager_api.conf new file mode 100644 index 0000000..894f409 --- /dev/null +++ b/src/lockmanager/test_lockmanager_api.conf @@ -0,0 +1,73 @@ +[lockmanager] +DEBUG = YES +AUTOSTART = NO +PORT = 12112 +ACCEPT_FROM = 127.0.0.1; +HOSTNAME = localhost +# PREFIX = valgrind --leak-check=full +# PREFIX = xterm -geometry 100x85 -T peer1 -e libtool --mode=execute gdb --args + +[fs] +AUTOSTART = NO + +[resolver] +AUTOSTART = NO + +[mesh] +AUTOSTART = NO + +[dht] +AUTOSTART = NO + +[block] +plugins = dht test + +[dhtcache] +QUOTA = 1 MB +DATABASE = sqlite + +[transport] +PLUGINS = tcp +DEBUG = NO +ACCEPT_FROM6 = ::1; +ACCEPT_FROM = 127.0.0.1; +NEIGHBOUR_LIMIT = 50 +PORT = 12365 + +[ats] +WAN_QUOTA_OUT = 3932160 +WAN_QUOTA_IN = 3932160 + +[core] +PORT = 12092 + +[arm] +DEFAULTSERVICES = core lockmanager +PORT = 12366 +DEBUG = NO + +[transport-tcp] +TIMEOUT = 300 s +PORT = 12368 + +[TESTING] +NUM_PEERS = 5 +WEAKRANDOM = YES +DEBUG = YES +HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat +MAX_CONCURRENT_SSH = 10 +USE_PROGRESSBARS = YES +PEERGROUP_TIMEOUT = 2400 s + +[gnunetd] +HOSTKEY = $SERVICEHOME/.hostkey + +[PATHS] +DEFAULTCONFIG = test_lockmanager_api.conf +SERVICEHOME = /tmp/test-lockmanager/ + +[dns] +AUTOSTART = NO + +[nse] +AUTOSTART = NO diff --git a/src/lockmanager/test_lockmanager_api_lockrelease.c b/src/lockmanager/test_lockmanager_api_lockrelease.c new file mode 100644 index 0000000..7e24d10 --- /dev/null +++ b/src/lockmanager/test_lockmanager_api_lockrelease.c @@ -0,0 +1,301 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file lockmanager/test_lockmanager_api_lockrelease.c + * @brief Test cases for lockmanager_api where client disconnects abruptly + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_lockmanager_service.h" + +#define VERBOSE GNUNET_YES + +#define VERBOSE_ARM 1 + +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +#define TIME_REL_SECONDS(min) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, min) + +/** + * Various steps of the test + */ +enum Test + { + /** + * Signal test failure + */ + TEST_FAIL, + + /** + * Testing just began + */ + TEST_INIT, + + /** + * Client 1 has got the lock successfully; Client 2 should try to acquire + * the lock now; after some time client 1 has to release the lock + */ + TEST_CLIENT1_LOCK_SUCCESS, + + /** + * Client 2 has got the lock; Should release it and call shutdown + */ + TEST_CLIENT2_LOCK_SUCCESS, + }; + +/** + * The testing result + */ +static enum Test result; + +/** + * The process id of the GNUNET ARM process + */ +static struct GNUNET_OS_Process *arm_pid = NULL; + +/** + * Configuration Handle + */ +static struct GNUNET_CONFIGURATION_Handle *config; + +/** + * The handle to the lockmanager service + */ +static struct GNUNET_LOCKMANAGER_Handle *handle; + +/** + * A second client handle to the lockmanager service + */ +static struct GNUNET_LOCKMANAGER_Handle *handle2; + +/** + * The locking request + */ +static struct GNUNET_LOCKMANAGER_LockingRequest *request; + +/** + * The locking request of second client + */ +static struct GNUNET_LOCKMANAGER_LockingRequest *request2; + +/** + * Abort task identifier + */ +static GNUNET_SCHEDULER_TaskIdentifier abort_task_id; + + +/** + * Shutdown nicely + * + * @param cls + * @param tc the task context + */ +static void +do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (GNUNET_SCHEDULER_NO_TASK != abort_task_id) + { + GNUNET_SCHEDULER_cancel (abort_task_id); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_LOCKMANAGER_disconnect (handle); + GNUNET_LOCKMANAGER_disconnect (handle2); + if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Kill gnunet-service-arm manually\n"); + } + GNUNET_OS_process_wait (arm_pid); + GNUNET_OS_process_destroy (arm_pid); + + if (NULL != config) + GNUNET_CONFIGURATION_destroy (config); +} + + +/** + * Abort + * + * @param cls + * @param tc the task context + */ +static void +do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Aborting test...\n"); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + result = TEST_FAIL; + do_shutdown (cls, tc); +} + + +/** + * Callback for lock status changes + * + * @param cls the handle + * + * @param domain_name the locking domain of the lock + * + * @param lock the lock for which this status is relevant + * + * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully + * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost + */ +static void +status_cb (void *cls, + const char *domain_name, + uint32_t lock, + enum GNUNET_LOCKMANAGER_Status status) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Status change callback called on lock: %d of domain: %s\n", + lock, domain_name); + GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status); + switch (result) + { + case TEST_INIT: + GNUNET_assert (handle == cls); + result = TEST_CLIENT1_LOCK_SUCCESS; + request2 = GNUNET_LOCKMANAGER_acquire_lock (handle2, + "GNUNET_LOCKMANAGER_TESTING", + 99, + &status_cb, + handle2); + GNUNET_assert (NULL != request2); + GNUNET_LOCKMANAGER_cancel_request (request); + request = NULL; + break; + case TEST_CLIENT1_LOCK_SUCCESS: + GNUNET_assert (handle2 == cls); + result = TEST_CLIENT2_LOCK_SUCCESS; + GNUNET_LOCKMANAGER_cancel_request (request2); + GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), + &do_shutdown, + NULL); + break; + default: + GNUNET_assert (0); /* We should never reach here */ + } + +} + + +/** + * Testing function + * + * @param cls NULL + * @param tc the task context + */ +static void +test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + result = TEST_INIT; + handle = GNUNET_LOCKMANAGER_connect (config); + GNUNET_assert (NULL != handle); + handle2 = GNUNET_LOCKMANAGER_connect (config); + + request = GNUNET_LOCKMANAGER_acquire_lock (handle, + "GNUNET_LOCKMANAGER_TESTING", + 99, + &status_cb, + handle); + GNUNET_assert (NULL != request); + abort_task_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (10), + &do_abort, + NULL); +} + + +/** + * Main point of test execution + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting test...\n"); + config = GNUNET_CONFIGURATION_dup (cfg); + arm_pid = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", +#if VERBOSE_ARM + "-L", "DEBUG", +#endif + "-c", "test_lockmanager_api.conf", NULL); + + GNUNET_assert (NULL != arm_pid); + GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (3), + &test, + NULL); +} + + +/** + * Main function + */ +int main (int argc, char **argv) +{ + int ret; + + char *const argv2[] = { "test-lockmanager-api-lockrelease", + "-c", "test_lockmanager_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_log_setup ("test-lockmanager-api-lockrelease", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + + ret = + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test-lockmanager-api-lockrelease", + "nohelp", options, &run, NULL); + + if (GNUNET_OK != ret) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", + ret); + return 1; + } + if (TEST_CLIENT2_LOCK_SUCCESS != result) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); + return 1; + } + LOG (GNUNET_ERROR_TYPE_INFO, "test OK\n"); + return 0; +} diff --git a/src/lockmanager/test_lockmanager_api_servercrash.c b/src/lockmanager/test_lockmanager_api_servercrash.c new file mode 100644 index 0000000..3fa6418 --- /dev/null +++ b/src/lockmanager/test_lockmanager_api_servercrash.c @@ -0,0 +1,326 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file lockmanager/test_lockmanager_api_servercrash.c + * @brief Test cases for lockmanager_api where the server crashes + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_lockmanager_service.h" + +#define VERBOSE GNUNET_YES + +#define VERBOSE_ARM 1 + +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +#define TIME_REL_SECONDS(min) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, min) + +/** + * Various steps of the test + */ +enum Test + { + /** + * Signal test failure + */ + TEST_FAIL, + + /** + * Testing just began + */ + TEST_INIT, + + /** + * Client 1 has got the lock successfully; Client 2 should try to acquire + * the lock now; after some time client 1 has to release the lock + */ + TEST_CLIENT1_LOCK_SUCCESS, + + /** + * Client 2 has got the lock; Server should crash now; + */ + TEST_CLIENT2_LOCK_SUCCESS, + + /** + * Client 2 should get lock release due to server crash; Should call + * shutdown now + */ + TEST_CLIENT2_SERVER_CRASH_SUCCESS + }; + +/** + * The testing result + */ +static enum Test result; + +/** + * The process id of the GNUNET ARM process + */ +static struct GNUNET_OS_Process *arm_pid = NULL; + +/** + * Configuration Handle + */ +static struct GNUNET_CONFIGURATION_Handle *config; + +/** + * The handle to the lockmanager service + */ +static struct GNUNET_LOCKMANAGER_Handle *handle; + +/** + * A second client handle to the lockmanager service + */ +static struct GNUNET_LOCKMANAGER_Handle *handle2; + +/** + * The locking request + */ +static struct GNUNET_LOCKMANAGER_LockingRequest *request; + +/** + * The locking request of second client + */ +static struct GNUNET_LOCKMANAGER_LockingRequest *request2; + +/** + * Abort task identifier + */ +static GNUNET_SCHEDULER_TaskIdentifier abort_task_id; + + +/** + * Shutdown nicely + * + * @param cls + * @param tc the task context + */ +static void +do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (GNUNET_SCHEDULER_NO_TASK != abort_task_id) + { + GNUNET_SCHEDULER_cancel (abort_task_id); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != handle) + GNUNET_LOCKMANAGER_disconnect (handle); + if (NULL != handle2) + GNUNET_LOCKMANAGER_disconnect (handle2); + if (NULL != arm_pid) + { + if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Kill gnunet-service-arm manually\n"); + } + GNUNET_OS_process_wait (arm_pid); + GNUNET_OS_process_destroy (arm_pid); + } + if (NULL != config) + GNUNET_CONFIGURATION_destroy (config); +} + + +/** + * Abort + * + * @param cls + * @param tc the task context + */ +static void +do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Aborting test...\n"); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + result = TEST_FAIL; + do_shutdown (cls, tc); +} + + +/** + * Callback for lock status changes + * + * @param cls the handle + * + * @param domain_name the locking domain of the lock + * + * @param lock the lock for which this status is relevant + * + * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully + * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost + */ +static void +status_cb (void *cls, + const char *domain_name, + uint32_t lock, + enum GNUNET_LOCKMANAGER_Status status) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Status change callback called on lock: %d of domain: %s\n", + lock, domain_name); + switch (result) + { + case TEST_INIT: + GNUNET_assert (handle == cls); + GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status); + result = TEST_CLIENT1_LOCK_SUCCESS; + request2 = GNUNET_LOCKMANAGER_acquire_lock (handle2, + "GNUNET_LOCKMANAGER_TESTING", + 99, + &status_cb, + handle2); + GNUNET_assert (NULL != request2); + GNUNET_LOCKMANAGER_cancel_request (request); + request = NULL; + break; + case TEST_CLIENT1_LOCK_SUCCESS: + GNUNET_assert (handle2 == cls); + GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status); + result = TEST_CLIENT2_LOCK_SUCCESS; + /* We should kill the lockmanager process */ + if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Kill gnunet-service-arm manually\n"); + } + GNUNET_OS_process_wait (arm_pid); + GNUNET_OS_process_destroy (arm_pid); + arm_pid =NULL; + break; + case TEST_CLIENT2_LOCK_SUCCESS: + GNUNET_assert (handle2 == cls); + GNUNET_assert (GNUNET_LOCKMANAGER_RELEASE == status); + GNUNET_assert (99 == lock); + GNUNET_assert (0 == strcmp (domain_name, "GNUNET_LOCKMANAGER_TESTING")); + result = TEST_CLIENT2_SERVER_CRASH_SUCCESS; + GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), + &do_shutdown, + NULL); + break; + default: + GNUNET_assert (0); /* We should never reach here */ + } + +} + + +/** + * Testing function + * + * @param cls NULL + * @param tc the task context + */ +static void +test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + result = TEST_INIT; + handle = GNUNET_LOCKMANAGER_connect (config); + GNUNET_assert (NULL != handle); + handle2 = GNUNET_LOCKMANAGER_connect (config); + + request = GNUNET_LOCKMANAGER_acquire_lock (handle, + "GNUNET_LOCKMANAGER_TESTING", + 99, + &status_cb, + handle); + GNUNET_assert (NULL != request); + abort_task_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (10), + &do_abort, + NULL); +} + + +/** + * Main point of test execution + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting test...\n"); + config = GNUNET_CONFIGURATION_dup (cfg); + arm_pid = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", +#if VERBOSE_ARM + "-L", "DEBUG", +#endif + "-c", "test_lockmanager_api.conf", NULL); + + GNUNET_assert (NULL != arm_pid); + GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (3), + &test, + NULL); +} + + +/** + * Main function + */ +int main (int argc, char **argv) +{ + int ret; + + char *const argv2[] = { "test-lockmanager-api-servercrash", + "-c", "test_lockmanager_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_log_setup ("test-lockmanager-api-servercrash", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + + ret = + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test-lockmanager-api-servercrash", + "nohelp", options, &run, NULL); + + if (GNUNET_OK != ret) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", + ret); + return 1; + } + if (TEST_CLIENT2_SERVER_CRASH_SUCCESS != result) + { + LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); + return 1; + } + LOG (GNUNET_ERROR_TYPE_INFO, "test OK\n"); + return 0; +} diff --git a/src/mesh/Makefile.am b/src/mesh/Makefile.am index e9c0109..ac38b0d 100644 --- a/src/mesh/Makefile.am +++ b/src/mesh/Makefile.am @@ -41,7 +41,7 @@ libgnunetmesh_la_LIBADD = \ $(XLIB) libgnunetmesh_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 0:0:0 + -version-info 1:0:0 check_PROGRAMS = \ test_mesh_api \ diff --git a/src/mesh/Makefile.in b/src/mesh/Makefile.in index 337d6ab..1504c4b 100644 --- a/src/mesh/Makefile.in +++ b/src/mesh/Makefile.in @@ -242,6 +242,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -275,6 +276,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -426,7 +428,7 @@ libgnunetmesh_la_LIBADD = \ libgnunetmesh_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 0:0:0 + -version-info 1:0:0 test_mesh_api_SOURCES = \ test_mesh_api.c diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index 80848f2..36c6115 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c @@ -474,21 +474,25 @@ struct MeshClient /** * GNUNET_SCHEDULER_Task for printing a message after some operation is done * @param cls string to print - * @param tc task context + * @param success GNUNET_OK if the PUT was transmitted, + * GNUNET_NO on timeout, + * GNUNET_SYSERR on disconnect from service + * after the PUT message was transmitted + * (so we don't know if it was received or not) */ + +#if 0 static void -mesh_debug (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +mesh_debug (void *cls, int success) { char *s = cls; - if (NULL != tc && GNUNET_SCHEDULER_REASON_SHUTDOWN == tc->reason) - { - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", s); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s (%d)\n", s, success); } #endif +#endif + /******************************************************************************/ /*********************** GLOBAL VARIABLES ****************************/ /******************************************************************************/ @@ -622,19 +626,15 @@ static int announce_application (void *cls, const GNUNET_HashCode * key, void *value) { /* FIXME are hashes in multihash map equal on all aquitectures? */ - GNUNET_DHT_put (dht_handle, key, 10U, + /* FIXME: keep return value of 'put' to possibly cancel!? */ + GNUNET_DHT_put (dht_handle, key, 10, GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_BLOCK_TYPE_TEST, sizeof (struct GNUNET_PeerIdentity), (const char *) &my_full_id, -#if MESH_DEBUG - GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_FOREVER_REL, - &mesh_debug, "DHT_put for app completed"); -#else GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), APP_ANNOUNCE_TIME), APP_ANNOUNCE_TIME, NULL, NULL); -#endif return GNUNET_OK; } @@ -689,19 +689,15 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_DHT_put (dht_handle, /* DHT handle */ &my_full_id.hashPubKey, /* Key to use */ - 10U, /* Replication level */ + 10, /* Replication level */ GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */ GNUNET_BLOCK_TYPE_TEST, /* Block type */ sizeof (my_full_id), /* Size of the data */ (char *) &my_full_id, /* Data itself */ - GNUNET_TIME_absolute_get_forever (), /* Data expiration */ + GNUNET_TIME_UNIT_FOREVER_ABS, /* Data expiration */ GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */ -#if MESH_DEBUG_DHT - &mesh_debug, "DHT_put for id completed"); -#else NULL, /* Continuation */ NULL); /* Continuation closure */ -#endif announce_id_task = GNUNET_SCHEDULER_add_delayed (ID_ANNOUNCE_TIME, &announce_id, cls); } @@ -1608,10 +1604,9 @@ peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t) " Starting DHT GET for peer %s\n", GNUNET_i2s (&id)); peer->dhtgetcls = path_info; peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */ - GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */ GNUNET_BLOCK_TYPE_TEST, /* type */ &id.hashPubKey, /* key to search */ - 10U, /* replication level */ + 10, /* replication level */ GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, NULL, /* xquery */ 0, /* xquery bits */ &dht_get_id_handler, path_info); @@ -2987,7 +2982,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, info->peer->types[j] = GNUNET_MESSAGE_TYPE_MESH_PATH_ACK; info->peer->infos[j] = info; info->peer->core_transmit[j] = - GNUNET_CORE_notify_transmit_ready (core_handle, 0, 100, + GNUNET_CORE_notify_transmit_ready (core_handle, 0, 10, GNUNET_TIME_UNIT_FOREVER_REL, peer, sizeof (struct GNUNET_MESH_PathACK), &send_core_path_ack, info); @@ -4025,8 +4020,7 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - send_client_tunnel_disconnect(t, c); - if (c != t->owner) + if (c != t->owner || tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) { client_ignore_tunnel (c, t); #if 0 @@ -4045,6 +4039,7 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } + send_client_tunnel_disconnect(t, c); client_delete_tunnel(c, t); /* Don't try to ACK the client about the tunnel_destroy multicast packet */ @@ -4288,8 +4283,8 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking in DHT for %s\n", GNUNET_h2s (&hash)); t->dht_get_type = - GNUNET_DHT_get_start (dht_handle, GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_BLOCK_TYPE_TEST, &hash, 10U, + GNUNET_DHT_get_start (dht_handle, + GNUNET_BLOCK_TYPE_TEST, &hash, 10, GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, NULL, 0, &dht_get_type_handler, t); @@ -4370,7 +4365,7 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client, * (pretend we got it from a mesh peer) */ { - char buf[ntohs (message->size)]; + char buf[ntohs (message->size)] GNUNET_ALIGN; struct GNUNET_MESH_Unicast *copy; /* Work around const limitation */ @@ -4454,7 +4449,7 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client, * (pretend we got it from a mesh peer) */ { - char buf[ntohs (message->size)]; + char buf[ntohs (message->size)] GNUNET_ALIGN; struct GNUNET_MESH_ToOrigin *copy; /* Work around const limitation */ @@ -4527,7 +4522,7 @@ handle_local_multicast (void *cls, struct GNUNET_SERVER_Client *client, } { - char buf[ntohs (message->size)]; + char buf[ntohs (message->size)] GNUNET_ALIGN; struct GNUNET_MESH_Multicast *copy; copy = (struct GNUNET_MESH_Multicast *) buf; diff --git a/src/mesh/mesh_api.c b/src/mesh/mesh_api.c index 7b9aa06..de931db 100644 --- a/src/mesh/mesh_api.c +++ b/src/mesh/mesh_api.c @@ -28,14 +28,6 @@ * - SEND FUNCTIONS * - API CALL DEFINITIONS */ -#ifdef __cplusplus -extern "C" -{ -#if 0 /* keep Emacsens' auto-indent happy */ -} -#endif -#endif - #include "platform.h" #include "gnunet_common.h" #include "gnunet_client_lib.h" @@ -45,13 +37,8 @@ extern "C" #include "mesh.h" #include "mesh_protocol.h" -#define MESH_API_DEBUG GNUNET_YES - -#if MESH_API_DEBUG #define LOG(kind,...) GNUNET_log_from (kind, "mesh-api",__VA_ARGS__) -#else -#define LOG(kind,...) -#endif + /******************************************************************************/ /************************ DATA STRUCTURES ****************************/ @@ -618,7 +605,7 @@ send_connect (struct GNUNET_MESH_Handle *h) size += h->n_applications * sizeof (GNUNET_MESH_ApplicationType); size += h->n_handlers * sizeof (uint16_t); { - char buf[size]; + char buf[size] GNUNET_ALIGN; struct GNUNET_MESH_ClientConnect *msg; GNUNET_MESH_ApplicationType *apps; uint16_t napps; @@ -675,7 +662,7 @@ do_reconnect (struct GNUNET_MESH_Handle *h) } if (NULL != h->client) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); } /* connect again */ @@ -805,26 +792,38 @@ process_tunnel_created (struct GNUNET_MESH_Handle *h, GNUNET_break (0); return; } - t = create_tunnel (h, tid); - t->owner = GNUNET_PEER_intern (&msg->peer); - t->npeers = 1; - t->peers = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer *)); - t->peers[0] = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer)); - t->peers[0]->t = t; - t->peers[0]->connected = 1; - t->peers[0]->id = t->owner; - GNUNET_PEER_change_rc (t->owner, 1); - t->mesh = h; - t->tid = tid; if (NULL != h->new_tunnel) { struct GNUNET_ATS_Information atsi; + t = create_tunnel (h, tid); + t->owner = GNUNET_PEER_intern (&msg->peer); + t->npeers = 1; + t->peers = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer *)); + t->peers[0] = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer)); + t->peers[0]->t = t; + t->peers[0]->connected = 1; + t->peers[0]->id = t->owner; + GNUNET_PEER_change_rc (t->owner, 1); + t->mesh = h; + t->tid = tid; atsi.type = 0; atsi.value = 0; t->ctx = h->new_tunnel (h->cls, t, &msg->peer, &atsi); + LOG (GNUNET_ERROR_TYPE_DEBUG, "new incoming tunnel %X\n", t->tid); + } + else + { + struct GNUNET_MESH_TunnelMessage d_msg; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "No handler for incoming tunnels\n"); + + d_msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY); + d_msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage)); + d_msg.tunnel_id = msg->tunnel_id; + + send_packet (h, &d_msg.header, NULL); } - LOG (GNUNET_ERROR_TYPE_DEBUG, "new incoming tunnel %X\n", t->tid); return; } @@ -853,7 +852,7 @@ process_tunnel_destroy (struct GNUNET_MESH_Handle *h, { GNUNET_break (0); } - LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %u destroyed\n", t->tid); + LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %X destroyed\n", t->tid); destroy_tunnel (t, GNUNET_YES); return; } @@ -974,7 +973,7 @@ process_incoming_data (struct GNUNET_MESH_Handle *h, } if (NULL == t) { - GNUNET_break (0); + /* Tunnel was ignored, probably service didn't get it yet */ return GNUNET_YES; } type = ntohs (payload->type); @@ -1363,7 +1362,7 @@ GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle) } if (NULL != handle->client) { - GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (handle->client); handle->client = NULL; } if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task) @@ -1446,7 +1445,7 @@ GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel) } destroy_tunnel (tunnel, GNUNET_NO); - send_packet (h, &msg.header, tunnel); + send_packet (h, &msg.header, NULL); } @@ -1705,9 +1704,3 @@ GNUNET_MESH_tunnel_get_data (struct GNUNET_MESH_Tunnel *tunnel) } -#if 0 /* keep Emacsens' auto-indent happy */ -{ -#endif -#ifdef __cplusplus -} -#endif diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c index 445b710..287eefc 100644 --- a/src/mesh/mesh_tunnel_tree.c +++ b/src/mesh/mesh_tunnel_tree.c @@ -837,7 +837,7 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Adding peer %s.\n", GNUNET_i2s (&id)); GNUNET_PEER_resolve (parent->peer, &id); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: to %s.\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: to %s.\n", GNUNET_i2s (&id)); #endif @@ -860,11 +860,11 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, #endif n = tree_node_new (parent, p->peers[i]); n->status = MESH_PEER_RELAY; - if (n->peer == 1) - { - t->me = n; - me = i; - } + } + if (n->peer == 1) + { + t->me = n; + me = i; } i++; parent = n; diff --git a/src/mesh/test_mesh.conf b/src/mesh/test_mesh.conf index 3d955f0..f2e51e4 100644 --- a/src/mesh/test_mesh.conf +++ b/src/mesh/test_mesh.conf @@ -19,7 +19,7 @@ AUTOSTART = YES ACCEPT_FROM6 = ::1; ACCEPT_FROM = 127.0.0.1; HOSTNAME = localhost -PORT = 2100 +PORT = 12100 [block] plugins = dht test @@ -67,3 +67,6 @@ AUTOSTART = NO [nse] AUTOSTART = NO + +[namestore] +AUTOSTART = NO diff --git a/src/mesh/test_mesh_2dtorus.c b/src/mesh/test_mesh_2dtorus.c index 9946fe2..c708e8f 100644 --- a/src/mesh/test_mesh_2dtorus.c +++ b/src/mesh/test_mesh_2dtorus.c @@ -171,7 +171,7 @@ topo_cb (void *cls, const struct GNUNET_PeerIdentity *first, if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (disconnect_task); - GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); + disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); } return; } @@ -316,7 +316,7 @@ run (void *cls, char *const *args, const char *cfgfile, hosts); GNUNET_assert (pg != NULL); shutdown_handle = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_get_forever (), + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); } diff --git a/src/mesh/test_mesh_api.c b/src/mesh/test_mesh_api.c index fbc1fba..1e12e9b 100644 --- a/src/mesh/test_mesh_api.c +++ b/src/mesh/test_mesh_api.c @@ -85,7 +85,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid)); - GNUNET_OS_process_close (arm_pid); + GNUNET_OS_process_destroy (arm_pid); } static void diff --git a/src/mesh/test_mesh_local_1.c b/src/mesh/test_mesh_local_1.c index 73e2bdc..d80bee8 100644 --- a/src/mesh/test_mesh_local_1.c +++ b/src/mesh/test_mesh_local_1.c @@ -77,7 +77,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n"); GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid)); - GNUNET_OS_process_close (arm_pid); + GNUNET_OS_process_destroy (arm_pid); } diff --git a/src/mesh/test_mesh_local_2.c b/src/mesh/test_mesh_local_2.c index b185f1b..d495b71 100644 --- a/src/mesh/test_mesh_local_2.c +++ b/src/mesh/test_mesh_local_2.c @@ -76,7 +76,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n"); GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid)); - GNUNET_OS_process_close (arm_pid); + GNUNET_OS_process_destroy (arm_pid); } diff --git a/src/mesh/test_mesh_path.conf b/src/mesh/test_mesh_path.conf index 3d955f0..c3d8a2c 100644 --- a/src/mesh/test_mesh_path.conf +++ b/src/mesh/test_mesh_path.conf @@ -19,7 +19,7 @@ AUTOSTART = YES ACCEPT_FROM6 = ::1; ACCEPT_FROM = 127.0.0.1; HOSTNAME = localhost -PORT = 2100 +PORT = 12100 [block] plugins = dht test diff --git a/src/mesh/test_mesh_small.c b/src/mesh/test_mesh_small.c index b06e324..974b635 100644 --- a/src/mesh/test_mesh_small.c +++ b/src/mesh/test_mesh_small.c @@ -901,7 +901,7 @@ run (void *cls, char *const *args, const char *cfgfile, hosts); GNUNET_assert (pg != NULL); shutdown_handle = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_get_forever (), + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); } diff --git a/src/mysql/Makefile.am b/src/mysql/Makefile.am new file mode 100644 index 0000000..1711e75 --- /dev/null +++ b/src/mysql/Makefile.am @@ -0,0 +1,20 @@ +INCLUDES = -I$(top_srcdir)/src/include + +if MINGW + WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +endif + +if USE_COVERAGE + AM_CFLAGS = --coverage +endif + +lib_LTLIBRARIES = libgnunetmysql.la + +libgnunetmysql_la_SOURCES = \ + mysql.c +libgnunetmysql_la_LIBADD = -lmysqlclient \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunetmysql_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + diff --git a/src/mysql/Makefile.in b/src/mysql/Makefile.in new file mode 100644 index 0000000..f058135 --- /dev/null +++ b/src/mysql/Makefile.in @@ -0,0 +1,654 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/mysql +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ + $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ + $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/gnunet_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libgnunetmysql_la_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la +am_libgnunetmysql_la_OBJECTS = mysql.lo +libgnunetmysql_la_OBJECTS = $(am_libgnunetmysql_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libgnunetmysql_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libgnunetmysql_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libgnunetmysql_la_SOURCES) +DIST_SOURCES = $(libgnunetmysql_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_INTERFACE = @DEFAULT_INTERFACE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLDIR = @DLLDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXT_LIBS = @EXT_LIBS@ +EXT_LIB_PATH = @EXT_LIB_PATH@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ +GN_DAEMON_CONFIG_DIR = @GN_DAEMON_CONFIG_DIR@ +GN_DAEMON_HOME_DIR = @GN_DAEMON_HOME_DIR@ +GN_INTLINCL = @GN_INTLINCL@ +GN_LIBINTL = @GN_LIBINTL@ +GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ +GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ +GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GREP = @GREP@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBPREFIX = @LIBPREFIX@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNISTRING = @LIBUNISTRING@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ +POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CPPFLAGS = @SQLITE_CPPFLAGS@ +SQLITE_LDFLAGS = @SQLITE_LDFLAGS@ +STRIP = @STRIP@ +SUDO_BINARY = @SUDO_BINARY@ +UNIXONLY = @UNIXONLY@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_OBJC = @ac_ct_OBJC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_target = @build_target@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/src/include +@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage +lib_LTLIBRARIES = libgnunetmysql.la +libgnunetmysql_la_SOURCES = \ + mysql.c + +libgnunetmysql_la_LIBADD = -lmysqlclient \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunetmysql_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/mysql/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/mysql/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgnunetmysql.la: $(libgnunetmysql_la_OBJECTS) $(libgnunetmysql_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunetmysql_la_LINK) -rpath $(libdir) $(libgnunetmysql_la_OBJECTS) $(libgnunetmysql_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mysql.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/mysql/mysql.c b/src/mysql/mysql.c new file mode 100644 index 0000000..098213b --- /dev/null +++ b/src/mysql/mysql.c @@ -0,0 +1,698 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file mysql/mysql.c + * @brief library to help with access to a MySQL database + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include "gnunet_mysql_lib.h" + +/** + * Maximum number of supported parameters for a prepared + * statement. Increase if needed. + */ +#define MAX_PARAM 16 + + +/** + * Die with an error message that indicates + * a failure of the command 'cmd' with the message given + * by strerror(errno). + */ +#define DIE_MYSQL(cmd, dbh) do { GNUNET_log_from (GNUNET_ERROR_TYPE__ERROR, "mysql", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); GNUNET_abort(); } while(0); + +/** + * Log an error message at log-level 'level' that indicates + * a failure of the command 'cmd' on file 'filename' + * with the message given by strerror(errno). + */ +#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log_from (level, "mysql", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } while(0); + + +/** + * Mysql context. + */ +struct GNUNET_MYSQL_Context +{ + + /** + * Our configuration. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Our section. + */ + const char *section; + + /** + * Handle to the mysql database. + */ + MYSQL *dbf; + + /** + * Head of list of our prepared statements. + */ + struct GNUNET_MYSQL_StatementHandle *shead; + + /** + * Tail of list of our prepared statements. + */ + struct GNUNET_MYSQL_StatementHandle *stail; + + /** + * Filename of "my.cnf" (msyql configuration). + */ + char *cnffile; + +}; + + +/** + * Handle for a prepared statement. + */ +struct GNUNET_MYSQL_StatementHandle +{ + + /** + * Kept in a DLL. + */ + struct GNUNET_MYSQL_StatementHandle *next; + + /** + * Kept in a DLL. + */ + struct GNUNET_MYSQL_StatementHandle *prev; + + /** + * Original query string. + */ + char *query; + + /** + * Handle to MySQL prepared statement. + */ + MYSQL_STMT *statement; + + /** + * Is the MySQL prepared statement valid, or do we need to re-initialize it? + */ + int valid; + +}; + + +/** + * Obtain the location of ".my.cnf". + * + * @param cfg our configuration + * @param section the section + * @return NULL on error + */ +static char * +get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section) +{ + char *cnffile; + char *home_dir; + struct stat st; + +#ifndef WINDOWS + struct passwd *pw; +#endif + int configured; + +#ifndef WINDOWS + pw = getpwuid (getuid ()); + if (!pw) + { + GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_ERROR, "mysql", "getpwuid"); + return NULL; + } + if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, section, "CONFIG")) + { + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, section, + "CONFIG", + &cnffile)); + configured = GNUNET_YES; + } + else + { + home_dir = GNUNET_strdup (pw->pw_dir); + GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); + GNUNET_free (home_dir); + configured = GNUNET_NO; + } +#else + home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1); + plibc_conv_to_win_path ("~/", home_dir); + GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); + GNUNET_free (home_dir); + configured = GNUNET_NO; +#endif + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "mysql", + _("Trying to use file `%s' for MySQL configuration.\n"), + cnffile); + if ((0 != STAT (cnffile, &st)) || (0 != ACCESS (cnffile, R_OK)) || + (!S_ISREG (st.st_mode))) + { + if (configured == GNUNET_YES) + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", + _("Could not access file `%s': %s\n"), cnffile, + STRERROR (errno)); + GNUNET_free (cnffile); + return NULL; + } + return cnffile; +} + + +/** + * Open the connection with the database (and initialize + * our default options). + * + * @param mc database context to initialze + * @return GNUNET_OK on success + */ +static int +iopen (struct GNUNET_MYSQL_Context *mc) +{ + char *mysql_dbname; + char *mysql_server; + char *mysql_user; + char *mysql_password; + unsigned long long mysql_port; + my_bool reconnect; + unsigned int timeout; + + mc->dbf = mysql_init (NULL); + if (mc->dbf == NULL) + return GNUNET_SYSERR; + if (mc->cnffile != NULL) + mysql_options (mc->dbf, MYSQL_READ_DEFAULT_FILE, mc->cnffile); + mysql_options (mc->dbf, MYSQL_READ_DEFAULT_GROUP, "client"); + reconnect = 0; + mysql_options (mc->dbf, MYSQL_OPT_RECONNECT, &reconnect); + mysql_options (mc->dbf, MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout); + mysql_options (mc->dbf, MYSQL_SET_CHARSET_NAME, "UTF8"); + timeout = 60; /* in seconds */ + mysql_options (mc->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout); + mysql_options (mc->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout); + mysql_dbname = NULL; + if (GNUNET_YES == + GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "DATABASE")) + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (mc->cfg, mc->section, + "DATABASE", + &mysql_dbname)); + else + mysql_dbname = GNUNET_strdup ("gnunet"); + mysql_user = NULL; + if (GNUNET_YES == + GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "USER")) + { + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (mc->cfg, mc->section, + "USER", &mysql_user)); + } + mysql_password = NULL; + if (GNUNET_YES == + GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "PASSWORD")) + { + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (mc->cfg, mc->section, + "PASSWORD", + &mysql_password)); + } + mysql_server = NULL; + if (GNUNET_YES == + GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "HOST")) + { + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (mc->cfg, mc->section, + "HOST", + &mysql_server)); + } + mysql_port = 0; + if (GNUNET_YES == + GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "PORT")) + { + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number (mc->cfg, mc->section, + "PORT", &mysql_port)); + } + + GNUNET_assert (mysql_dbname != NULL); + mysql_real_connect (mc->dbf, mysql_server, mysql_user, mysql_password, + mysql_dbname, (unsigned int) mysql_port, NULL, + CLIENT_IGNORE_SIGPIPE); + GNUNET_free_non_null (mysql_server); + GNUNET_free_non_null (mysql_user); + GNUNET_free_non_null (mysql_password); + GNUNET_free (mysql_dbname); + if (mysql_error (mc->dbf)[0]) + { + LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_real_connect", mc); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Create a mysql context. + * + * @param cfg configuration + * @param section configuration section to use to get MySQL configuration options + * @return the mysql context + */ +struct GNUNET_MYSQL_Context * +GNUNET_MYSQL_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section) +{ + struct GNUNET_MYSQL_Context *mc; + + mc = GNUNET_malloc (sizeof (struct GNUNET_MYSQL_Context)); + mc->cfg = cfg; + mc->section = section; + mc->cnffile = get_my_cnf_path (cfg, section); + + return mc; +} + + +/** + * Close database connection and all prepared statements (we got a DB + * error). + * + * @param mc mysql context + */ +void +GNUNET_MYSQL_statements_invalidate (struct GNUNET_MYSQL_Context *mc) +{ + struct GNUNET_MYSQL_StatementHandle *sh; + + for (sh = mc->shead; NULL != sh; sh = sh->next) + { + if (GNUNET_YES == sh->valid) + { + mysql_stmt_close (sh->statement); + sh->valid = GNUNET_NO; + } + sh->statement = NULL; + } + if (NULL != mc->dbf) + { + mysql_close (mc->dbf); + mc->dbf = NULL; + } +} + + +/** + * Destroy a mysql context. Also frees all associated prepared statements. + * + * @param mc context to destroy + */ +void +GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc) +{ + struct GNUNET_MYSQL_StatementHandle *sh; + + GNUNET_MYSQL_statements_invalidate (mc); + while (NULL != (sh = mc->shead)) + { + GNUNET_CONTAINER_DLL_remove (mc->shead, mc->stail, sh); + GNUNET_free (sh->query); + GNUNET_free (sh); + } + GNUNET_free (mc); + mysql_library_end (); +} + + +/** + * Prepare a statement. Prepared statements are automatically discarded + * when the MySQL context is destroyed. + * + * @param mc mysql context + * @param query query text + * @return prepared statement, NULL on error + */ +struct GNUNET_MYSQL_StatementHandle * +GNUNET_MYSQL_statement_prepare (struct GNUNET_MYSQL_Context *mc, + const char *query) +{ + struct GNUNET_MYSQL_StatementHandle *sh; + + sh = GNUNET_malloc (sizeof (struct GNUNET_MYSQL_StatementHandle)); + sh->query = GNUNET_strdup (query); + GNUNET_CONTAINER_DLL_insert (mc->shead, mc->stail, sh); + return sh; +} + + +/** + * Run a SQL statement. + * + * @param mc mysql context + * @param sql SQL statement to run + * @return GNUNET_OK on success + * GNUNET_SYSERR if there was a problem + */ +int +GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc, const char *sql) +{ + if ((NULL == mc->dbf) && (GNUNET_OK != iopen (mc))) + return GNUNET_SYSERR; + mysql_query (mc->dbf, sql); + if (mysql_error (mc->dbf)[0]) + { + LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_query", mc); + GNUNET_MYSQL_statements_invalidate (mc); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Prepare a statement for running. + * + * @param mc mysql context + * @param sh statement handle to prepare + * @return GNUNET_OK on success + */ +static int +prepare_statement (struct GNUNET_MYSQL_Context *mc, + struct GNUNET_MYSQL_StatementHandle *sh) +{ + if (GNUNET_YES == sh->valid) + return GNUNET_OK; + if ((NULL == mc->dbf) && (GNUNET_OK != iopen (mc))) + return GNUNET_SYSERR; + sh->statement = mysql_stmt_init (mc->dbf); + if (NULL == sh->statement) + { + GNUNET_MYSQL_statements_invalidate (mc); + return GNUNET_SYSERR; + } + if (0 != mysql_stmt_prepare (sh->statement, sh->query, strlen (sh->query))) + { + LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", mc); + mysql_stmt_close (sh->statement); + sh->statement = NULL; + GNUNET_MYSQL_statements_invalidate (mc); + return GNUNET_SYSERR; + } + sh->valid = GNUNET_YES; + return GNUNET_OK; +} + + +/** + * Get internal handle for a prepared statement. This function should rarely + * be used, and if, with caution! On failures during the interaction with + * the handle, you must call 'GNUNET_MYSQL_statements_invalidate'! + * + * @param mc mysql context + * @param sh prepared statement to introspect + * @return MySQL statement handle, NULL on error + */ +MYSQL_STMT * +GNUNET_MYSQL_statement_get_stmt (struct GNUNET_MYSQL_Context * mc, + struct GNUNET_MYSQL_StatementHandle * sh) +{ + (void) prepare_statement (mc, sh); + return sh->statement; +} + + +/** + * Bind the parameters for the given MySQL statement + * and run it. + * + * @param mc mysql context + * @param sh statement to bind and run + * @param ap arguments for the binding + * @return GNUNET_SYSERR on error, GNUNET_OK on success + */ +static int +init_params (struct GNUNET_MYSQL_Context *mc, + struct GNUNET_MYSQL_StatementHandle *sh, va_list ap) +{ + MYSQL_BIND qbind[MAX_PARAM]; + unsigned int pc; + unsigned int off; + enum enum_field_types ft; + + pc = mysql_stmt_param_count (sh->statement); + if (pc > MAX_PARAM) + { + /* increase internal constant! */ + GNUNET_break (0); + return GNUNET_SYSERR; + } + memset (qbind, 0, sizeof (qbind)); + off = 0; + ft = 0; + while ((pc > 0) && (-1 != (int) (ft = va_arg (ap, enum enum_field_types)))) + { + qbind[off].buffer_type = ft; + switch (ft) + { + case MYSQL_TYPE_FLOAT: + qbind[off].buffer = va_arg (ap, float *); + + break; + case MYSQL_TYPE_LONGLONG: + qbind[off].buffer = va_arg (ap, unsigned long long *); + qbind[off].is_unsigned = va_arg (ap, int); + + break; + case MYSQL_TYPE_LONG: + qbind[off].buffer = va_arg (ap, unsigned int *); + qbind[off].is_unsigned = va_arg (ap, int); + + break; + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_BLOB: + qbind[off].buffer = va_arg (ap, void *); + qbind[off].buffer_length = va_arg (ap, unsigned long); + qbind[off].length = va_arg (ap, unsigned long *); + + break; + default: + /* unsupported type */ + GNUNET_break (0); + return GNUNET_SYSERR; + } + pc--; + off++; + } + if (!((pc == 0) && (-1 != (int) ft) && (va_arg (ap, int) == -1))) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (mysql_stmt_bind_param (sh->statement, qbind)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", + _("`%s' failed at %s:%d with error: %s\n"), + "mysql_stmt_bind_param", __FILE__, __LINE__, + mysql_stmt_error (sh->statement)); + GNUNET_MYSQL_statements_invalidate (mc); + return GNUNET_SYSERR; + } + if (mysql_stmt_execute (sh->statement)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", + _("`%s' failed at %s:%d with error: %s\n"), + "mysql_stmt_execute", __FILE__, __LINE__, + mysql_stmt_error (sh->statement)); + GNUNET_MYSQL_statements_invalidate (mc); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + + +/** + * Run a prepared SELECT statement. + * + * @param mc mysql context + * @param s statement to run + * @param result_size number of elements in results array + * @param results pointer to already initialized MYSQL_BIND + * array (of sufficient size) for passing results + * @param processor function to call on each result + * @param processor_cls extra argument to processor + * @param ap pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective + * values (size + buffer-reference for pointers); terminated + * with "-1" + * @return GNUNET_SYSERR on error, otherwise + * the number of successfully affected (or queried) rows + */ +int +GNUNET_MYSQL_statement_run_prepared_select_va (struct GNUNET_MYSQL_Context *mc, + struct + GNUNET_MYSQL_StatementHandle *s, + unsigned int result_size, + MYSQL_BIND * results, + GNUNET_MYSQL_DataProcessor + processor, void *processor_cls, + va_list ap) +{ + int ret; + unsigned int rsize; + int total; + + if (GNUNET_OK != prepare_statement (mc, s)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != init_params (mc, s, ap)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + rsize = mysql_stmt_field_count (s->statement); + if (rsize > result_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (mysql_stmt_bind_result (s->statement, results)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("`%s' failed at %s:%d with error: %s\n"), + "mysql_stmt_bind_result", __FILE__, __LINE__, + mysql_stmt_error (s->statement)); + GNUNET_MYSQL_statements_invalidate (mc); + return GNUNET_SYSERR; + } + + total = 0; + while (1) + { + ret = mysql_stmt_fetch (s->statement); + if (ret == MYSQL_NO_DATA) + break; + if (ret != 0) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", + _("`%s' failed at %s:%d with error: %s\n"), + "mysql_stmt_fetch", __FILE__, __LINE__, + mysql_stmt_error (s->statement)); + GNUNET_MYSQL_statements_invalidate (mc); + return GNUNET_SYSERR; + } + total++; + if ((NULL == processor) || + (GNUNET_OK != processor (processor_cls, rsize, results))) + break; + } + mysql_stmt_reset (s->statement); + return total; +} + + +/** + * Run a prepared SELECT statement. + * + * @param mc mysql context + * @param sh handle to SELECT statment + * @param result_size number of elements in results array + * @param results pointer to already initialized MYSQL_BIND + * array (of sufficient size) for passing results + * @param processor function to call on each result + * @param processor_cls extra argument to processor + * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective + * values (size + buffer-reference for pointers); terminated + * with "-1" + * @return GNUNET_SYSERR on error, otherwise + * the number of successfully affected (or queried) rows + */ +int +GNUNET_MYSQL_statement_run_prepared_select (struct GNUNET_MYSQL_Context *mc, + struct GNUNET_MYSQL_StatementHandle + *sh, unsigned int result_size, + MYSQL_BIND * results, + GNUNET_MYSQL_DataProcessor + processor, void *processor_cls, ...) +{ + va_list ap; + int ret; + + va_start (ap, processor_cls); + ret = + GNUNET_MYSQL_statement_run_prepared_select_va (mc, sh, result_size, + results, processor, + processor_cls, ap); + va_end (ap); + return ret; +} + + +/** + * Run a prepared statement that does NOT produce results. + * + * @param mc mysql context + * @param sh handle to statment + * @param insert_id NULL or address where to store the row ID of whatever + * was inserted (only for INSERT statements!) + * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective + * values (size + buffer-reference for pointers); terminated + * with "-1" + * @return GNUNET_SYSERR on error, otherwise + * the number of successfully affected rows + */ +int +GNUNET_MYSQL_statement_run_prepared (struct GNUNET_MYSQL_Context *mc, + struct GNUNET_MYSQL_StatementHandle *sh, + unsigned long long *insert_id, ...) +{ + va_list ap; + int affected; + + if (GNUNET_OK != prepare_statement (mc, sh)) + return GNUNET_SYSERR; + va_start (ap, insert_id); + if (GNUNET_OK != init_params (mc, sh, ap)) + { + va_end (ap); + return GNUNET_SYSERR; + } + va_end (ap); + affected = mysql_stmt_affected_rows (sh->statement); + if (NULL != insert_id) + *insert_id = (unsigned long long) mysql_stmt_insert_id (sh->statement); + mysql_stmt_reset (sh->statement); + return affected; +} + + +/* end of mysql.c */ diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 47517b9..7783506 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am @@ -2,10 +2,11 @@ INCLUDES = -I$(top_srcdir)/src/include plugindir = $(libdir)/gnunet -pkgcfgdir= $(pkgnamedir)/config.d/ +pkgcfgdir= $(pkgdatadir)/config.d/ + +pkgcfg_DATA = \ + namestore.conf -pkgcfg_NAME = \ - namestore.conf if MINGW WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols @@ -24,19 +25,30 @@ endif check_PROGRAMS = \ $(SQLITE_TESTS) \ + test_namestore_record_serialization \ + test_namestore_api_sign_verify \ test_namestore_api \ + test_namestore_api_put \ + test_namestore_api_lookup \ + test_namestore_api_lookup_specific_type \ + test_namestore_api_create \ + test_namestore_api_create_update \ + test_namestore_api_remove \ + test_namestore_api_remove_not_existing_record \ + test_namestore_api_zone_to_name \ test_namestore_api_zone_iteration \ - test_namestore_record_serialization + test_namestore_api_zone_iteration_specific_zone \ + test_namestore_api_zone_iteration_stop -if HAVE_EXPERIMENTAL - check_PROGRAMS +if ENABLE_TEST_RUN +TESTS = $(check_PROGRAMS) endif lib_LTLIBRARIES = \ libgnunetnamestore.la - + libgnunetnamestore_la_SOURCES = \ - namestore_api.c namestore.h + namestore_api.c namestore_common.c namestore.h libgnunetnamestore_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -46,15 +58,34 @@ libgnunetnamestore_la_LDFLAGS = \ -version-info 0:0:0 bin_PROGRAMS = \ - gnunet-service-namestore + gnunet-service-namestore \ + gnunet-namestore + + +gnunet_namestore_SOURCES = \ + gnunet-namestore.c +gnunet_namestore_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la \ + $(GN_LIBINTL) +gnunet_namestore_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la + + gnunet_service_namestore_SOURCES = \ - gnunet-service-namestore.c \ - namestore_common.c + gnunet-service-namestore.c + gnunet_service_namestore_LDADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la \ $(GN_LIBINTL) +gnunet_service_namestore_DEPENDENCIES = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la if HAVE_SQLITE SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la @@ -64,31 +95,100 @@ plugin_LTLIBRARIES = \ $(SQLITE_PLUGIN) libgnunet_plugin_namestore_sqlite_la_SOURCES = \ - plugin_namestore_sqlite.c + plugin_namestore_sqlite.c namestore_common.c libgnunet_plugin_namestore_sqlite_la_LIBADD = \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 libgnunet_plugin_namestore_sqlite_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) +libgnunet_plugin_namestore_sqlite_la_DEPENDENCIES = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la +test_namestore_api_sign_verify_SOURCES = \ + test_namestore_api_sign_verify.c +test_namestore_api_sign_verify_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la test_namestore_api_SOURCES = \ - test_namestore_api.c \ - namestore_common.c + test_namestore_api.c test_namestore_api_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la - + +test_namestore_api_put_SOURCES = \ + test_namestore_api_put.c +test_namestore_api_put_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_lookup_SOURCES = \ + test_namestore_api_lookup.c +test_namestore_api_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_lookup_specific_type_SOURCES = \ + test_namestore_api_lookup_specific_type.c +test_namestore_api_lookup_specific_type_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + + +test_namestore_api_create_SOURCES = \ + test_namestore_api_create.c +test_namestore_api_create_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_create_update_SOURCES = \ + test_namestore_api_create_update.c +test_namestore_api_create_update_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + + +test_namestore_api_remove_SOURCES = \ + test_namestore_api_remove.c +test_namestore_api_remove_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_remove_not_existing_record_SOURCES = \ + test_namestore_api_remove_not_existing_record.c +test_namestore_api_remove_not_existing_record_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_zone_to_name_SOURCES = \ + test_namestore_api_zone_to_name.c +test_namestore_api_zone_to_name_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + test_namestore_api_zone_iteration_SOURCES = \ - test_namestore_api_zone_iteration.c \ - namestore_common.c + test_namestore_api_zone_iteration.c test_namestore_api_zone_iteration_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_zone_iteration_specific_zone_SOURCES = \ + test_namestore_api_zone_iteration_specific_zone.c +test_namestore_api_zone_iteration_specific_zone_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_zone_iteration_stop_SOURCES = \ + test_namestore_api_zone_iteration_stop.c +test_namestore_api_zone_iteration_stop_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la test_namestore_record_serialization_SOURCES = \ - test_namestore_record_serialization.c \ - namestore_common.c + test_namestore_record_serialization.c test_namestore_record_serialization_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la @@ -96,7 +196,9 @@ test_namestore_record_serialization_LDADD = \ EXTRA_DIST = \ test_namestore_api.conf \ test_plugin_namestore_sqlite.conf\ - hostkey + test_hostkey \ + zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey \ + zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey test_plugin_namestore_sqlite_SOURCES = \ diff --git a/src/namestore/Makefile.in b/src/namestore/Makefile.in index 2ed2a46..180232d 100644 --- a/src/namestore/Makefile.in +++ b/src/namestore/Makefile.in @@ -16,6 +16,7 @@ @SET_MAKE@ + VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ @@ -36,10 +37,22 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -check_PROGRAMS = $(am__EXEEXT_1) test_namestore_api$(EXEEXT) \ +check_PROGRAMS = $(am__EXEEXT_1) \ + test_namestore_record_serialization$(EXEEXT) \ + test_namestore_api_sign_verify$(EXEEXT) \ + test_namestore_api$(EXEEXT) test_namestore_api_put$(EXEEXT) \ + test_namestore_api_lookup$(EXEEXT) \ + test_namestore_api_lookup_specific_type$(EXEEXT) \ + test_namestore_api_create$(EXEEXT) \ + test_namestore_api_create_update$(EXEEXT) \ + test_namestore_api_remove$(EXEEXT) \ + test_namestore_api_remove_not_existing_record$(EXEEXT) \ + test_namestore_api_zone_to_name$(EXEEXT) \ test_namestore_api_zone_iteration$(EXEEXT) \ - test_namestore_record_serialization$(EXEEXT) -bin_PROGRAMS = gnunet-service-namestore$(EXEEXT) + test_namestore_api_zone_iteration_specific_zone$(EXEEXT) \ + test_namestore_api_zone_iteration_stop$(EXEEXT) +bin_PROGRAMS = gnunet-service-namestore$(EXEEXT) \ + gnunet-namestore$(EXEEXT) subdir = src/namestore DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/namestore.conf.in @@ -84,15 +97,11 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" \ - "$(DESTDIR)$(bindir)" + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = -libgnunet_plugin_namestore_sqlite_la_DEPENDENCIES = \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(am__DEPENDENCIES_1) am_libgnunet_plugin_namestore_sqlite_la_OBJECTS = \ - plugin_namestore_sqlite.lo + plugin_namestore_sqlite.lo namestore_common.lo libgnunet_plugin_namestore_sqlite_la_OBJECTS = \ $(am_libgnunet_plugin_namestore_sqlite_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) @@ -109,7 +118,8 @@ libgnunetnamestore_la_DEPENDENCIES = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) -am_libgnunetnamestore_la_OBJECTS = namestore_api.lo +am_libgnunetnamestore_la_OBJECTS = namestore_api.lo \ + namestore_common.lo libgnunetnamestore_la_OBJECTS = $(am_libgnunetnamestore_la_OBJECTS) libgnunetnamestore_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -118,31 +128,101 @@ libgnunetnamestore_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @HAVE_SQLITE_TRUE@am__EXEEXT_1 = \ @HAVE_SQLITE_TRUE@ test_plugin_namestore_sqlite$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) +am_gnunet_namestore_OBJECTS = gnunet-namestore.$(OBJEXT) +gnunet_namestore_OBJECTS = $(am_gnunet_namestore_OBJECTS) am_gnunet_service_namestore_OBJECTS = \ - gnunet-service-namestore.$(OBJEXT) namestore_common.$(OBJEXT) + gnunet-service-namestore.$(OBJEXT) gnunet_service_namestore_OBJECTS = \ $(am_gnunet_service_namestore_OBJECTS) -gnunet_service_namestore_DEPENDENCIES = \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(am__DEPENDENCIES_1) -am_test_namestore_api_OBJECTS = test_namestore_api.$(OBJEXT) \ - namestore_common.$(OBJEXT) +am_test_namestore_api_OBJECTS = test_namestore_api.$(OBJEXT) test_namestore_api_OBJECTS = $(am_test_namestore_api_OBJECTS) test_namestore_api_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_create_OBJECTS = \ + test_namestore_api_create.$(OBJEXT) +test_namestore_api_create_OBJECTS = \ + $(am_test_namestore_api_create_OBJECTS) +test_namestore_api_create_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_create_update_OBJECTS = \ + test_namestore_api_create_update.$(OBJEXT) +test_namestore_api_create_update_OBJECTS = \ + $(am_test_namestore_api_create_update_OBJECTS) +test_namestore_api_create_update_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_lookup_OBJECTS = \ + test_namestore_api_lookup.$(OBJEXT) +test_namestore_api_lookup_OBJECTS = \ + $(am_test_namestore_api_lookup_OBJECTS) +test_namestore_api_lookup_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_lookup_specific_type_OBJECTS = \ + test_namestore_api_lookup_specific_type.$(OBJEXT) +test_namestore_api_lookup_specific_type_OBJECTS = \ + $(am_test_namestore_api_lookup_specific_type_OBJECTS) +test_namestore_api_lookup_specific_type_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_put_OBJECTS = test_namestore_api_put.$(OBJEXT) +test_namestore_api_put_OBJECTS = $(am_test_namestore_api_put_OBJECTS) +test_namestore_api_put_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_remove_OBJECTS = \ + test_namestore_api_remove.$(OBJEXT) +test_namestore_api_remove_OBJECTS = \ + $(am_test_namestore_api_remove_OBJECTS) +test_namestore_api_remove_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_remove_not_existing_record_OBJECTS = \ + test_namestore_api_remove_not_existing_record.$(OBJEXT) +test_namestore_api_remove_not_existing_record_OBJECTS = \ + $(am_test_namestore_api_remove_not_existing_record_OBJECTS) +test_namestore_api_remove_not_existing_record_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_sign_verify_OBJECTS = \ + test_namestore_api_sign_verify.$(OBJEXT) +test_namestore_api_sign_verify_OBJECTS = \ + $(am_test_namestore_api_sign_verify_OBJECTS) +test_namestore_api_sign_verify_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la am_test_namestore_api_zone_iteration_OBJECTS = \ - test_namestore_api_zone_iteration.$(OBJEXT) \ - namestore_common.$(OBJEXT) + test_namestore_api_zone_iteration.$(OBJEXT) test_namestore_api_zone_iteration_OBJECTS = \ $(am_test_namestore_api_zone_iteration_OBJECTS) test_namestore_api_zone_iteration_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_zone_iteration_specific_zone_OBJECTS = \ + test_namestore_api_zone_iteration_specific_zone.$(OBJEXT) +test_namestore_api_zone_iteration_specific_zone_OBJECTS = \ + $(am_test_namestore_api_zone_iteration_specific_zone_OBJECTS) +test_namestore_api_zone_iteration_specific_zone_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_zone_iteration_stop_OBJECTS = \ + test_namestore_api_zone_iteration_stop.$(OBJEXT) +test_namestore_api_zone_iteration_stop_OBJECTS = \ + $(am_test_namestore_api_zone_iteration_stop_OBJECTS) +test_namestore_api_zone_iteration_stop_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la +am_test_namestore_api_zone_to_name_OBJECTS = \ + test_namestore_api_zone_to_name.$(OBJEXT) +test_namestore_api_zone_to_name_OBJECTS = \ + $(am_test_namestore_api_zone_to_name_OBJECTS) +test_namestore_api_zone_to_name_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la am_test_namestore_record_serialization_OBJECTS = \ - test_namestore_record_serialization.$(OBJEXT) \ - namestore_common.$(OBJEXT) + test_namestore_record_serialization.$(OBJEXT) test_namestore_record_serialization_OBJECTS = \ $(am_test_namestore_record_serialization_OBJECTS) test_namestore_record_serialization_DEPENDENCIES = \ @@ -181,21 +261,46 @@ AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgnunet_plugin_namestore_sqlite_la_SOURCES) \ - $(libgnunetnamestore_la_SOURCES) \ + $(libgnunetnamestore_la_SOURCES) $(gnunet_namestore_SOURCES) \ $(gnunet_service_namestore_SOURCES) \ $(test_namestore_api_SOURCES) \ + $(test_namestore_api_create_SOURCES) \ + $(test_namestore_api_create_update_SOURCES) \ + $(test_namestore_api_lookup_SOURCES) \ + $(test_namestore_api_lookup_specific_type_SOURCES) \ + $(test_namestore_api_put_SOURCES) \ + $(test_namestore_api_remove_SOURCES) \ + $(test_namestore_api_remove_not_existing_record_SOURCES) \ + $(test_namestore_api_sign_verify_SOURCES) \ $(test_namestore_api_zone_iteration_SOURCES) \ + $(test_namestore_api_zone_iteration_specific_zone_SOURCES) \ + $(test_namestore_api_zone_iteration_stop_SOURCES) \ + $(test_namestore_api_zone_to_name_SOURCES) \ $(test_namestore_record_serialization_SOURCES) \ $(test_plugin_namestore_sqlite_SOURCES) DIST_SOURCES = $(libgnunet_plugin_namestore_sqlite_la_SOURCES) \ - $(libgnunetnamestore_la_SOURCES) \ + $(libgnunetnamestore_la_SOURCES) $(gnunet_namestore_SOURCES) \ $(gnunet_service_namestore_SOURCES) \ $(test_namestore_api_SOURCES) \ + $(test_namestore_api_create_SOURCES) \ + $(test_namestore_api_create_update_SOURCES) \ + $(test_namestore_api_lookup_SOURCES) \ + $(test_namestore_api_lookup_specific_type_SOURCES) \ + $(test_namestore_api_put_SOURCES) \ + $(test_namestore_api_remove_SOURCES) \ + $(test_namestore_api_remove_not_existing_record_SOURCES) \ + $(test_namestore_api_sign_verify_SOURCES) \ $(test_namestore_api_zone_iteration_SOURCES) \ + $(test_namestore_api_zone_iteration_specific_zone_SOURCES) \ + $(test_namestore_api_zone_iteration_stop_SOURCES) \ + $(test_namestore_api_zone_to_name_SOURCES) \ $(test_namestore_record_serialization_SOURCES) \ $(test_plugin_namestore_sqlite_SOURCES) +DATA = $(pkgcfg_DATA) ETAGS = etags CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -252,6 +357,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -285,6 +391,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -403,9 +510,9 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = -I$(top_srcdir)/src/include plugindir = $(libdir)/gnunet -pkgcfgdir = $(pkgnamedir)/config.d/ -pkgcfg_NAME = \ - namestore.conf +pkgcfgdir = $(pkgdatadir)/config.d/ +pkgcfg_DATA = \ + namestore.conf @MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols @USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0 @@ -413,11 +520,12 @@ pkgcfg_NAME = \ @HAVE_SQLITE_TRUE@SQLITE_TESTS = \ @HAVE_SQLITE_TRUE@ test_plugin_namestore_sqlite +@ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) lib_LTLIBRARIES = \ libgnunetnamestore.la libgnunetnamestore_la_SOURCES = \ - namestore_api.c namestore.h + namestore_api.c namestore_common.c namestore.h libgnunetnamestore_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ @@ -428,48 +536,145 @@ libgnunetnamestore_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ -version-info 0:0:0 +gnunet_namestore_SOURCES = \ + gnunet-namestore.c + +gnunet_namestore_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la \ + $(GN_LIBINTL) + +gnunet_namestore_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la + gnunet_service_namestore_SOURCES = \ - gnunet-service-namestore.c \ - namestore_common.c + gnunet-service-namestore.c gnunet_service_namestore_LDADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la \ $(GN_LIBINTL) +gnunet_service_namestore_DEPENDENCIES = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la + @HAVE_SQLITE_TRUE@SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la plugin_LTLIBRARIES = \ $(SQLITE_PLUGIN) libgnunet_plugin_namestore_sqlite_la_SOURCES = \ - plugin_namestore_sqlite.c + plugin_namestore_sqlite.c namestore_common.c libgnunet_plugin_namestore_sqlite_la_LIBADD = \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 libgnunet_plugin_namestore_sqlite_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) +libgnunet_plugin_namestore_sqlite_la_DEPENDENCIES = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + libgnunetnamestore.la + +test_namestore_api_sign_verify_SOURCES = \ + test_namestore_api_sign_verify.c + +test_namestore_api_sign_verify_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + test_namestore_api_SOURCES = \ - test_namestore_api.c \ - namestore_common.c + test_namestore_api.c test_namestore_api_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la +test_namestore_api_put_SOURCES = \ + test_namestore_api_put.c + +test_namestore_api_put_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_lookup_SOURCES = \ + test_namestore_api_lookup.c + +test_namestore_api_lookup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_lookup_specific_type_SOURCES = \ + test_namestore_api_lookup_specific_type.c + +test_namestore_api_lookup_specific_type_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_create_SOURCES = \ + test_namestore_api_create.c + +test_namestore_api_create_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_create_update_SOURCES = \ + test_namestore_api_create_update.c + +test_namestore_api_create_update_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_remove_SOURCES = \ + test_namestore_api_remove.c + +test_namestore_api_remove_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_remove_not_existing_record_SOURCES = \ + test_namestore_api_remove_not_existing_record.c + +test_namestore_api_remove_not_existing_record_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_zone_to_name_SOURCES = \ + test_namestore_api_zone_to_name.c + +test_namestore_api_zone_to_name_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + test_namestore_api_zone_iteration_SOURCES = \ - test_namestore_api_zone_iteration.c \ - namestore_common.c + test_namestore_api_zone_iteration.c test_namestore_api_zone_iteration_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la +test_namestore_api_zone_iteration_specific_zone_SOURCES = \ + test_namestore_api_zone_iteration_specific_zone.c + +test_namestore_api_zone_iteration_specific_zone_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + +test_namestore_api_zone_iteration_stop_SOURCES = \ + test_namestore_api_zone_iteration_stop.c + +test_namestore_api_zone_iteration_stop_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + test_namestore_record_serialization_SOURCES = \ - test_namestore_record_serialization.c \ - namestore_common.c + test_namestore_record_serialization.c test_namestore_record_serialization_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -478,7 +683,9 @@ test_namestore_record_serialization_LDADD = \ EXTRA_DIST = \ test_namestore_api.conf \ test_plugin_namestore_sqlite.conf\ - hostkey + test_hostkey \ + zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey \ + zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey test_plugin_namestore_sqlite_SOURCES = \ test_plugin_namestore.c @@ -640,15 +847,51 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list +gnunet-namestore$(EXEEXT): $(gnunet_namestore_OBJECTS) $(gnunet_namestore_DEPENDENCIES) + @rm -f gnunet-namestore$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_namestore_OBJECTS) $(gnunet_namestore_LDADD) $(LIBS) gnunet-service-namestore$(EXEEXT): $(gnunet_service_namestore_OBJECTS) $(gnunet_service_namestore_DEPENDENCIES) @rm -f gnunet-service-namestore$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_service_namestore_OBJECTS) $(gnunet_service_namestore_LDADD) $(LIBS) test_namestore_api$(EXEEXT): $(test_namestore_api_OBJECTS) $(test_namestore_api_DEPENDENCIES) @rm -f test_namestore_api$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_namestore_api_OBJECTS) $(test_namestore_api_LDADD) $(LIBS) +test_namestore_api_create$(EXEEXT): $(test_namestore_api_create_OBJECTS) $(test_namestore_api_create_DEPENDENCIES) + @rm -f test_namestore_api_create$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_create_OBJECTS) $(test_namestore_api_create_LDADD) $(LIBS) +test_namestore_api_create_update$(EXEEXT): $(test_namestore_api_create_update_OBJECTS) $(test_namestore_api_create_update_DEPENDENCIES) + @rm -f test_namestore_api_create_update$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_create_update_OBJECTS) $(test_namestore_api_create_update_LDADD) $(LIBS) +test_namestore_api_lookup$(EXEEXT): $(test_namestore_api_lookup_OBJECTS) $(test_namestore_api_lookup_DEPENDENCIES) + @rm -f test_namestore_api_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_lookup_OBJECTS) $(test_namestore_api_lookup_LDADD) $(LIBS) +test_namestore_api_lookup_specific_type$(EXEEXT): $(test_namestore_api_lookup_specific_type_OBJECTS) $(test_namestore_api_lookup_specific_type_DEPENDENCIES) + @rm -f test_namestore_api_lookup_specific_type$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_lookup_specific_type_OBJECTS) $(test_namestore_api_lookup_specific_type_LDADD) $(LIBS) +test_namestore_api_put$(EXEEXT): $(test_namestore_api_put_OBJECTS) $(test_namestore_api_put_DEPENDENCIES) + @rm -f test_namestore_api_put$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_put_OBJECTS) $(test_namestore_api_put_LDADD) $(LIBS) +test_namestore_api_remove$(EXEEXT): $(test_namestore_api_remove_OBJECTS) $(test_namestore_api_remove_DEPENDENCIES) + @rm -f test_namestore_api_remove$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_remove_OBJECTS) $(test_namestore_api_remove_LDADD) $(LIBS) +test_namestore_api_remove_not_existing_record$(EXEEXT): $(test_namestore_api_remove_not_existing_record_OBJECTS) $(test_namestore_api_remove_not_existing_record_DEPENDENCIES) + @rm -f test_namestore_api_remove_not_existing_record$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_remove_not_existing_record_OBJECTS) $(test_namestore_api_remove_not_existing_record_LDADD) $(LIBS) +test_namestore_api_sign_verify$(EXEEXT): $(test_namestore_api_sign_verify_OBJECTS) $(test_namestore_api_sign_verify_DEPENDENCIES) + @rm -f test_namestore_api_sign_verify$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_sign_verify_OBJECTS) $(test_namestore_api_sign_verify_LDADD) $(LIBS) test_namestore_api_zone_iteration$(EXEEXT): $(test_namestore_api_zone_iteration_OBJECTS) $(test_namestore_api_zone_iteration_DEPENDENCIES) @rm -f test_namestore_api_zone_iteration$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_namestore_api_zone_iteration_OBJECTS) $(test_namestore_api_zone_iteration_LDADD) $(LIBS) +test_namestore_api_zone_iteration_specific_zone$(EXEEXT): $(test_namestore_api_zone_iteration_specific_zone_OBJECTS) $(test_namestore_api_zone_iteration_specific_zone_DEPENDENCIES) + @rm -f test_namestore_api_zone_iteration_specific_zone$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_zone_iteration_specific_zone_OBJECTS) $(test_namestore_api_zone_iteration_specific_zone_LDADD) $(LIBS) +test_namestore_api_zone_iteration_stop$(EXEEXT): $(test_namestore_api_zone_iteration_stop_OBJECTS) $(test_namestore_api_zone_iteration_stop_DEPENDENCIES) + @rm -f test_namestore_api_zone_iteration_stop$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_zone_iteration_stop_OBJECTS) $(test_namestore_api_zone_iteration_stop_LDADD) $(LIBS) +test_namestore_api_zone_to_name$(EXEEXT): $(test_namestore_api_zone_to_name_OBJECTS) $(test_namestore_api_zone_to_name_DEPENDENCIES) + @rm -f test_namestore_api_zone_to_name$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_namestore_api_zone_to_name_OBJECTS) $(test_namestore_api_zone_to_name_LDADD) $(LIBS) test_namestore_record_serialization$(EXEEXT): $(test_namestore_record_serialization_OBJECTS) $(test_namestore_record_serialization_DEPENDENCIES) @rm -f test_namestore_record_serialization$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_namestore_record_serialization_OBJECTS) $(test_namestore_record_serialization_LDADD) $(LIBS) @@ -662,12 +905,24 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-namestore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-namestore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namestore_api.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namestore_common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namestore_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_namestore_sqlite.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_create.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_create_update.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_lookup_specific_type.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_put.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_remove.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_remove_not_existing_record.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_sign_verify.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_zone_iteration.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_zone_iteration_specific_zone.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_zone_iteration_stop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_api_zone_to_name.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_namestore_record_serialization.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin_namestore.Po@am__quote@ @@ -700,6 +955,26 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +install-pkgcfgDATA: $(pkgcfg_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" + @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcfgdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcfgdir)" || exit $$?; \ + done + +uninstall-pkgcfgDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -753,6 +1028,98 @@ GTAGS: distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -785,12 +1152,13 @@ distdir: $(DISTFILES) done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) install-binPROGRAMS: install-libLTLIBRARIES installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -842,7 +1210,7 @@ info: info-am info-am: -install-data-am: install-pluginLTLIBRARIES +install-data-am: install-pkgcfgDATA install-pluginLTLIBRARIES install-dvi: install-dvi-am @@ -889,29 +1257,28 @@ ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-pluginLTLIBRARIES + uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool clean-pluginLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES install-man install-pdf \ - install-pdf-am install-pluginLTLIBRARIES install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-pluginLTLIBRARIES - - -@HAVE_EXPERIMENTAL_TRUE@ check_PROGRAMS +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-pkgcfgDATA \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ + uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c new file mode 100644 index 0000000..a0d1de1 --- /dev/null +++ b/src/namestore/gnunet-namestore.c @@ -0,0 +1,507 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gnunet-namestore.c + * @brief command line tool to manipulate the local zone + * @author Christian Grothoff + * + * TODO: + * - allow users to set record options (not just 'RF_AUTHORITY') + * - test + * - add options to list/lookup individual records + */ +#include "platform.h" +#include +#include +#include + +/** + * Handle to the namestore. + */ +static struct GNUNET_NAMESTORE_Handle *ns; + +/** + * Hash of the public key of our zone. + */ +static struct GNUNET_CRYPTO_ShortHashCode zone; + +/** + * Private key for the our zone. + */ +static struct GNUNET_CRYPTO_RsaPrivateKey *zone_pkey; + +/** + * Keyfile to manipulate. + */ +static char *keyfile; + +/** + * Desired action is to add a record. + */ +static int add; + +/** + * Queue entry for the 'add' operation. + */ +static struct GNUNET_NAMESTORE_QueueEntry *add_qe; + +/** + * Desired action is to list records. + */ +static int list; + +/** + * List iterator for the 'list' operation. + */ +static struct GNUNET_NAMESTORE_ZoneIterator *list_it; + +/** + * Desired action is to remove a record. + */ +static int del; + +/** + * Is record public + */ +static int public; + +/** + * Is record authority + */ +static int nonauthority; + +/** + * Queue entry for the 'del' operation. + */ +static struct GNUNET_NAMESTORE_QueueEntry *del_qe; + +/** + * Name of the records to add/list/remove. + */ +static char *name; + +/** + * Value of the record to add/remove. + */ +static char *value; + +/** + * Type of the record to add/remove, NULL to remove all. + */ +static char *typestring; + +/** + * Desired expiration time. + */ +static char *expirationstring; + + +/** + * Task run on shutdown. Cleans up everything. + * + * @param cls unused + * @param tc scheduler context + */ +static void +do_shutdown (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (NULL != ns) + { + GNUNET_NAMESTORE_disconnect (ns, GNUNET_NO); + ns = NULL; + } + if (NULL != zone_pkey) + { + GNUNET_CRYPTO_rsa_key_free (zone_pkey); + zone_pkey = NULL; + } +} + + +/** + * Continuation called to notify client about result of the + * operation. + * + * @param cls closure, unused + * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate) + * GNUNET_NO if content was already there + * GNUNET_YES (or other positive value) on success + * @param emsg NULL on success, otherwise an error message + */ +static void +add_continuation (void *cls, + int32_t success, + const char *emsg) +{ + add_qe = NULL; + if (success != GNUNET_YES) + fprintf (stderr, + _("Adding record failed: %s\n"), + (success == GNUNET_NO) ? "record exists" : emsg); + if ( (NULL == del_qe) && + (NULL == list_it) ) + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Continuation called to notify client about result of the + * operation. + * + * @param cls closure, unused + * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate) + * GNUNET_NO if content was already there + * GNUNET_YES (or other positive value) on success + * @param emsg NULL on success, otherwise an error message + */ +static void +del_continuation (void *cls, + int32_t success, + const char *emsg) +{ + del_qe = NULL; + if (success != GNUNET_YES) + fprintf (stderr, + _("Deleting record failed: %s\n"), + emsg); + if ( (NULL == add_qe) && + (NULL == list_it) ) + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Process a record that was stored in the namestore. + * + * @param cls closure + * @param zone_key public key of the zone + * @param expire when does the corresponding block in the DHT expire (until + * when should we never do a DHT lookup for the same name again)?; + * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore, + * or the expiration time of the block in the namestore (even if there are zero + * records matching the desired record type) + * @param name name that is being mapped (at most 255 characters long) + * @param rd_len number of entries in 'rd' array + * @param rd array of records with data to store + * @param signature signature of the record block, NULL if signature is unavailable (i.e. + * because the user queried for a particular record type only) + */ +static void +display_record (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_len, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + const char *typestring; + char *s; + unsigned int i; + + if (NULL == name) + { + list_it = NULL; + if ( (NULL == del_qe) && + (NULL == add_qe) ) + GNUNET_SCHEDULER_shutdown (); + return; + } + FPRINTF (stdout, + "%s:\n", + name); + for (i=0;iprivkey; + struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc; + struct GNUNET_DISK_FileHandle *fd; + + if (GNUNET_YES == GNUNET_DISK_file_test (filename)) + { + struct GNUNET_CRYPTO_ShortHashCode zone; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; + struct GNUNET_CRYPTO_RsaPrivateKey * privkey; + + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(filename); + if (privkey == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("File zone `%s' but corrupt content already exists, failed to write! \n"), GNUNET_short_h2s (&zone)); + return GNUNET_SYSERR; + } + + GNUNET_CRYPTO_rsa_key_get_public (privkey, &pubkey); + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone); + GNUNET_CRYPTO_rsa_key_free (privkey); + + if (0 == memcmp (&zone, &c->zone, sizeof(zone))) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("File zone `%s' containing this key already exists\n"), GNUNET_short_h2s (&zone)); + return GNUNET_OK; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("File zone `%s' but different zone key already exists, failed to write! \n"), GNUNET_short_h2s (&zone)); + return GNUNET_OK; + } + } + fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_FAILIFEXISTS, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); + if (NULL == fd) + { + if (errno == EEXIST) + { + if (GNUNET_YES != GNUNET_DISK_file_test (filename)) + { + /* must exist but not be accessible, fail for good! */ + if (0 != ACCESS (filename, R_OK)) + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename); + else + GNUNET_break (0); /* what is going on!? */ + return GNUNET_SYSERR; + } + } + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); + return GNUNET_SYSERR; + } + + if (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), GNUNET_YES)) + { + GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); + return GNUNET_SYSERR; + } + enc = GNUNET_CRYPTO_rsa_encode_key (ret); + GNUNET_assert (enc != NULL); + GNUNET_assert (ntohs (enc->len) == GNUNET_DISK_file_write (fd, enc, ntohs (enc->len))); + GNUNET_free (enc); + GNUNET_DISK_file_sync (fd); + if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded))) + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); + GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Stored zonekey for zone `%s' in file `%s'\n"), GNUNET_short_h2s(&c->zone), c->filename); + return GNUNET_OK; +} + +int zone_to_disk_it (void *cls, + const GNUNET_HashCode *key, + void *value) +{ + struct GNUNET_NAMESTORE_CryptoContainer * c = value; + if (c->filename != NULL) + write_key_to_file(c->filename, c); + else + { + GNUNET_asprintf(&c->filename, "%s/%s.zkey", zonefile_directory, GNUNET_short_h2s (&c->zone)); + write_key_to_file(c->filename, c); + } + + + GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (zonekeys, key, value)); + GNUNET_CRYPTO_rsa_key_free (c->privkey); + GNUNET_free (c->pubkey); + GNUNET_free (c->filename); + GNUNET_free (c); + + return GNUNET_OK; +} + + +struct GNUNET_TIME_Absolute +get_block_expiration_time (unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd) +{ + unsigned int c; + struct GNUNET_TIME_Absolute expire = GNUNET_TIME_UNIT_FOREVER_ABS; + + if (NULL == rd) + return GNUNET_TIME_UNIT_ZERO_ABS; + for (c = 0; c < rd_count; c++) + expire = GNUNET_TIME_absolute_min (rd[c].expiration, expire); + return expire; +} /** * Task run during shutdown. @@ -94,12 +246,16 @@ static void cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); - struct GNUNET_NAMESTORE_ZoneIteration * no; struct GNUNET_NAMESTORE_ZoneIteration * tmp; struct GNUNET_NAMESTORE_Client * nc; struct GNUNET_NAMESTORE_Client * next; + GNUNET_SERVER_notification_context_destroy (snc); + snc = NULL; + GNUNET_CONTAINER_multihashmap_iterate(zonekeys, &zone_to_disk_it, NULL); + GNUNET_CONTAINER_multihashmap_destroy(zonekeys); + for (nc = client_head; nc != NULL; nc = next) { next = nc->next; @@ -109,17 +265,14 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) tmp = no->next; GNUNET_free (no); } - + GNUNET_SERVER_client_drop(nc->client); GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc); GNUNET_free (nc); - } - GNUNET_SERVER_notification_context_destroy (snc); - snc = NULL; - GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database)); GNUNET_free (db_lib_name); + GNUNET_free_non_null(zonefile_directory); } static struct GNUNET_NAMESTORE_Client * @@ -137,7 +290,6 @@ client_lookup (struct GNUNET_SERVER_Client *client) return nc; } - /** * Called whenever a client is disconnected. Frees our * resources associated with that client. @@ -160,16 +312,22 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) if ((NULL == client) || (NULL == nc)) return; - for (no = nc->op_head; no != NULL; no = no->next) + no = nc->op_head; + while (NULL != no) { GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no); GNUNET_free (no); + no = nc->op_head; } + GNUNET_SERVER_client_drop(nc->client); GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc); GNUNET_free (nc); + nc = NULL; } + + static void handle_start (void *cls, struct GNUNET_SERVER_Client * client, const struct GNUNET_MessageHeader * message) @@ -180,18 +338,40 @@ static void handle_start (void *cls, nc->client = client; GNUNET_SERVER_notification_context_add (snc, client); GNUNET_CONTAINER_DLL_insert(client_head, client_tail, nc); - + GNUNET_SERVER_client_keep (client); GNUNET_SERVER_receive_done (client, GNUNET_OK); } struct LookupNameContext { struct GNUNET_NAMESTORE_Client *nc; - uint32_t id; + uint32_t request_id; uint32_t record_type; + struct GNUNET_CRYPTO_ShortHashCode *zone; + char * name; }; - +void drop_iterator (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_len, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct GNUNET_CRYPTO_ShortHashCode zone_hash; + int * stop = cls; + if (NULL != zone_key) + { + GNUNET_CRYPTO_short_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_hash); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting zone `%s'\n", GNUNET_short_h2s (&zone_hash)); + GSN_database->delete_zone (GSN_database->cls, &zone_hash); + } + else + { + (*stop) = GNUNET_YES; + } +} static void @@ -206,24 +386,26 @@ handle_lookup_name_it (void *cls, /* send response */ struct LookupNameContext *lnc = cls; struct LookupNameResponseMessage *lnr_msg; - - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key_tmp; - struct GNUNET_NAMESTORE_RecordData * rd_tmp; + struct GNUNET_NAMESTORE_RecordData *rd_selected = NULL; + struct GNUNET_NAMESTORE_CryptoContainer *cc; + struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL; + struct GNUNET_TIME_Absolute e; + struct GNUNET_CRYPTO_ShortHashCode zone_key_hash; + GNUNET_HashCode long_hash; + char *rd_tmp; char *name_tmp; - struct GNUNET_CRYPTO_RsaSignature *signature_tmp; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE"); - + size_t rd_ser_len; size_t r_size = 0; - size_t name_len = 0; - if (NULL != name) - name_len = strlen(name) + 1; int copied_elements = 0; - int contains_signature = 0; + int contains_signature = GNUNET_NO; + int authoritative = GNUNET_NO; int c; + if (NULL != name) + name_len = strlen(name) + 1; + /* count records to copy */ if (rd_count != 0) { @@ -233,68 +415,114 @@ handle_lookup_name_it (void *cls, for (c = 0; c < rd_count; c ++) if (rd[c].record_type == lnc->record_type) copied_elements++; /* found matching record */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records with type %u for name `%s' in zone `%s'\n", + copied_elements, lnc->record_type, lnc->name, GNUNET_short_h2s(lnc->zone)); + rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData)); + copied_elements = 0; + for (c = 0; c < rd_count; c ++) + { + if (rd[c].record_type == lnc->record_type) + { + /* found matching record */ + memcpy (&rd_selected[copied_elements], &rd[c], sizeof (struct GNUNET_NAMESTORE_RecordData)); + copied_elements++; + } + } } else + { copied_elements = rd_count; + rd_selected = (struct GNUNET_NAMESTORE_RecordData *) rd; + } + } + else + { + /* No results */ + copied_elements = 0; + rd_selected = NULL; + expire = GNUNET_TIME_UNIT_ZERO_ABS; } - if ((copied_elements == rd_count) && (signature != NULL)) - contains_signature = GNUNET_YES; + rd_ser_len = GNUNET_NAMESTORE_records_get_size(copied_elements, rd_selected); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(copied_elements, rd_selected, rd_ser_len, rd_ser); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records for name `%s' in zone `%s'\n", + copied_elements, lnc->name, GNUNET_short_h2s(lnc->zone)); + + if ((copied_elements == rd_count) && (NULL != signature)) + contains_signature = GNUNET_YES; /* returning all records, so include signature */ + else + contains_signature = GNUNET_NO; /* returning not all records, so do not include signature */ + + + if ((NULL != zone_key) && (copied_elements == rd_count)) + { + GNUNET_CRYPTO_short_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash); + GNUNET_CRYPTO_short_hash_double (&zone_key_hash, &long_hash); + if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash)) + { + cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash); + e = get_block_expiration_time(rd_count, rd); + signature_new = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd, rd_count); + GNUNET_assert (signature_new != NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for name `%s' with %u records in zone `%s'\n",name, copied_elements, GNUNET_short_h2s(&zone_key_hash)); + authoritative = GNUNET_YES; + } + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am not authoritative for name `%s' in zone `%s'\n",name, GNUNET_short_h2s(&zone_key_hash)); + } r_size = sizeof (struct LookupNameResponseMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len + - copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData) + - contains_signature * sizeof (struct GNUNET_CRYPTO_RsaSignature); + rd_ser_len; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE"); lnr_msg = GNUNET_malloc (r_size); - - lnr_msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE); - lnr_msg->header.size = ntohs (r_size); - lnr_msg->op_id = htonl (lnc->id); - lnr_msg->rc_count = htonl (copied_elements); + lnr_msg->gns_header.header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE); + lnr_msg->gns_header.header.size = ntohs (r_size); + lnr_msg->gns_header.r_id = htonl (lnc->request_id); + lnr_msg->rd_count = htons (copied_elements); + lnr_msg->rd_len = htons (rd_ser_len); lnr_msg->name_len = htons (name_len); - lnr_msg->expire = GNUNET_TIME_absolute_hton(expire); - lnr_msg->contains_sig = htons (contains_signature); + lnr_msg->expire = GNUNET_TIME_absolute_hton(get_block_expiration_time(copied_elements, rd_selected)); - - zone_key_tmp = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &lnr_msg[1]; - name_tmp = (char *) &zone_key_tmp[1]; - rd_tmp = (struct GNUNET_NAMESTORE_RecordData *) &name_tmp[name_len]; - signature_tmp = (struct GNUNET_CRYPTO_RsaSignature *) &rd_tmp[copied_elements]; + if (rd_selected != rd) + GNUNET_free (rd_selected); if (zone_key != NULL) - memcpy (zone_key_tmp, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + lnr_msg->public_key = (*zone_key); else + memset(&lnr_msg->public_key, '\0', sizeof (lnr_msg->public_key)); + + if (GNUNET_YES == authoritative) + { /* use new created signature */ + lnr_msg->contains_sig = htons (GNUNET_YES); + GNUNET_assert (signature_new != NULL); + lnr_msg->signature = *signature_new; + GNUNET_free (signature_new); + } + else if (GNUNET_YES == contains_signature) { - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded dummy; - memset (&dummy, '0', sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); - memcpy (zone_key_tmp, &dummy, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + /* use existing signature */ + lnr_msg->contains_sig = htons (GNUNET_YES); + GNUNET_assert (signature != NULL); + lnr_msg->signature = *signature; } - memcpy (name_tmp, name, name_len); - /* copy records */ - copied_elements = 0; - if (rd_count != 0) + else { - if (lnc->record_type != 0) - { - /* special record type needed */ - for (c = 0; c < rd_count; c ++) - if (rd[c].record_type == lnc->record_type) - { - /* found matching record */ - memcpy (&rd_tmp[copied_elements], &rd[c], rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); - copied_elements++; - } - } - else - memcpy (rd_tmp, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + /* use no signature */ + memset (&lnr_msg->signature, '\0', sizeof (lnr_msg->signature)); } - if (GNUNET_YES == contains_signature) - memcpy (signature_tmp, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature)); - GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO); + name_tmp = (char *) &lnr_msg[1]; + rd_tmp = &name_tmp[name_len]; + + memcpy (name_tmp, name, name_len); + memcpy (rd_tmp, rd_ser, rd_ser_len); + GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO); GNUNET_free (lnr_msg); } @@ -305,13 +533,11 @@ static void handle_lookup_name (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_LOOKUP_NAME"); struct LookupNameContext lnc; struct GNUNET_NAMESTORE_Client *nc; - GNUNET_HashCode name_hash; size_t name_len; char * name; - uint32_t id = 0; + uint32_t rid = 0; uint32_t type = 0; - if (ntohs (message->size) < sizeof (struct LookupNameMessage)) { GNUNET_break_op (0); @@ -328,7 +554,7 @@ static void handle_lookup_name (void *cls, } struct LookupNameMessage * ln_msg = (struct LookupNameMessage *) message; - id = ntohl (ln_msg->op_id); + rid = ntohl (ln_msg->gns_header.r_id); name_len = ntohl (ln_msg->name_len); type = ntohl (ln_msg->record_type); @@ -339,17 +565,26 @@ static void handle_lookup_name (void *cls, return; } - name = GNUNET_malloc (name_len); - memcpy (name, &ln_msg[1], name_len); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up record for name `%s'\n", name); - GNUNET_CRYPTO_hash(name, name_len-1, &name_hash); - GNUNET_free (name); + name = (char *) &ln_msg[1]; + if (name[name_len -1] != '\0') + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + if (0 == type) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up all records for name `%s' in zone `%s'\n", name, GNUNET_short_h2s(&ln_msg->zone)); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up records with type %u for name `%s' in zone `%s'\n", type, name, GNUNET_short_h2s(&ln_msg->zone)); /* do the actual lookup */ - lnc.id = id; + lnc.request_id = rid; lnc.nc = nc; lnc.record_type = type; - GSN_database->iterate_records(GSN_database->cls, &ln_msg->zone, &ln_msg->zone, 0, &handle_lookup_name_it, &lnc); + lnc.name = name; + lnc.zone = &ln_msg->zone; + GSN_database->iterate_records(GSN_database->cls, &ln_msg->zone, name, 0, &handle_lookup_name_it, &lnc); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -361,8 +596,6 @@ static void handle_record_put (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_PUT"); struct GNUNET_NAMESTORE_Client *nc; struct GNUNET_TIME_Absolute expire; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; - struct GNUNET_NAMESTORE_RecordData *rd; struct GNUNET_CRYPTO_RsaSignature *signature; struct RecordPutResponseMessage rpr_msg; size_t name_len; @@ -370,7 +603,7 @@ static void handle_record_put (void *cls, size_t msg_size_exp; char * name; char * rd_ser; - uint32_t id = 0; + uint32_t rid = 0; uint32_t rd_ser_len; uint32_t rd_count; int res = GNUNET_SYSERR; @@ -391,12 +624,28 @@ static void handle_record_put (void *cls, } struct RecordPutMessage * rp_msg = (struct RecordPutMessage *) message; - id = ntohl (rp_msg->op_id); + + rid = ntohl (rp_msg->gns_header.r_id); + msg_size = ntohs (rp_msg->gns_header.header.size); name_len = ntohs (rp_msg->name_len); + rd_count = ntohs (rp_msg->rd_count); rd_ser_len = ntohs(rp_msg->rd_len); - msg_size = ntohs (message->size); - msg_size_exp = sizeof (struct RecordPutMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len + rd_ser_len; + if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + if ((rd_count < 1) || (rd_ser_len < 1) || (name_len >=256) || (name_len == 0)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + msg_size_exp = sizeof (struct RecordPutMessage) + name_len + rd_ser_len; if (msg_size != msg_size_exp) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size); @@ -404,25 +653,42 @@ static void handle_record_put (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } + if ((name_len == 0) || (name_len > 256)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + name = (char *) &rp_msg[1]; - if ((name_len == 0) || (name_len > 256)) + if (name[name_len -1] != '\0') { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } - zone_key = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &rp_msg[1]; - name = (char *) &zone_key[1]; expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire); signature = (struct GNUNET_CRYPTO_RsaSignature *) &rp_msg->signature; + rd_ser = &name[name_len]; - rd_count = GNUNET_NAMESTORE_records_deserialize(&rd, rd_ser, rd_ser_len); + struct GNUNET_NAMESTORE_RecordData rd[rd_count]; + res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd); + if (res != GNUNET_OK) + { + GNUNET_break_op (0); + goto send; + } + + struct GNUNET_CRYPTO_ShortHashCode zone_hash; + GNUNET_CRYPTO_short_hash (&rp_msg->public_key, sizeof (rp_msg->public_key), &zone_hash); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting %u record for name `%s' in zone `%s'\n", rd_count, name, GNUNET_short_h2s(&zone_hash)); /* Database operation */ res = GSN_database->put_records(GSN_database->cls, - zone_key, + &rp_msg->public_key, expire, name, rd_count, rd, @@ -432,20 +698,157 @@ static void handle_record_put (void *cls, name, (res == GNUNET_OK) ? "OK" : "FAIL"); /* Send response */ - +send: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_PUT_RESPONSE"); - rpr_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE); - rpr_msg.op_id = rp_msg->op_id; - rpr_msg.header.size = htons (sizeof (struct RecordPutResponseMessage)); - if (GNUNET_OK == res) - rpr_msg.op_result = htons (GNUNET_OK); - else - rpr_msg.op_result = htons (GNUNET_NO); + rpr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE); + rpr_msg.gns_header.header.size = htons (sizeof (struct RecordPutResponseMessage)); + rpr_msg.gns_header.r_id = htonl (rid); + rpr_msg.op_result = htonl (res); GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rpr_msg, GNUNET_NO); GNUNET_SERVER_receive_done (client, GNUNET_OK); } +struct CreateRecordContext +{ + struct GNUNET_NAMESTORE_RecordData *rd; + struct GNUNET_CRYPTO_RsaPrivateKey *pkey; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey; + struct GNUNET_TIME_Absolute expire; + char *name; + int res; +}; + + +static void +handle_create_record_it (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct CreateRecordContext * crc = cls; + struct GNUNET_NAMESTORE_RecordData *rd_new = NULL; + struct GNUNET_CRYPTO_RsaSignature dummy_signature; + struct GNUNET_TIME_Absolute block_expiration; + int res; + int exist = GNUNET_SYSERR; + int update = GNUNET_NO; + int c; + int rd_count_new = 0; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u existing records for `%s'\n", rd_count, crc->name); + for (c = 0; c < rd_count; c++) + { + if ((crc->rd->record_type == GNUNET_NAMESTORE_TYPE_PKEY) && (rd[c].record_type == GNUNET_NAMESTORE_TYPE_PKEY)) + { + /* Update unique PKEY */ + exist = c; + update = GNUNET_YES; + break; + } + else if ((crc->rd->record_type == GNUNET_NAMESTORE_TYPE_PSEU) && (rd[c].record_type == GNUNET_NAMESTORE_TYPE_PSEU)) + { + /* Update unique PSEU */ + exist = c; + update = GNUNET_YES; + break; + } + else if ((crc->rd->record_type == rd[c].record_type) && + (crc->rd->data_size == rd[c].data_size) && + (0 == memcmp (crc->rd->data, rd[c].data, rd[c].data_size))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing records for `%s' to update expiration date!\n", crc->name); + exist = c; + if (crc->rd->expiration.abs_value != rd[c].expiration.abs_value) + update = GNUNET_YES; + break; + } + } + + if (exist == GNUNET_SYSERR) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New record does not exist for name `%s'!\n", crc->name); + + if (exist == GNUNET_SYSERR) + { + rd_new = GNUNET_malloc ((rd_count+1) * sizeof (struct GNUNET_NAMESTORE_RecordData)); + memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + rd_count_new = rd_count + 1; + rd_new[rd_count] = *(crc->rd); + } + else if (update == GNUNET_NO) + { + /* Exact same record already exists */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No update for %s' record required!\n", crc->name); + res = GNUNET_NO; + goto end; + } + else if (update == GNUNET_YES) + { + /* Update record */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating existing records for `%s'!\n", crc->name); + rd_new = GNUNET_malloc ((rd_count) * sizeof (struct GNUNET_NAMESTORE_RecordData)); + memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + rd_count_new = rd_count; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating expiration from %llu to %llu!\n", rd_new[exist].expiration.abs_value, crc->rd->expiration.abs_value); + rd_new[exist] = *(crc->rd); + } + + block_expiration = GNUNET_TIME_absolute_max(crc->expire, expire); + if (block_expiration.abs_value != expire.abs_value) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updated block expiration time\n"); + + memset (&dummy_signature, '\0', sizeof (dummy_signature)); + + /* Database operation */ + GNUNET_assert ((rd_new != NULL) && (rd_count_new > 0)); + res = GSN_database->put_records(GSN_database->cls, + (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) crc->pubkey, + block_expiration, + crc->name, + rd_count_new, rd_new, + &dummy_signature); + GNUNET_break (GNUNET_OK == res); + if (res == GNUNET_OK) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully put record for `%s' in database \n", crc->name); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to put record for `%s' in database \n", crc->name); + res = GNUNET_YES; + +end: + GNUNET_free_non_null (rd_new); + + switch (res) { + case GNUNET_SYSERR: + /* failed to create the record */ + crc->res = GNUNET_SYSERR; + break; + case GNUNET_YES: + /* database operations OK */ + if (GNUNET_YES == update) + { + /* we updated an existing record */ + crc->res = GNUNET_NO; + } + else + { + /* we created a new record */ + crc->res = GNUNET_YES; + } + break; + case GNUNET_NO: + /* identical entry existed, so we did nothing */ + crc->res = GNUNET_NO; + break; + default: + break; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Update result for name `%s' %u\n", crc->name, res); + +} static void handle_record_create (void *cls, struct GNUNET_SERVER_Client * client, @@ -453,13 +856,26 @@ static void handle_record_create (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_CREATE"); struct GNUNET_NAMESTORE_Client *nc; + struct GNUNET_NAMESTORE_CryptoContainer *cc; + struct CreateRecordContext crc; + struct GNUNET_CRYPTO_RsaPrivateKey *pkey; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; struct RecordCreateResponseMessage rcr_msg; + struct GNUNET_CRYPTO_ShortHashCode pubkey_hash; + GNUNET_HashCode long_hash; size_t name_len; size_t msg_size; size_t msg_size_exp; - uint32_t id = 0; + size_t rd_ser_len; + size_t key_len; + uint32_t rid = 0; + char *pkey_tmp; + char *name_tmp; + char *rd_ser; + int rd_count; int res = GNUNET_SYSERR; + crc.res = GNUNET_SYSERR; if (ntohs (message->size) < sizeof (struct RecordCreateMessage)) { @@ -477,10 +893,13 @@ static void handle_record_create (void *cls, } struct RecordCreateMessage * rp_msg = (struct RecordCreateMessage *) message; - id = ntohl (rp_msg->op_id); + rid = ntohl (rp_msg->gns_header.r_id); name_len = ntohs (rp_msg->name_len); msg_size = ntohs (message->size); - msg_size_exp = sizeof (struct RecordCreateMessage) + name_len + sizeof (struct GNUNET_NAMESTORE_RecordData); + rd_count = ntohs (rp_msg->rd_count); + rd_ser_len = ntohs (rp_msg->rd_len); + key_len = ntohs (rp_msg->pkey_len); + msg_size_exp = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len; if (msg_size != msg_size_exp) { @@ -490,7 +909,6 @@ static void handle_record_create (void *cls, return; } - if ((name_len == 0) || (name_len > 256)) { GNUNET_break_op (0); @@ -498,23 +916,195 @@ static void handle_record_create (void *cls, return; } - /* DO WORK HERE */ + pkey_tmp = (char *) &rp_msg[1]; + name_tmp = &pkey_tmp[key_len]; + rd_ser = &name_tmp[name_len]; - /* Send response */ + if (name_tmp[name_len -1] != '\0') + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + struct GNUNET_NAMESTORE_RecordData rd[rd_count]; + res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd); + if ((res != GNUNET_OK) || (rd_count != 1)) + { + GNUNET_break_op (0); + goto send; + } + /* Extracting and converting private key */ + pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len); + GNUNET_assert (pkey != NULL); + GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub); + GNUNET_CRYPTO_short_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash); + GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash); + + if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received new private key for zone `%s'\n",GNUNET_short_h2s(&pubkey_hash)); + + cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer)); + cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len); + cc->pubkey = GNUNET_malloc(sizeof (pub)); + memcpy (cc->pubkey, &pub, sizeof(pub)); + cc->zone = pubkey_hash; + GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + } + + crc.expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire); + crc.res = GNUNET_SYSERR; + crc.pkey = pkey; + crc.pubkey = &pub; + crc.rd = rd; + crc.name = name_tmp; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating record for name `%s' in zone `%s'\n", name_tmp, GNUNET_short_h2s(&pubkey_hash)); + + /* Get existing records for name */ + res = GSN_database->iterate_records(GSN_database->cls, &pubkey_hash, name_tmp, 0, &handle_create_record_it, &crc); + if (res != GNUNET_SYSERR) + res = GNUNET_OK; + GNUNET_CRYPTO_rsa_key_free(pkey); + pkey = NULL; + + /* Send response */ +send: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_CREATE_RESPONSE"); - rcr_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE); - rcr_msg.op_id = rp_msg->op_id; - rcr_msg.header.size = htons (sizeof (struct RecordCreateResponseMessage)); - if (GNUNET_OK == res) - rcr_msg.op_result = htons (GNUNET_OK); + rcr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE); + rcr_msg.gns_header.header.size = htons (sizeof (struct RecordCreateResponseMessage)); + rcr_msg.gns_header.r_id = htonl (rid); + if ((GNUNET_OK == res) && (crc.res == GNUNET_YES)) + rcr_msg.op_result = htonl (GNUNET_YES); + else if ((GNUNET_OK == res) && (crc.res == GNUNET_NO)) + rcr_msg.op_result = htonl (GNUNET_NO); else - rcr_msg.op_result = htons (GNUNET_NO); + rcr_msg.op_result = htonl (GNUNET_SYSERR); GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rcr_msg, GNUNET_NO); GNUNET_SERVER_receive_done (client, GNUNET_OK); } + +struct RemoveRecordContext +{ + struct GNUNET_NAMESTORE_RecordData *rd; + struct GNUNET_CRYPTO_RsaPrivateKey *pkey; + int remove_name; + uint16_t op_res; +}; + +static void +handle_record_remove_it (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct RemoveRecordContext *rrc = cls; + unsigned int c; + int res; + int found; + unsigned int rd_count_new; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s 'currently has %u records\n", name, rd_count); + + if (rd_count == 0) + { + /* Could not find record to remove */ + rrc->op_res = 1; + return; + } + + /* Find record to remove */ + found = GNUNET_SYSERR; + for (c = 0; c < rd_count; c++) + { + /* + if (rd[c].flags != rrc->rd->flags) + continue;*/ + if (rd[c].record_type != rrc->rd->record_type) + continue; + /* + if (rd[c].data_size != rrc->rd->data_size) + continue; + GNUNET_break(0); + if (0 != memcmp (rd[c].data, rrc->rd->data, rrc->rd->data_size)) + continue; + GNUNET_break(0); */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found record to remove!\n", rd_count); + found = c; + break; + } + if (GNUNET_SYSERR == found) + { + /* Could not find record to remove */ + rrc->op_res = 2; + return; + } + + if (rd_count-1 == 0) + { + struct GNUNET_CRYPTO_ShortHashCode pubkey_hash; + GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash); + res = GSN_database->remove_records (GSN_database->cls, + &pubkey_hash, + name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No records left for name `%s', removing name\n", + name, res); + if (GNUNET_OK != res) + { + /* Could put records into database */ + rrc->op_res = 4; + return; + } + rrc->op_res = 0; + return; + } + + rd_count_new = rd_count -1; + struct GNUNET_NAMESTORE_RecordData rd_new[rd_count_new]; + + unsigned int c2 = 0; + for (c = 0; c < rd_count; c++) + { + if (c != found) + { + GNUNET_assert (c2 < rd_count_new); + rd_new[c2] = rd[c]; + c2++; + } + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s' now has %u records\n", name, rd_count_new); + + /* Create dummy signature */ + struct GNUNET_CRYPTO_RsaSignature dummy_signature; + memset (&dummy_signature, '\0', sizeof (dummy_signature)); + + + /* Put records */ + res = GSN_database->put_records(GSN_database->cls, + zone_key, + expire, + name, + rd_count_new, rd_new, + &dummy_signature); + if (GNUNET_OK != res) + { + /* Could put records into database */ + rrc->op_res = 4; + return; + } + + rrc->op_res = 0; +} + static void handle_record_remove (void *cls, struct GNUNET_SERVER_Client * client, const struct GNUNET_MessageHeader * message) @@ -522,10 +1112,21 @@ static void handle_record_remove (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_REMOVE"); struct GNUNET_NAMESTORE_Client *nc; struct RecordRemoveResponseMessage rrr_msg; - size_t name_len; - size_t msg_size; - size_t msg_size_exp; - uint32_t id = 0; + struct GNUNET_CRYPTO_RsaPrivateKey *pkey; + struct GNUNET_NAMESTORE_CryptoContainer *cc = NULL; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; + struct GNUNET_CRYPTO_ShortHashCode pubkey_hash; + GNUNET_HashCode long_hash; + char * pkey_tmp = NULL; + char * name_tmp = NULL; + char * rd_ser = NULL; + size_t key_len = 0; + size_t name_len = 0; + size_t rd_ser_len = 0; + size_t msg_size = 0; + size_t msg_size_exp = 0; + uint32_t rd_count; + uint32_t rid = 0; int res = GNUNET_SYSERR; @@ -544,12 +1145,29 @@ static void handle_record_remove (void *cls, return; } - struct RecordRemoveMessage * rp_msg = (struct RecordRemoveMessage *) message; - id = ntohl (rp_msg->op_id); - name_len = ntohs (rp_msg->name_len); + struct RecordRemoveMessage * rr_msg = (struct RecordRemoveMessage *) message; + rid = ntohl (rr_msg->gns_header.r_id); + name_len = ntohs (rr_msg->name_len); + rd_ser_len = ntohs (rr_msg->rd_len); + rd_count = ntohs (rr_msg->rd_count); + key_len = ntohs (rr_msg->pkey_len); msg_size = ntohs (message->size); - msg_size_exp = sizeof (struct RecordRemoveMessage) + name_len + sizeof (struct GNUNET_NAMESTORE_RecordData); + if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + if ((name_len >=256) || (name_len == 0)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + msg_size_exp = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len; if (msg_size != msg_size_exp) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size); @@ -558,6 +1176,10 @@ static void handle_record_remove (void *cls, return; } + pkey_tmp = (char *) &rr_msg[1]; + name_tmp = &pkey_tmp[key_len]; + rd_ser = &name_tmp[name_len]; + if ((name_len == 0) || (name_len > 256)) { @@ -566,41 +1188,268 @@ static void handle_record_remove (void *cls, return; } - /* DO WORK HERE */ + if (name_tmp[name_len -1] != '\0') + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } - /* Send response */ + /* Extracting and converting private key */ + pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len); + GNUNET_assert (pkey != NULL); + GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub); + GNUNET_CRYPTO_short_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash); + GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_REMOVE_RESPONSE"); - rrr_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE); - rrr_msg.op_id = rp_msg->op_id; - rrr_msg.header.size = htons (sizeof (struct RecordRemoveResponseMessage)); - if (GNUNET_OK == res) - rrr_msg.op_result = htons (GNUNET_OK); + if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received new private key for zone `%s'\n",GNUNET_short_h2s(&pubkey_hash)); + cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer)); + cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len); + cc->pubkey = GNUNET_malloc(sizeof (pub)); + memcpy (cc->pubkey, &pub, sizeof(pub)); + cc->zone = pubkey_hash; + + GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + } + + + struct GNUNET_NAMESTORE_RecordData rd[rd_count]; + res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd); + if ((res != GNUNET_OK) || (rd_count > 1)) + { + GNUNET_break_op (0); + goto send; + } + + if (0 == rd_count) + { + /* remove the whole name and all records */ + /* Database operation */ + res = GSN_database->remove_records (GSN_database->cls, + &pubkey_hash, + name_tmp); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing name `%s': %s\n", + name_tmp, (GNUNET_OK == res) ? "OK" : "FAIL"); + + if (GNUNET_OK != res) + /* Could not remove entry from database */ + res = 4; + else + res = 0; + } else - rrr_msg.op_result = htons (GNUNET_NO); + { + /* remove a single record */ + struct RemoveRecordContext rrc; + rrc.rd = rd; + rrc.pkey = pkey; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s' in zone `%s'\n", name_tmp, GNUNET_short_h2s(&pubkey_hash)); + + /* Database operation */ + res = GSN_database->iterate_records (GSN_database->cls, + &pubkey_hash, + name_tmp, + 0, + handle_record_remove_it, &rrc); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s': %s\n", + name_tmp, (rrc.op_res == 0) ? "OK" : "FAIL"); + res = rrc.op_res; + } + /* Send response */ +send: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_REMOVE_RESPONSE"); + rrr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE); + rrr_msg.gns_header.header.size = htons (sizeof (struct RecordRemoveResponseMessage)); + rrr_msg.gns_header.r_id = htonl (rid); + rrr_msg.op_result = htonl (res); GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rrr_msg, GNUNET_NO); + GNUNET_CRYPTO_rsa_key_free (pkey); + + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + +struct ZoneToNameCtx +{ + struct GNUNET_NAMESTORE_Client *nc; + uint32_t rid; +}; + +static void +handle_zone_to_name_it (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct ZoneToNameCtx * ztn_ctx = cls; + struct ZoneToNameResponseMessage *ztnr_msg; + int16_t res = GNUNET_SYSERR; + uint16_t name_len = 0; + uint16_t rd_ser_len = 0 ; + int32_t contains_sig = 0; + size_t msg_size = 0; + + char *rd_ser = NULL; + char *name_tmp; + char *rd_tmp; + char *sig_tmp; + + if ((zone_key != NULL) && (name != NULL)) + { + /* found result */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found results: name is `%s', has %u records\n", name, rd_count); + res = GNUNET_YES; + name_len = strlen (name) +1; + } + else + { + /* no result found */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found no results\n"); + res = GNUNET_NO; + name_len = 0; + } + + if (rd_count > 0) + { + rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); + rd_ser = GNUNET_malloc (rd_ser_len); + GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser); + } + else + rd_ser_len = 0; + + if (signature != NULL) + contains_sig = GNUNET_YES; + else + contains_sig = GNUNET_NO; + + + + msg_size = sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len + contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature); + ztnr_msg = GNUNET_malloc (msg_size); + + name_tmp = (char *) &ztnr_msg[1]; + rd_tmp = &name_tmp[name_len]; + sig_tmp = &rd_tmp[rd_ser_len]; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_TO_NAME_RESPONSE"); + ztnr_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE); + ztnr_msg->gns_header.header.size = htons (msg_size); + ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid); + ztnr_msg->res = htons (res); + ztnr_msg->rd_len = htons (rd_ser_len); + ztnr_msg->rd_count = htons (rd_count); + ztnr_msg->name_len = htons (name_len); + ztnr_msg->expire = GNUNET_TIME_absolute_hton(expire); + if (zone_key != NULL) + ztnr_msg->zone_key = *zone_key; + else + memset (&ztnr_msg->zone_key, '\0', sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + + if ((name_len > 0) && (name != NULL)) + memcpy (name_tmp, name, name_len); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name is `%s', has %u records, rd ser len %u msg_size %u\n", name, rd_count, rd_ser_len, msg_size); + if ((rd_ser_len > 0) && (rd_ser != NULL)) + memcpy (rd_tmp, rd_ser, rd_ser_len); + if ((GNUNET_YES == contains_sig) && (signature != NULL)) + memcpy (sig_tmp, signature, contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature)); + + GNUNET_SERVER_notification_context_unicast (snc, ztn_ctx->nc->client, (const struct GNUNET_MessageHeader *) ztnr_msg, GNUNET_NO); + GNUNET_free (ztnr_msg); + GNUNET_free_non_null (rd_ser); +} + + +static void handle_zone_to_name (void *cls, + struct GNUNET_SERVER_Client * client, + const struct GNUNET_MessageHeader * message) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_TO_NAME"); + struct GNUNET_NAMESTORE_Client *nc; + struct ZoneToNameCtx ztn_ctx; + size_t msg_size = 0; + uint32_t rid = 0; + + if (ntohs (message->size) != sizeof (struct ZoneToNameMessage)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + nc = client_lookup(client); + if (nc == NULL) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + struct ZoneToNameMessage *ztn_msg = (struct ZoneToNameMessage *) message; + + if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + rid = ntohl (ztn_msg->gns_header.r_id); + + ztn_ctx.rid = rid; + ztn_ctx.nc = nc; + + struct GNUNET_CRYPTO_ShortHashAsciiEncoded z_tmp; + GNUNET_CRYPTO_short_hash_to_enc(&ztn_msg->zone, &z_tmp); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up name for zone `%s' in zone `%s'\n", + (char *) &z_tmp, + GNUNET_short_h2s (&ztn_msg->value_zone)); + + GSN_database->zone_to_name (GSN_database->cls, &ztn_msg->zone, &ztn_msg->value_zone, &handle_zone_to_name_it, &ztn_ctx); + GNUNET_SERVER_receive_done (client, GNUNET_OK); } + +/** + * Copy record, data has to be free separetely + */ +void +copy_record (const struct GNUNET_NAMESTORE_RecordData *src, struct GNUNET_NAMESTORE_RecordData *dest) +{ + + memcpy (dest, src, sizeof (struct GNUNET_NAMESTORE_RecordData)); + dest->data = GNUNET_malloc (src->data_size); + memcpy ((void *) dest->data, src->data, src->data_size); +} + struct ZoneIterationProcResult { - int have_zone_key; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key; + struct GNUNET_NAMESTORE_ZoneIteration *zi; - int have_signature; + int res_iteration_finished; + int records_included; + int has_signature; + + char *name; + struct GNUNET_CRYPTO_ShortHashCode zone_hash; + struct GNUNET_NAMESTORE_RecordData *rd; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key; struct GNUNET_CRYPTO_RsaSignature signature; struct GNUNET_TIME_Absolute expire; - - int have_name; - char name[256]; - - unsigned int rd_count; - char *rd_ser; }; -void zone_iteration_proc (void *cls, +void zone_iteraterate_proc (void *cls, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, struct GNUNET_TIME_Absolute expire, const char *name, @@ -608,40 +1457,230 @@ void zone_iteration_proc (void *cls, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature) { - struct ZoneIterationProcResult *zipr = cls; - size_t len; - if (zone_key != NULL) + struct ZoneIterationProcResult *proc = cls; + struct GNUNET_NAMESTORE_RecordData *rd_filtered; + struct GNUNET_CRYPTO_RsaSignature * new_signature; + struct GNUNET_NAMESTORE_CryptoContainer *cc; + struct GNUNET_CRYPTO_ShortHashCode hash; + GNUNET_HashCode long_hash; + struct GNUNET_TIME_Absolute e; + unsigned int rd_count_filtered = 0; + int include; + int c; + + proc->res_iteration_finished = GNUNET_NO; + proc->records_included = 0; + + if ((zone_key == NULL) && (name == NULL)) { - zipr->zone_key = *zone_key; - zipr->have_zone_key = GNUNET_YES; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n"); + proc->res_iteration_finished = GNUNET_YES; + proc->rd = NULL; + proc->name = NULL; } - else - zipr->have_zone_key = GNUNET_NO; + else if ((zone_key != NULL) && (name != NULL)) /* just a safety check */ + { + rd_filtered = GNUNET_malloc (rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received result for zone iteration: `%s'\n", name); + for (c = 0; c < rd_count; c++) + { + include = GNUNET_YES; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must have 0x%x \n", + c, rd[c].flags, proc->zi->must_have_flags); + /* Checking must have flags */ + if ((rd[c].flags & proc->zi->must_have_flags) == proc->zi->must_have_flags) + { + /* Include */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include \n", c); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include \n", c); + include = GNUNET_NO; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must not have 0x%x\n", + c, rd[c].flags, proc->zi->must_not_have_flags); + if ((rd[c].flags & proc->zi->must_not_have_flags) != 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include \n", c); + include = GNUNET_NO; + } + else + { + /* Include */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include \n", c); + } + if (GNUNET_YES == include) + { + copy_record (&rd[c], &rd_filtered[rd_count_filtered]); + rd_count_filtered++; + } + + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Included %i of %i records \n", rd_count_filtered, rd_count); + + proc->records_included = rd_count_filtered; + if (0 == rd_count_filtered) + { + GNUNET_free (rd_filtered); + rd_filtered = NULL; + } + proc->rd = rd_filtered; + proc->name = GNUNET_strdup(name); + memcpy (&proc->zone_key, zone_key, sizeof (proc->zone_key)); - zipr->expire = expire; + /* Signature */ + proc->has_signature = GNUNET_NO; + GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &hash); + GNUNET_CRYPTO_short_hash_double(&hash, &long_hash); + proc->zone_hash = hash; - if (name != NULL) + if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash)) + { + cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash); + e = get_block_expiration_time(rd_count_filtered, rd_filtered); + proc->expire = e; + new_signature = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd_filtered, rd_count_filtered); + GNUNET_assert (signature != NULL); + proc->signature = (*new_signature); + GNUNET_free (new_signature); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n", + name, GNUNET_short_h2s(&hash), rd_count_filtered, e.abs_value); + proc->has_signature = GNUNET_YES; + } + else if (rd_count_filtered == rd_count) + { + proc->expire = expire; + if (NULL != signature) + { + proc->signature = (*signature); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using provided signature for `%s' in zone `%s' with %u records and expiration %llu\n", + name, GNUNET_short_h2s(&hash), rd_count_filtered, expire.abs_value); + proc->has_signature = GNUNET_YES; + } + else + { + memset (&proc->signature, '\0', sizeof (proc->signature)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No signature provided for `%s'\n", name); + } + } + } + else { - memcpy (zipr->name, name, strlen(name) + 1); - zipr->have_name = GNUNET_YES; + GNUNET_break (0); + return; } + +} + +void find_next_zone_iteration_result (struct ZoneIterationProcResult *proc) +{ + + struct GNUNET_CRYPTO_ShortHashCode *zone; + + if (GNUNET_YES == proc->zi->has_zone) + zone = &proc->zi->zone; else - zipr->have_name = GNUNET_NO; + zone = NULL; + + do + { + GSN_database->iterate_records (GSN_database->cls, zone , NULL, proc->zi->offset, &zone_iteraterate_proc, proc); + proc->zi->offset++; + } + while ((proc->records_included == 0) && (GNUNET_NO == proc->res_iteration_finished)); +} - zipr->rd_count = rd_count; - if (signature != NULL) +void send_zone_iteration_result (struct ZoneIterationProcResult *proc) +{ + struct GNUNET_NAMESTORE_ZoneIteration *zi = proc->zi; + + if (GNUNET_YES == proc->res_iteration_finished) { - zipr->signature = *signature; - zipr->have_signature = GNUNET_YES; + struct ZoneIterationResponseMessage zir_msg; + if (zi->has_zone == GNUNET_YES) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for zone `%s'\n", GNUNET_short_h2s(&zi->zone)); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for all zones\n"); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending empty `%s' message\n", "ZONE_ITERATION_RESPONSE"); + zir_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE); + zir_msg.gns_header.header.size = htons (sizeof (struct ZoneIterationResponseMessage)); + zir_msg.gns_header.r_id = htonl(zi->request_id); + zir_msg.expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_UNIT_ZERO_ABS); + zir_msg.name_len = htons (0); + zir_msg.reserved = htons (0); + zir_msg.rd_count = htons (0); + zir_msg.rd_len = htons (0); + memset (&zir_msg.public_key, '\0', sizeof (zir_msg.public_key)); + memset (&zir_msg.signature, '\0', sizeof (zir_msg.signature)); + GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing zone iterator\n"); + GNUNET_CONTAINER_DLL_remove (zi->client->op_head, zi->client->op_tail, zi); + GNUNET_free (zi); + return; } else - zipr->have_signature = GNUNET_NO; + { + GNUNET_assert (proc->records_included > 0); + + struct ZoneIterationResponseMessage *zir_msg; + if (zi->has_zone == GNUNET_YES) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over zone `%s'\n", + proc->name, GNUNET_short_h2s(&zi->zone)); + if (zi->has_zone == GNUNET_NO) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over all zones\n", + proc->name); + + size_t name_len; + size_t rd_ser_len; + size_t msg_size; + char *name_tmp; + char *rd_tmp; + name_len = strlen (proc->name) +1; + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(proc->records_included, proc->rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(proc->records_included, proc->rd, rd_ser_len, rd_ser); + msg_size = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_ser_len; + zir_msg = GNUNET_malloc(msg_size); + + name_tmp = (char *) &zir_msg[1]; + rd_tmp = &name_tmp[name_len]; + + zir_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE); + zir_msg->gns_header.header.size = htons (msg_size); + zir_msg->gns_header.r_id = htonl(zi->request_id); + zir_msg->expire = GNUNET_TIME_absolute_hton(proc->expire); + zir_msg->reserved = htons (0); + zir_msg->name_len = htons (name_len); + zir_msg->rd_count = htons (proc->records_included); + zir_msg->rd_len = htons (rd_ser_len); + zir_msg->signature = proc->signature; + zir_msg->public_key = proc->zone_key; + memcpy (name_tmp, proc->name, name_len); + memcpy (rd_tmp, rd_ser, rd_ser_len); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with size %u\n", "ZONE_ITERATION_RESPONSE", msg_size); + GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) zir_msg, GNUNET_NO); + GNUNET_free (zir_msg); + } +} - if ((rd_count > 0) && (rd != NULL)) +void clean_up_zone_iteration_result (struct ZoneIterationProcResult *proc) +{ + int c; + GNUNET_free_non_null (proc->name); + for (c = 0; c < proc->records_included; c++) { - len = GNUNET_NAMESTORE_records_serialize (&zipr->rd_ser, rd_count, rd); + GNUNET_free ((void *) proc->rd[c].data); } + GNUNET_free_non_null (proc->rd); + proc->name = NULL; + proc->rd = NULL; } static void handle_iteration_start (void *cls, @@ -653,9 +1692,6 @@ static void handle_iteration_start (void *cls, struct ZoneIterationStartMessage * zis_msg = (struct ZoneIterationStartMessage *) message; struct GNUNET_NAMESTORE_Client *nc; struct GNUNET_NAMESTORE_ZoneIteration *zi; - struct ZoneIterationResponseMessage zir_msg; - struct ZoneIterationProcResult zipr; - int res; nc = client_lookup(client); if (nc == NULL) @@ -666,22 +1702,43 @@ static void handle_iteration_start (void *cls, } zi = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIteration)); - zi->op_id = ntohl (zis_msg->op_id); + zi->request_id = ntohl (zis_msg->gns_header.r_id); zi->offset = 0; zi->client = nc; - zi->zone = zis_msg->zone; - - GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi); + zi->must_have_flags = ntohs (zis_msg->must_have_flags); + zi->must_not_have_flags = ntohs (zis_msg->must_not_have_flags); - res = GSN_database->iterate_records (GSN_database->cls, &zis_msg->zone, NULL, zi->offset , &zone_iteration_proc, &zipr); + struct GNUNET_CRYPTO_ShortHashCode dummy; + memset (&dummy, '\0', sizeof (dummy)); + if (0 == memcmp (&dummy, &zis_msg->zone, sizeof (dummy))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over all zones\n"); + zi->zone = zis_msg->zone; + zi->has_zone = GNUNET_NO; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over zone `%s'\n", GNUNET_short_h2s (&zis_msg->zone)); + zi->zone = zis_msg->zone; + zi->has_zone = GNUNET_YES; + } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_ITERATION_RESPONSE"); - zir_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE); - zir_msg.op_id = htonl(zi->op_id); - zir_msg.header.size = htons (sizeof (struct ZoneIterationResponseMessage)); + GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi); - GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO); + struct ZoneIterationProcResult proc; + proc.zi = zi; + find_next_zone_iteration_result (&proc); + if (GNUNET_YES == proc.res_iteration_finished) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n"); + } + else if (proc.records_included != 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", proc.records_included); + } + send_zone_iteration_result (&proc); + clean_up_zone_iteration_result (&proc); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -695,7 +1752,7 @@ static void handle_iteration_stop (void *cls, struct GNUNET_NAMESTORE_Client *nc; struct GNUNET_NAMESTORE_ZoneIteration *zi; struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message; - uint32_t id; + uint32_t rid; nc = client_lookup(client); if (nc == NULL) @@ -705,10 +1762,10 @@ static void handle_iteration_stop (void *cls, return; } - id = ntohl (zis_msg->op_id); + rid = ntohl (zis_msg->gns_header.r_id); for (zi = nc->op_head; zi != NULL; zi = zi->next) { - if (zi->op_id == id) + if (zi->request_id == rid) break; } if (zi == NULL) @@ -719,7 +1776,10 @@ static void handle_iteration_stop (void *cls, } GNUNET_CONTAINER_DLL_remove(nc->op_head, nc->op_tail, zi); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration for zone `%s'\n", GNUNET_h2s (&zi->zone)); + if (GNUNET_YES == zi->has_zone) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration for zone `%s'\n", GNUNET_short_h2s (&zi->zone)); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration all zones\n"); GNUNET_free (zi); GNUNET_SERVER_receive_done (client, GNUNET_OK); @@ -734,8 +1794,7 @@ static void handle_iteration_next (void *cls, struct GNUNET_NAMESTORE_Client *nc; struct GNUNET_NAMESTORE_ZoneIteration *zi; struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message; - uint32_t id; - int res; + uint32_t rid; nc = client_lookup(client); if (nc == NULL) @@ -745,10 +1804,10 @@ static void handle_iteration_next (void *cls, return; } - id = ntohl (zis_msg->op_id); + rid = ntohl (zis_msg->gns_header.r_id); for (zi = nc->op_head; zi != NULL; zi = zi->next) { - if (zi->op_id == id) + if (zi->request_id == rid) break; } if (zi == NULL) @@ -758,10 +1817,49 @@ static void handle_iteration_next (void *cls, return; } - zi->offset++; - res = GSN_database->iterate_records (GSN_database->cls, &zi->zone, NULL, zi->offset , &zone_iteration_proc, zi); + struct ZoneIterationProcResult proc; + proc.zi = zi; + + find_next_zone_iteration_result (&proc); + if (GNUNET_YES == proc.res_iteration_finished) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n"); + } + else if (proc.records_included != 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", proc.records_included); + } + send_zone_iteration_result (&proc); + clean_up_zone_iteration_result (&proc); + + GNUNET_SERVER_receive_done (client, GNUNET_OK); } +int zonekey_file_it (void *cls, const char *filename) +{ + GNUNET_HashCode long_hash; + int *counter = cls; + if ((filename != NULL) && (NULL != strstr(filename, ".zkey"))) + { + struct GNUNET_CRYPTO_RsaPrivateKey * privkey; + struct GNUNET_NAMESTORE_CryptoContainer *c; + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(filename); + if (privkey == NULL) + return GNUNET_OK; + + c = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer)); + c->pubkey = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + c->privkey = privkey; + GNUNET_CRYPTO_rsa_key_get_public(privkey, c->pubkey); + GNUNET_CRYPTO_short_hash(c->pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &c->zone); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found zonefile for zone `%s'\n", GNUNET_short_h2s (&c->zone)); + GNUNET_CRYPTO_short_hash_double (&c->zone, &long_hash); + GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, c, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + (*counter) ++; + } + return GNUNET_OK; +} /** @@ -776,7 +1874,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg) { char * database; - + int counter = 0; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n"); static const struct GNUNET_SERVER_MessageHandler handlers[] = { @@ -790,17 +1888,45 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE, 0}, {&handle_record_remove, NULL, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE, 0}, + {&handle_zone_to_name, NULL, + GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, 0}, {&handle_iteration_start, NULL, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START, sizeof (struct ZoneIterationStartMessage)}, - {&handle_iteration_stop, NULL, - GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, sizeof (struct ZoneIterationStopMessage)}, {&handle_iteration_next, NULL, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT, 0}, + {&handle_iteration_stop, NULL, + GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, 0}, {NULL, NULL, 0, 0} }; GSN_cfg = cfg; + /* Load private keys from disk */ + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore", "zonefile_directory", + &zonefile_directory)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("No directory to load zonefiles specified in configuration\n")); + GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); + return; + } + + if (GNUNET_NO == GNUNET_DISK_file_test (zonefile_directory)) + { + if (GNUNET_SYSERR == GNUNET_DISK_directory_create (zonefile_directory)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Creating directory `%s' for zone files failed!\n"), zonefile_directory); + GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created directory `%s' for zone files\n", zonefile_directory); + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scanning directory `%s' for zone files\n", zonefile_directory); + zonekeys = GNUNET_CONTAINER_multihashmap_create (10); + GNUNET_DISK_directory_scan (zonefile_directory, zonekey_file_it, &counter); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u zone files\n", counter); + /* Loading database plugin */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "namestore", "database", @@ -809,10 +1935,14 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database); GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg); + GNUNET_free (database); if (GSN_database == NULL) + { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n", db_lib_name); - GNUNET_free (database); + GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); + return; + } /* Configuring server handles */ GNUNET_SERVER_add_handlers (server, handlers); @@ -843,3 +1973,4 @@ main (int argc, char *const *argv) } /* end of gnunet-service-namestore.c */ + diff --git a/src/namestore/hostkey b/src/namestore/hostkey deleted file mode 100644 index eac1d1e..0000000 Binary files a/src/namestore/hostkey and /dev/null differ diff --git a/src/namestore/namestore.conf.in b/src/namestore/namestore.conf.in index c9b9984..d93aea6 100644 --- a/src/namestore/namestore.conf.in +++ b/src/namestore/namestore.conf.in @@ -11,6 +11,7 @@ BINARY = gnunet-service-namestore ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; DATABASE = sqlite +ZONEFILE_DIRECTORY = $SERVICEHOME/namestore/zonefiles [namestore-sqlite] FILENAME = $SERVICEHOME/namestore/sqlite.db diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index 22fc860..5a42c14 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h @@ -29,6 +29,7 @@ /* * Collect message types here, move to protocols later */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_START 430 #define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME 431 #define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE 432 #define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT 433 @@ -37,23 +38,64 @@ #define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE 436 #define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE 437 #define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE 438 +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME 439 +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE 440 -#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START 439 -#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE 440 -#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT 441 -#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP 442 +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START 445 +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE 446 +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT 447 +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP 448 -size_t -GNUNET_NAMESTORE_records_serialize (char ** dest, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd); +/** + * Convert a short hash to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param hc the short hash code + * @return string form; will be overwritten by next call to GNUNET_h2s. + */ +const char * +GNUNET_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc); + + +/** + * Sign name and records + * + * @param key the private key + * @param expire block expiration + * @param name the name + * @param rd record data + * @param rd_count number of records + * + * @return the signature + */ +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key, + struct GNUNET_TIME_Absolute expire, + const char *name, + const struct GNUNET_NAMESTORE_RecordData *rd, + unsigned int rd_count); + + +/** + * Compares if two records are equal + * + * @param a Record a + * @param b Record b + * + * @return GNUNET_YES or GNUNET_NO + */ int -GNUNET_NAMESTORE_records_deserialize ( struct GNUNET_NAMESTORE_RecordData **dest, char *src, size_t len); +GNUNET_NAMESTORE_records_cmp (const struct GNUNET_NAMESTORE_RecordData *a, + const struct GNUNET_NAMESTORE_RecordData *b); + +GNUNET_NETWORK_STRUCT_BEGIN /** * A GNS record serialized for network transmission. - * layout is [struct GNUNET_NAMESTORE_NetworkRecord][char[data_size] data] + * + * Layout is [struct GNUNET_NAMESTORE_NetworkRecord][char[data_size] data] */ struct GNUNET_NAMESTORE_NetworkRecord { @@ -80,9 +122,8 @@ struct GNUNET_NAMESTORE_NetworkRecord -GNUNET_NETWORK_STRUCT_BEGIN /** - * Connect to namestore service + * Connect to namestore service. FIXME: UNNECESSARY. */ struct StartMessage { @@ -93,329 +134,451 @@ struct StartMessage struct GNUNET_MessageHeader header; }; -GNUNET_NETWORK_STRUCT_END -GNUNET_NETWORK_STRUCT_BEGIN /** * Generic namestore message with op id */ -struct GenericMessage +struct GNUNET_NAMESTORE_Header { /** - * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* + * header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* + * header.size will be message size */ struct GNUNET_MessageHeader header; /** - * Operation ID in NBO + * Request ID in NBO */ - uint32_t op_id; + uint32_t r_id; }; -GNUNET_NETWORK_STRUCT_END /** - * Connect to namestore service + * Lookup a name in the namestore */ -GNUNET_NETWORK_STRUCT_BEGIN struct LookupNameMessage { + struct GNUNET_NAMESTORE_Header gns_header; + /** - * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME + * The zone */ - struct GNUNET_MessageHeader header; + struct GNUNET_CRYPTO_ShortHashCode zone; /** - * Operation ID in NBO + * Requested record type */ - uint32_t op_id; - - /* The zone */ - GNUNET_HashCode zone; - - /* Requested record type */ uint32_t record_type; - /* Requested record type */ + /** + * Length of the name + */ uint32_t name_len; + + /* 0-terminated name here */ }; -GNUNET_NETWORK_STRUCT_END /** * Lookup response - * Memory layout: - * [struct LookupNameResponseMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData][struct GNUNET_CRYPTO_RsaSignature] */ -GNUNET_NETWORK_STRUCT_BEGIN struct LookupNameResponseMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE */ - struct GNUNET_MessageHeader header; + struct GNUNET_NAMESTORE_Header gns_header; /** - * Operation ID in NBO + * Expiration time */ - uint32_t op_id; - struct GNUNET_TIME_AbsoluteNBO expire; + + /** + * Name length + */ uint16_t name_len; - uint16_t contains_sig; + /** + * Bytes of serialized record data + */ + uint16_t rd_len; + + /** + * Number of records contained + */ + uint16_t rd_count; + + /** + * Is the signature valid + * GNUNET_YES or GNUNET_NO + */ + int16_t contains_sig; - /* Requested record type */ - uint32_t rc_count; + /** + * All zeros if 'contains_sig' is GNUNET_NO. + */ + struct GNUNET_CRYPTO_RsaSignature signature; + + /** + * The public key for the name + */ + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; + + /* 0-terminated name and serialized record data */ + /* rd_len bytes serialized record data */ }; -GNUNET_NETWORK_STRUCT_END /** * Put a record to the namestore - * Memory layout: - * [struct RecordPutMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData] */ -GNUNET_NETWORK_STRUCT_BEGIN struct RecordPutMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_RECORD_PUT */ - struct GNUNET_MessageHeader header; + struct GNUNET_NAMESTORE_Header gns_header; /** - * Operation ID in NBO + * Expiration time */ - uint32_t op_id; - - /* Contenct starts here */ + struct GNUNET_TIME_AbsoluteNBO expire; - /* name length */ + /** + * Name length + */ uint16_t name_len; - /* Length of serialized rd data */ + /** + * Length of serialized record data + */ uint16_t rd_len; - struct GNUNET_TIME_AbsoluteNBO expire; + /** + * Number of records contained + */ + uint16_t rd_count; + + /** + * always zero (for alignment) + */ + uint16_t reserved; + /** + * The signature + */ struct GNUNET_CRYPTO_RsaSignature signature; + + /** + * The public key + */ + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; + + /* name (0-terminated) followed by "rd_count" serialized records */ + }; -GNUNET_NETWORK_STRUCT_END + /** * Put a record to the namestore response */ -GNUNET_NETWORK_STRUCT_BEGIN struct RecordPutResponseMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE */ - struct GNUNET_MessageHeader header; - - /** - * Operation ID in NBO - */ - uint32_t op_id; - - /* Contenct starts here */ + struct GNUNET_NAMESTORE_Header gns_header; /** - * name length: GNUNET_NO (0) on error, GNUNET_OK (1) on success + * result: + * GNUNET_SYSERR on failure + * GNUNET_OK on success */ - uint16_t op_result; + int32_t op_result; }; -GNUNET_NETWORK_STRUCT_END /** - * Put a record to the namestore + * Create a record and put it to the namestore * Memory layout: - * [struct RecordPutMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData] */ -GNUNET_NETWORK_STRUCT_BEGIN struct RecordCreateMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE */ - struct GNUNET_MessageHeader header; + struct GNUNET_NAMESTORE_Header gns_header; + + struct GNUNET_TIME_AbsoluteNBO expire; /** - * Operation ID in NBO + * Name length */ - uint32_t op_id; + uint16_t name_len; - /* Contenct starts here */ + /** + * Length of serialized record data + */ + uint16_t rd_len; - /* name length */ - uint16_t name_len; + /** + * Record count + */ + uint16_t rd_count; - struct GNUNET_CRYPTO_RsaSignature signature; + /** + * private key length + */ + uint16_t pkey_len; + + /* followed by: + * GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded private key with length pkey_len + * name with length name_len + * serialized record data with length rd_len + * */ }; -GNUNET_NETWORK_STRUCT_END /** * Create a record to the namestore response - * Memory layout: */ -GNUNET_NETWORK_STRUCT_BEGIN struct RecordCreateResponseMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE */ - struct GNUNET_MessageHeader header; - - /** - * Operation ID in NBO - */ - uint32_t op_id; - - /* Contenct starts here */ + struct GNUNET_NAMESTORE_Header gns_header; /** - * name length: GNUNET_NO (0) on error, GNUNET_OK (1) on success + * name length: GNUNET_NO already exists, GNUNET_YES on success, GNUNET_SYSERR error */ - uint16_t op_result; + int32_t op_result; }; -GNUNET_NETWORK_STRUCT_END + /** * Remove a record from the namestore * Memory layout: - * [struct RecordRemoveMessage][char *name][struct GNUNET_NAMESTORE_RecordData] */ -GNUNET_NETWORK_STRUCT_BEGIN struct RecordRemoveMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE */ - struct GNUNET_MessageHeader header; + struct GNUNET_NAMESTORE_Header gns_header; /** - * Operation ID in NBO + * Name length */ - uint32_t op_id; + uint16_t name_len; - /* Contenct starts here */ + /** + * Length of serialized rd data + */ + uint16_t rd_len; - /* name length */ - uint16_t name_len; + /** + * Number of records contained + */ + uint16_t rd_count; - struct GNUNET_CRYPTO_RsaSignature signature; + /** + * Length of private key + */ + uint16_t pkey_len; + + /* followed by: + * GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded private key with length pkey_len + * name with length name_len + * serialized record data with length rd_len + * */ }; -GNUNET_NETWORK_STRUCT_END /** * Remove a record from the namestore response */ -GNUNET_NETWORK_STRUCT_BEGIN struct RecordRemoveResponseMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE */ - struct GNUNET_MessageHeader header; + struct GNUNET_NAMESTORE_Header gns_header; /** - * Operation ID in NBO + * result: + * 0 : successful + * 1 : no records for entry + * 2 : Could not find record to remove + * 3 : Failed to create new signature + * 4 : Failed to put new set of records in database + */ + int32_t op_result; +}; + + +/** + * Lookup a name for a zone hash + */ +struct ZoneToNameMessage +{ + /** + * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME */ - uint32_t op_id; + struct GNUNET_NAMESTORE_Header gns_header; - /* Contenct starts here */ + /** + * The hash of public key of the zone to look up in + */ + struct GNUNET_CRYPTO_ShortHashCode zone; /** - * name length: GNUNET_NO (0) on error, GNUNET_OK (1) on success + * The hash of the public key of the target zone */ - uint16_t op_result; + struct GNUNET_CRYPTO_ShortHashCode value_zone; }; -GNUNET_NETWORK_STRUCT_END + +/** + * Respone for zone to name lookup + */ +struct ZoneToNameResponseMessage +{ + /** + * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE + */ + struct GNUNET_NAMESTORE_Header gns_header; + + /** + * Record block expiration + */ + struct GNUNET_TIME_AbsoluteNBO expire; + + /** + * Length of the name + */ + uint16_t name_len; + + /** + * Length of serialized record data + */ + uint16_t rd_len; + + /** + * Number of records contained + */ + uint16_t rd_count; + + /* result in NBO: GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error */ + int16_t res; + + /** + * Signature + */ + struct GNUNET_CRYPTO_RsaSignature signature; + + /** + * Publik key + */ + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key; + +}; + /** * Start a zone iteration for the given zone */ -GNUNET_NETWORK_STRUCT_BEGIN struct ZoneIterationStartMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START */ - struct GNUNET_MessageHeader header; + struct GNUNET_NAMESTORE_Header gns_header; /** - * Operation ID in NBO + * Zone hash */ - uint32_t op_id; - - /* Contenct starts here */ + struct GNUNET_CRYPTO_ShortHashCode zone; + /** + * Which flags must be included + */ uint16_t must_have_flags; - uint16_t must_not_have_flags; - GNUNET_HashCode zone; + /** + * Which flags must not be included + */ + uint16_t must_not_have_flags; }; -GNUNET_NETWORK_STRUCT_END + /** * Ask for next result of zone iteration for the given operation */ -GNUNET_NETWORK_STRUCT_BEGIN struct ZoneIterationNextMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT */ - struct GNUNET_MessageHeader header; - - /** - * Operation ID in NBO - */ - uint32_t op_id; + struct GNUNET_NAMESTORE_Header gns_header; }; -GNUNET_NETWORK_STRUCT_END /** * Stop zone iteration for the given operation */ -GNUNET_NETWORK_STRUCT_BEGIN struct ZoneIterationStopMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP */ - struct GNUNET_MessageHeader header; - - /** - * Operation ID in NBO - */ - uint32_t op_id; + struct GNUNET_NAMESTORE_Header gns_header; }; -GNUNET_NETWORK_STRUCT_END /** - * Ask for next result of zone iteration for the given operation + * Next result of zone iteration for the given operation + * // FIXME: use 'struct LookupResponseMessage' instead? (identical except + * for having 'contains_sig' instead of 'reserved', but fully compatible otherwise). */ -GNUNET_NETWORK_STRUCT_BEGIN struct ZoneIterationResponseMessage { /** * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE */ - struct GNUNET_MessageHeader header; + struct GNUNET_NAMESTORE_Header gns_header; + + struct GNUNET_TIME_AbsoluteNBO expire; + + uint16_t name_len; + + /* Record data length */ + uint16_t rd_len; /** - * Operation ID in NBO + * Number of records contained */ - uint32_t op_id; + uint16_t rd_count; + + /** + * always zero (for alignment) + */ + uint16_t reserved; + + /** + * All zeros if 'contains_sig' is GNUNET_NO. + */ + struct GNUNET_CRYPTO_RsaSignature signature; + + /** + * The public key + */ + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; + + + }; GNUNET_NETWORK_STRUCT_END diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index 1d41399..151fb97 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c @@ -27,11 +27,14 @@ #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet_crypto_lib.h" #include "gnunet_constants.h" +#include "gnunet_dnsparser_lib.h" #include "gnunet_arm_service.h" +#include "gnunet_signatures.h" #include "gnunet_namestore_service.h" #include "namestore.h" -#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING + #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) @@ -40,7 +43,15 @@ */ struct GNUNET_NAMESTORE_QueueEntry { + + /** + * Kept in a DLL. + */ struct GNUNET_NAMESTORE_QueueEntry *next; + + /** + * Kept in a DLL. + */ struct GNUNET_NAMESTORE_QueueEntry *prev; struct GNUNET_NAMESTORE_Handle *nsh; @@ -62,7 +73,15 @@ struct GNUNET_NAMESTORE_QueueEntry */ struct GNUNET_NAMESTORE_ZoneIterator { + + /** + * Kept in a DLL. + */ struct GNUNET_NAMESTORE_ZoneIterator *next; + + /** + * Kept in a DLL. + */ struct GNUNET_NAMESTORE_ZoneIterator *prev; uint32_t op_id; @@ -70,9 +89,10 @@ struct GNUNET_NAMESTORE_ZoneIterator struct GNUNET_NAMESTORE_Handle *h; GNUNET_NAMESTORE_RecordProcessor proc; void* proc_cls; - GNUNET_HashCode zone; + struct GNUNET_CRYPTO_ShortHashCode zone; uint32_t no_flags; uint32_t flags; + int has_zone; }; @@ -172,7 +192,7 @@ struct GNUNET_NAMESTORE_SimpleRecord struct GNUNET_NAMESTORE_SimpleRecord *prev; const char *name; - const GNUNET_HashCode *zone; + const struct GNUNET_CRYPTO_ShortHashCode *zone; uint32_t record_type; struct GNUNET_TIME_Absolute expiration; enum GNUNET_NAMESTORE_RecordFlags flags; @@ -181,6 +201,7 @@ struct GNUNET_NAMESTORE_SimpleRecord }; + /** * Disconnect from service and then reconnect. * @@ -198,57 +219,77 @@ handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe, "LOOKUP_NAME_RESPONSE"); struct GNUNET_NAMESTORE_Handle *h = qe->nsh; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; + + /* Operation done, remove */ + GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); + + char *name; - struct GNUNET_NAMESTORE_RecordData *rd = NULL; + char * rd_tmp; + struct GNUNET_CRYPTO_RsaSignature *signature = NULL; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded dummy; struct GNUNET_TIME_Absolute expire; - unsigned int rd_count = 0; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key_tmp; + size_t exp_msg_len; size_t msg_len = 0; size_t name_len = 0; + size_t rd_len = 0; int contains_sig = GNUNET_NO; + int rd_count = 0; - rd_count = ntohl (msg->rc_count); - msg_len = ntohs (msg->header.size); + rd_len = ntohs (msg->rd_len); + rd_count = ntohs (msg->rd_count); + msg_len = ntohs (msg->gns_header.header.size); name_len = ntohs (msg->name_len); contains_sig = ntohs (msg->contains_sig); expire = GNUNET_TIME_absolute_ntoh(msg->expire); - if (msg_len != sizeof (struct LookupNameResponseMessage) + + exp_msg_len = sizeof (struct LookupNameResponseMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + - name_len + - rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData) + - contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature)) + name_len + rd_len; + + if (msg_len != exp_msg_len) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message size describes with `%u' bytes but calculated size is %u bytes \n", + msg_len, exp_msg_len); + GNUNET_break_op (0); + return; + } + + name = (char *) &msg[1]; + if (name_len > 0) + { + GNUNET_assert ('\0' == name[name_len -1]); + GNUNET_assert ((name_len - 1) == strlen(name)); + } + rd_tmp = &name[name_len]; + + /* deserialize records */ + struct GNUNET_NAMESTORE_RecordData rd[rd_count]; + if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_len, rd_tmp, rd_count, rd)) { GNUNET_break_op (0); return; } - zone_key = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &msg[1]; - name = (char *) &zone_key[1]; - rd = (struct GNUNET_NAMESTORE_RecordData *) &name[name_len]; /* reset values if values not contained */ if (contains_sig == GNUNET_NO) signature = NULL; else - signature = (struct GNUNET_CRYPTO_RsaSignature *) &rd[rd_count]; - if (rd_count == 0) - rd = NULL; + signature = &msg->signature; if (name_len == 0) name = NULL; - memset (&dummy, '0', sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); - if (0 == memcmp (zone_key, &dummy, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) - zone_key = NULL; + if (name != NULL) + public_key_tmp = &msg->public_key; + else + public_key_tmp = NULL; if (qe->proc != NULL) { - qe->proc (qe->proc_cls, zone_key, expire, name, rd_count, rd, signature); + qe->proc (qe->proc_cls, public_key_tmp, expire, name, rd_count, (rd_count > 0) ? rd : NULL, signature); } - /* Operation done, remove */ - GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); GNUNET_free (qe); } @@ -262,20 +303,21 @@ handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe, "RECORD_PUT_RESPONSE"); struct GNUNET_NAMESTORE_Handle *h = qe->nsh; - int res = GNUNET_OK; + /* Operation done, remove */ + GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); + + int res = ntohl (msg->op_result); - if (ntohs (msg->op_result) == GNUNET_OK) + if (res == GNUNET_OK) { - res = GNUNET_OK; if (qe->cont != NULL) { qe->cont (qe->cont_cls, res, _("Namestore added record successfully")); } } - else if (ntohs (msg->op_result) == GNUNET_NO) + else if (res == GNUNET_SYSERR) { - res = GNUNET_SYSERR; if (qe->cont != NULL) { qe->cont (qe->cont_cls, res, _("Namestore failed to add record")); @@ -287,9 +329,6 @@ handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe, return; } - /* Operation done, remove */ - GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); - GNUNET_free (qe); } @@ -303,34 +342,165 @@ handle_record_create_response (struct GNUNET_NAMESTORE_QueueEntry *qe, "RECORD_CREATE_RESPONSE"); struct GNUNET_NAMESTORE_Handle *h = qe->nsh; - int res = GNUNET_OK; + /* Operation done, remove */ + GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); - if (ntohs (msg->op_result) == GNUNET_OK) + int res = ntohl (msg->op_result); + if (res == GNUNET_YES) { - res = GNUNET_OK; if (qe->cont != NULL) { qe->cont (qe->cont_cls, res, _("Namestore added record successfully")); } } - else if (ntohs (msg->op_result) == GNUNET_NO) + else if (res == GNUNET_NO) { - res = GNUNET_SYSERR; if (qe->cont != NULL) { - qe->cont (qe->cont_cls, res, _("Namestore failed to add record")); + qe->cont (qe->cont_cls, res, _("Namestore record already existed")); } } else { - GNUNET_break_op (0); - return; + if (qe->cont != NULL) + { + qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Namestore failed to add record\n")); + } + } + + GNUNET_free (qe); +} + + +static void +handle_record_remove_response (struct GNUNET_NAMESTORE_QueueEntry *qe, + struct RecordRemoveResponseMessage* msg, + size_t size) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n", + "RECORD_REMOVE_RESPONSE"); + + struct GNUNET_NAMESTORE_Handle *h = qe->nsh; + /* Operation done, remove */ + GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); + + int res = ntohl (msg->op_result); + /** + * result: + * 0 : successful + * 1 : No records for entry + * 2 : Could not find record to remove + * 3 : Failed to create new signature + * 4 : Failed to put new set of records in database + */ + switch (res) { + case 0: + if (qe->cont != NULL) + { + qe->cont (qe->cont_cls, GNUNET_YES, _("Namestore removed record successfully")); + } + + break; + case 1: + if (qe->cont != NULL) + { + qe->cont (qe->cont_cls, GNUNET_NO, _("No records for entry")); + } + + break; + case 2: + if (qe->cont != NULL) + { + qe->cont (qe->cont_cls, GNUNET_NO, _("Could not find record to remove")); + } + + break; + case 3: + if (qe->cont != NULL) + { + qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Failed to create new signature")); + } + + break; + case 4: + if (qe->cont != NULL) + { + qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Failed to put new set of records in database")); + } + break; + default: + GNUNET_break_op (0); + break; } + GNUNET_free (qe); +} + +static void +handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe, + struct ZoneToNameResponseMessage* msg, + size_t size) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n", + "ZONE_TO_NAME_RESPONSE"); + + struct GNUNET_NAMESTORE_Handle *h = qe->nsh; /* Operation done, remove */ GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); + int res = ntohs (msg->res); + + struct GNUNET_TIME_Absolute expire; + size_t name_len; + size_t rd_ser_len; + unsigned int rd_count; + + char * name_tmp; + char * rd_tmp; + + if (res == GNUNET_SYSERR) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "An error occured during zone to name operation\n"); + if (qe->proc != NULL) + qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); + } + else if (res == GNUNET_NO) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore has no result for zone to name mapping \n"); + if (qe->proc != NULL) + qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); + } + else if (res == GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore has result for zone to name mapping \n"); + + name_len = ntohs (msg->name_len); + rd_count = ntohs (msg->rd_count); + rd_ser_len = ntohs (msg->rd_len); + expire = GNUNET_TIME_absolute_ntoh(msg->expire); + + name_tmp = (char *) &msg[1]; + if (name_len > 0) + { + GNUNET_assert ('\0' == name_tmp[name_len -1]); + GNUNET_assert (name_len -1 == strlen(name_tmp)); + } + rd_tmp = &name_tmp[name_len]; + + struct GNUNET_NAMESTORE_RecordData rd[rd_count]; + if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_tmp, rd_count, rd)) + { + GNUNET_break_op (0); + return; + } + + if (qe->proc != NULL) + qe->proc (qe->proc_cls, &msg->zone_key, expire, name_tmp, rd_count, rd, &msg->signature); + } + else + GNUNET_break_op (0); + GNUNET_free (qe); } @@ -367,6 +537,22 @@ manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe, } handle_record_create_response (qe, (struct RecordCreateResponseMessage *) msg, size); break; + case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE: + if (size != sizeof (struct RecordRemoveResponseMessage)) + { + GNUNET_break_op (0); + break; + } + handle_record_remove_response (qe, (struct RecordRemoveResponseMessage *) msg, size); + break; + case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE: + if (size < sizeof (struct ZoneToNameResponseMessage)) + { + GNUNET_break_op (0); + break; + } + handle_zone_to_name_response (qe, (struct ZoneToNameResponseMessage *) msg, size); + break; default: GNUNET_break_op (0); break; @@ -381,12 +567,67 @@ handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n", "ZONE_ITERATION_RESPONSE"); + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubdummy; + size_t msg_len = 0; + size_t exp_msg_len = 0; + size_t name_len = 0; + size_t rd_len = 0; + unsigned rd_count = 0; - if (ze->proc != NULL) + char *name_tmp; + char *rd_ser_tmp; + struct GNUNET_TIME_Absolute expire; + + msg_len = ntohs (msg->gns_header.header.size); + rd_len = ntohs (msg->rd_len); + rd_count = ntohs (msg->rd_count); + name_len = ntohs (msg->name_len); + expire = GNUNET_TIME_absolute_ntoh (msg->expire); + + exp_msg_len = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_len; + if (msg_len != exp_msg_len) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message size describes with `%u' bytes but calculated size is %u bytes \n", + msg_len, exp_msg_len); + GNUNET_break_op (0); + return; + } + if (0 != ntohs (msg->reserved)) + { + GNUNET_break_op (0); + return; + } + + memset (&pubdummy, '\0', sizeof (pubdummy)); + if ((0 == name_len) && (0 == (memcmp (&msg->public_key, &pubdummy, sizeof (pubdummy))))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration is completed!\n"); + + GNUNET_CONTAINER_DLL_remove(ze->h->z_head, ze->h->z_tail, ze); + + if (ze->proc != NULL) + ze->proc(ze->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL , 0, NULL, NULL); + + GNUNET_free (ze); + return; + } + + name_tmp = (char *) &msg[1]; + if ((name_tmp[name_len -1] != '\0') || (name_len > 256)) + { + GNUNET_break_op (0); + return; + } + rd_ser_tmp = (char *) &name_tmp[name_len]; + struct GNUNET_NAMESTORE_RecordData rd[rd_count]; + if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd)) { - // FIXME - ze->proc(ze->proc_cls, NULL, GNUNET_TIME_absolute_get_forever(), "dummy", 0, NULL, NULL); + GNUNET_break_op (0); + return; } + + if (ze->proc != NULL) + ze->proc(ze->proc_cls, &msg->public_key, expire, name_tmp, rd_count, rd, &msg->signature); } @@ -423,12 +664,12 @@ static void process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_NAMESTORE_Handle *h = cls; - struct GenericMessage * gm; + struct GNUNET_NAMESTORE_Header * gm; struct GNUNET_NAMESTORE_QueueEntry *qe; struct GNUNET_NAMESTORE_ZoneIterator *ze; uint16_t size; uint16_t type; - uint32_t op_id = UINT32_MAX; + uint32_t r_id = UINT32_MAX; if (NULL == msg) { @@ -439,7 +680,7 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg) size = ntohs (msg->size); type = ntohs (msg->type); - if (size < sizeof (struct GenericMessage)) + if (size < sizeof (struct GNUNET_NAMESTORE_Header)) { GNUNET_break_op (0); GNUNET_CLIENT_receive (h->client, &process_namestore_message, h, @@ -447,13 +688,13 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg) return; } - gm = (struct GenericMessage *) msg; - op_id = ntohl (gm->op_id); + gm = (struct GNUNET_NAMESTORE_Header *) msg; + r_id = ntohl (gm->r_id); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message type %i size %i op %u\n", type, size, op_id); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message type %i size %i op %u\n", type, size, r_id); /* Find matching operation */ - if (op_id > h->op_id) + if (r_id > h->op_id) { /* No matching pending operation found */ GNUNET_break_op (0); @@ -465,7 +706,7 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg) /* Is it a record related operation ? */ for (qe = h->op_head; qe != NULL; qe = qe->next) { - if (qe->op_id == op_id) + if (qe->op_id == r_id) break; } if (qe != NULL) @@ -476,7 +717,7 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg) /* Is it a zone iteration operation ? */ for (ze = h->z_head; ze != NULL; ze = ze->next) { - if (ze->op_id == op_id) + if (ze->op_id == r_id) break; } if (ze != NULL) @@ -622,7 +863,7 @@ static void force_reconnect (struct GNUNET_NAMESTORE_Handle *h) { h->reconnect = GNUNET_NO; - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task, @@ -655,23 +896,15 @@ GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) return h; } - -/** - * Disconnect from the namestore service (and free associated - * resources). - * - * @param h handle to the namestore - * @param drop set to GNUNET_YES to delete all data in namestore (!) - */ -void -GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop) +static void +clean_up_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct PendingMessage *p; struct GNUNET_NAMESTORE_QueueEntry *q; struct GNUNET_NAMESTORE_ZoneIterator *z; - + struct GNUNET_NAMESTORE_Handle *h = cls; GNUNET_assert (h != NULL); - + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); while (NULL != (p = h->pending_head)) { GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p); @@ -692,7 +925,7 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop) if (NULL != h->client) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } if (GNUNET_SCHEDULER_NO_TASK != h->reconnect_task) @@ -705,6 +938,21 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop) } +/** + * Disconnect from the namestore service (and free associated + * resources). + * + * @param h handle to the namestore + * @param drop set to GNUNET_YES to delete all data in namestore (!) + */ +void +GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from namestore service\n"); + GNUNET_SCHEDULER_add_now (&clean_up_task, h); +} + + /** * Store an item in the namestore. If the item is already present, * the expiration time is updated to the max of the existing time and @@ -714,7 +962,7 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h, int drop) * @param h handle to the namestore * @param zone_key public key of the zone * @param name name that is being mapped (at most 255 characters long) - * @param expire when does the corresponding block in the DHT expire (until + * @param freshness when does the corresponding block in the DHT expire (until * when should we never do a DHT lookup for the same name again)? * @param rd_count number of entries in 'rd' array * @param rd array of records with data to store @@ -727,7 +975,7 @@ struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, const char *name, - struct GNUNET_TIME_Absolute expire, + struct GNUNET_TIME_Absolute freshness, unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature, @@ -738,52 +986,63 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, struct PendingMessage *pe; /* pointer to elements */ - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key_tmp; char * rd_tmp; - char * rd_ser; char * name_tmp; size_t msg_size = 0; - size_t name_len = strlen(name) + 1; + size_t name_len = 0; size_t rd_ser_len = 0; - uint32_t id = 0; + uint32_t rid = 0; GNUNET_assert (NULL != h); - id = get_op_id(h); + GNUNET_assert (NULL != zone_key); + GNUNET_assert (NULL != name); + GNUNET_assert (NULL != rd); + GNUNET_assert (NULL != signature); + + name_len = strlen(name) + 1; + if (name_len > 256) + { + GNUNET_break (0); + return NULL; + } + + rid = get_op_id(h); qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); qe->nsh = h; qe->cont = cont; qe->cont_cls = cont_cls; - qe->op_id = id; + qe->op_id = rid; GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe); /* set msg_size*/ - rd_ser_len = GNUNET_NAMESTORE_records_serialize(&rd_ser, rd_count, rd); + rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser); struct RecordPutMessage * msg; - msg_size = sizeof (struct RecordPutMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len + rd_ser_len; + msg_size = sizeof (struct RecordPutMessage) + name_len + rd_ser_len; /* create msg here */ pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); pe->size = msg_size; pe->is_init = GNUNET_NO; msg = (struct RecordPutMessage *) &pe[1]; - zone_key_tmp = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &msg[1]; - name_tmp = (char *) &zone_key_tmp[1]; + name_tmp = (char *) &msg[1]; rd_tmp = &name_tmp[name_len]; - msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT); - msg->header.size = htons (msg_size); - msg->op_id = htonl (id); - memcpy (zone_key_tmp, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT); + msg->gns_header.header.size = htons (msg_size); + msg->gns_header.r_id = htonl (rid); msg->signature = *signature; msg->name_len = htons (name_len); - memcpy (name_tmp, name, name_len); - msg->expire = GNUNET_TIME_absolute_hton (expire); + msg->expire = GNUNET_TIME_absolute_hton (freshness); msg->rd_len = htons (rd_ser_len); + msg->rd_count = htons (rd_count); + msg->public_key = *zone_key; + memcpy (name_tmp, name, name_len); memcpy (rd_tmp, rd_ser, rd_ser_len); - GNUNET_free (rd_ser); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_PUT", name, msg_size); @@ -799,6 +1058,7 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, * to validate signatures received from the network. * * @param public_key public key of the zone + * @param expire block expiration * @param name name that is being mapped (at most 255 characters long) * @param rd_count number of entries in 'rd' array * @param rd array of records with data to store @@ -807,12 +1067,53 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, */ int GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key, + const struct GNUNET_TIME_Absolute expire, const char *name, unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature) { - return GNUNET_SYSERR; + int res = GNUNET_SYSERR; + size_t rd_ser_len = 0; + size_t name_len = 0; + char * name_tmp; + char * rd_tmp; + struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose; + struct GNUNET_TIME_AbsoluteNBO *expire_tmp; + struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton(expire); + + GNUNET_assert (public_key != NULL); + GNUNET_assert (name != NULL); + GNUNET_assert (rd != NULL); + GNUNET_assert (signature != NULL); + + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser); + + name_len = strlen (name) + 1; + if (name_len > 256) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len); + sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len); + sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); + expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1]; + name_tmp = (char *) &expire_tmp[1]; + rd_tmp = &name_tmp[name_len]; + memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO)); + memcpy (name_tmp, name, name_len); + memcpy (rd_tmp, rd_ser, rd_ser_len); + + res = GNUNET_CRYPTO_rsa_verify(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, sig_purpose, signature, public_key); + + GNUNET_free (sig_purpose); + + return res; } /** @@ -839,26 +1140,45 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h, struct GNUNET_NAMESTORE_QueueEntry *qe; struct PendingMessage *pe; char * name_tmp; + char * pkey_tmp; char * rd_tmp; - char * rd_ser; size_t rd_ser_len = 0; size_t msg_size = 0; size_t name_len = 0; - uint32_t id = 0; + size_t key_len = 0; + uint32_t rid = 0; GNUNET_assert (NULL != h); + GNUNET_assert (NULL != pkey); + GNUNET_assert (NULL != name); + GNUNET_assert (NULL != rd); + + name_len = strlen(name) + 1; + if (name_len > 256) + { + GNUNET_break (0); + return NULL; + } - id = get_op_id(h); + rid = get_op_id(h); qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); qe->nsh = h; qe->cont = cont; qe->cont_cls = cont_cls; - qe->op_id = id; + qe->op_id = rid; + GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe); /* set msg_size*/ - rd_ser_len = GNUNET_NAMESTORE_records_serialize(&rd_ser, 1, rd); + struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * pkey_enc = GNUNET_CRYPTO_rsa_encode_key (pkey); + GNUNET_assert (pkey_enc != NULL); + key_len = ntohs (pkey_enc->len); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(1, rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(1, rd, rd_ser_len, rd_ser); + struct RecordCreateMessage * msg; - msg_size = sizeof (struct RecordCreateMessage) + name_len + rd_ser_len; + msg_size = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len; /* create msg here */ pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); @@ -866,17 +1186,22 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h, pe->is_init = GNUNET_NO; msg = (struct RecordCreateMessage *) &pe[1]; - name_tmp = (char *) &msg[1]; + pkey_tmp = (char *) &msg[1]; + name_tmp = &pkey_tmp[key_len]; rd_tmp = &name_tmp[name_len]; - msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE); - msg->header.size = htons (msg_size); - msg->op_id = htonl (id); - //msg->signature = *signature; + msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE); + msg->gns_header.header.size = htons (msg_size); + msg->gns_header.r_id = htonl (rid); msg->name_len = htons (name_len); + msg->rd_count = htons (1); + msg->rd_len = htons (rd_ser_len); + msg->pkey_len = htons (key_len); + msg->expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_UNIT_FOREVER_ABS); + memcpy (pkey_tmp, pkey_enc, key_len); memcpy (name_tmp, name, name_len); memcpy (rd_tmp, rd_ser, rd_ser_len); - GNUNET_free (rd_ser); + GNUNET_free (pkey_enc); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_CREATE", name, msg_size); @@ -896,7 +1221,7 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h, * @param h handle to the namestore * @param pkey private key of the zone * @param name name that is being mapped (at most 255 characters long) - * @param rd record data + * @param rd record data, remove specific record, NULL to remove the name and all records * @param cont continuation to call when done * @param cont_cls closure for cont * @return handle to abort the request @@ -911,27 +1236,43 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h, { struct GNUNET_NAMESTORE_QueueEntry *qe; struct PendingMessage *pe; - char * rd_tmp; - char * rd_ser; - char * name_tmp; + char *pkey_tmp; + char *rd_tmp; + char *name_tmp; size_t rd_ser_len = 0; size_t msg_size = 0; size_t name_len = 0; - uint32_t id = 0; + size_t key_len = 0; + uint32_t rid = 0; + uint16_t rd_count = 1; GNUNET_assert (NULL != h); - id = get_op_id(h); + rid = get_op_id(h); qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); qe->nsh = h; qe->cont = cont; qe->cont_cls = cont_cls; - qe->op_id = id; + qe->op_id = rid; + GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe); /* set msg_size*/ - rd_ser_len = GNUNET_NAMESTORE_records_serialize(&rd_ser, 1, rd); + struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * pkey_enc = GNUNET_CRYPTO_rsa_encode_key (pkey); + GNUNET_assert (pkey_enc != NULL); + key_len = ntohs (pkey_enc->len); + + if (NULL == rd) + rd_count = 0; + else + rd_count = 1; + rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser); + + name_len = strlen (name) + 1; + struct RecordRemoveMessage * msg; - msg_size = sizeof (struct RecordRemoveMessage) + name_len + rd_ser_len; + msg_size = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len; /* create msg here */ pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); @@ -939,17 +1280,22 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h, pe->is_init = GNUNET_NO; msg = (struct RecordRemoveMessage *) &pe[1]; - name_tmp = (char *) &msg[1]; + pkey_tmp = (char *) &msg[1]; + name_tmp = &pkey_tmp[key_len]; rd_tmp = &name_tmp[name_len]; - msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE); - msg->header.size = htons (msg_size); - msg->op_id = htonl (id); - //msg->signature = *signature; + msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE); + msg->gns_header.header.size = htons (msg_size); + msg->gns_header.r_id = htonl (rid); msg->name_len = htons (name_len); + msg->rd_len = htons (rd_ser_len); + msg->rd_count = htons (rd_count); + msg->pkey_len = htons (key_len); + memcpy (pkey_tmp, pkey_enc, key_len); memcpy (name_tmp, name, name_len); memcpy (rd_tmp, rd_ser, rd_ser_len); - GNUNET_free (rd_ser); + + GNUNET_free (pkey_enc); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_REMOVE", name, msg_size); @@ -975,7 +1321,7 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h, */ struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, - const GNUNET_HashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *zone, const char *name, uint32_t record_type, GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls) @@ -984,7 +1330,7 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, struct PendingMessage *pe; size_t msg_size = 0; size_t name_len = 0; - uint32_t id = 0; + uint32_t rid = 0; GNUNET_assert (NULL != h); GNUNET_assert (NULL != zone); @@ -997,12 +1343,12 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, return NULL; } - id = get_op_id(h); + rid = get_op_id(h); qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); qe->nsh = h; qe->proc = proc; qe->proc_cls = proc_cls; - qe->op_id = id; + qe->op_id = rid; GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe); /* set msg_size*/ @@ -1014,12 +1360,12 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, pe->size = msg_size; pe->is_init = GNUNET_NO; msg = (struct LookupNameMessage *) &pe[1]; - msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME); - msg->header.size = htons (msg_size); - msg->op_id = htonl (id); + msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME); + msg->gns_header.header.size = htons (msg_size); + msg->gns_header.r_id = htonl (rid); msg->record_type = htonl (record_type); - msg->zone = *zone; msg->name_len = htonl (name_len); + msg->zone = *zone; memcpy (&msg[1], name, name_len); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s'\n", "NAMESTORE_LOOKUP_NAME", name); @@ -1032,6 +1378,72 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, } +/** + * Look for an existing PKEY delegation record for a given public key. + * Returns at most one result to the processor. + * + * @param h handle to the namestore + * @param zone hash of public key of the zone to look up in, never NULL + * @param value_zone hash of the public key of the target zone (value), never NULL + * @param proc function to call on the matching records, or with + * NULL (rd_count == 0) if there are no matching records + * @param proc_cls closure for proc + * @return a handle that can be used to + * cancel + */ +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h, + const struct GNUNET_CRYPTO_ShortHashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *value_zone, + GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls) +{ + struct GNUNET_NAMESTORE_QueueEntry *qe; + struct PendingMessage *pe; + size_t msg_size = 0; + uint32_t rid = 0; + + GNUNET_assert (NULL != h); + GNUNET_assert (NULL != zone); + GNUNET_assert (NULL != value_zone); + + rid = get_op_id(h); + qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); + qe->nsh = h; + qe->proc = proc; + qe->proc_cls = proc_cls; + qe->op_id = rid; + GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe); + + /* set msg_size*/ + msg_size = sizeof (struct ZoneToNameMessage); + pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); + + /* create msg here */ + struct ZoneToNameMessage * msg; + pe->size = msg_size; + pe->is_init = GNUNET_NO; + msg = (struct ZoneToNameMessage *) &pe[1]; + msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME); + msg->gns_header.header.size = htons (msg_size); + msg->gns_header.r_id = htonl (rid); + msg->zone = *zone; + msg->value_zone = *value_zone; + + char * z_tmp = GNUNET_strdup (GNUNET_short_h2s (zone)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s' in zone `%s'\n", + "NAMESTORE_ZONE_TO_NAME", + z_tmp, + GNUNET_short_h2s (value_zone)); + GNUNET_free (z_tmp); + + /* transmit message */ + GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); + do_transmit(h); + + return qe; +} + + /** * Starts a new zone iteration (used to periodically PUT all of our @@ -1053,7 +1465,7 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, */ struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h, - const GNUNET_HashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *zone, enum GNUNET_NAMESTORE_RecordFlags must_have_flags, enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags, GNUNET_NAMESTORE_RecordProcessor proc, @@ -1062,18 +1474,28 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h, struct GNUNET_NAMESTORE_ZoneIterator *it; struct PendingMessage *pe; size_t msg_size = 0; - uint32_t id = 0; + uint32_t rid = 0; GNUNET_assert (NULL != h); - GNUNET_assert (NULL != zone); - id = get_op_id(h); + + rid = get_op_id(h); it = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIterator)); it->h = h; it->proc = proc; - it->proc_cls = proc; - it->op_id = id; - it->zone = *zone; + it->proc_cls = proc_cls; + it->op_id = rid; + + if (NULL != zone) + { + it->zone = *zone; + it->has_zone = GNUNET_YES; + } + else + { + memset (&it->zone, '\0', sizeof (it->zone)); + it->has_zone = GNUNET_NO; + } GNUNET_CONTAINER_DLL_insert_tail(h->z_head, h->z_tail, it); /* set msg_size*/ @@ -1085,14 +1507,23 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h, pe->size = msg_size; pe->is_init = GNUNET_NO; msg = (struct ZoneIterationStartMessage *) &pe[1]; - msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START); - msg->header.size = htons (msg_size); - msg->op_id = htonl (id); - msg->zone = *zone; + msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START); + msg->gns_header.header.size = htons (msg_size); + msg->gns_header.r_id = htonl (rid); + if (NULL != zone) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_START", GNUNET_short_h2s(zone)); + msg->zone = *zone; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for all zones\n", "ZONE_ITERATION_START"); + memset (&msg->zone, '\0', sizeof (msg->zone)); + } msg->must_have_flags = ntohs (must_have_flags); msg->must_not_have_flags = ntohs (must_not_have_flags); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_START", GNUNET_h2s(zone)); + /* transmit message */ GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); @@ -1117,6 +1548,15 @@ GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it) GNUNET_assert (NULL != it); h = it->h; + struct GNUNET_NAMESTORE_ZoneIterator *tmp = it->h->z_head; + + while (tmp != NULL) + { + if (tmp == it) + break; + tmp = tmp->next; + } + GNUNET_assert (NULL != tmp); /* set msg_size*/ msg_size = sizeof (struct ZoneIterationNextMessage); @@ -1127,11 +1567,11 @@ GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it) pe->size = msg_size; pe->is_init = GNUNET_NO; msg = (struct ZoneIterationNextMessage *) &pe[1]; - msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT); - msg->header.size = htons (msg_size); - msg->op_id = htonl (it->op_id); + msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT); + msg->gns_header.header.size = htons (msg_size); + msg->gns_header.r_id = htonl (it->op_id); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s'\n", "ZONE_ITERATION_NEXT", GNUNET_h2s(&it->zone)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_ITERATION_NEXT"); /* transmit message */ GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); @@ -1151,6 +1591,15 @@ GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it) struct PendingMessage *pe; size_t msg_size = 0; struct GNUNET_NAMESTORE_Handle *h = it->h; + struct GNUNET_NAMESTORE_ZoneIterator *tmp = it->h->z_head; + + while (tmp != NULL) + { + if (tmp == it) + break; + tmp = tmp->next; + } + GNUNET_assert (NULL != tmp); /* set msg_size*/ msg_size = sizeof (struct ZoneIterationStopMessage); @@ -1161,11 +1610,14 @@ GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it) pe->size = msg_size; pe->is_init = GNUNET_NO; msg = (struct ZoneIterationStopMessage *) &pe[1]; - msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP); - msg->header.size = htons (msg_size); - msg->op_id = htonl (it->op_id); + msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP); + msg->gns_header.header.size = htons (msg_size); + msg->gns_header.r_id = htonl (it->op_id); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s'\n", "ZONE_ITERATION_STOP", GNUNET_h2s(&it->zone)); + if (GNUNET_YES == it->has_zone) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_STOP", GNUNET_short_h2s(&it->zone)); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for all zones\n", "ZONE_ITERATION_STOP"); /* transmit message */ GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); diff --git a/src/namestore/namestore_common.c b/src/namestore/namestore_common.c index 37f0eab..95f6364 100644 --- a/src/namestore/namestore_common.c +++ b/src/namestore/namestore_common.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -28,132 +28,536 @@ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_constants.h" +#include "gnunet_signatures.h" #include "gnunet_arm_service.h" #include "gnunet_namestore_service.h" +#include "gnunet_dnsparser_lib.h" #include "namestore.h" -#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING + #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) + + +/** + * Internal format of a record in the serialized form. + */ +struct NetworkRecord +{ + + /** + * Expiration time for the DNS record. + */ + struct GNUNET_TIME_AbsoluteNBO expiration; + + /** + * Number of bytes in 'data', network byte order. + */ + uint32_t data_size; + + /** + * Type of the GNS/DNS record, network byte order. + */ + uint32_t record_type; + + /** + * Flags for the record, network byte order. + */ + uint32_t flags; + +}; + + /** - * Serialize an array of GNUNET_NAMESTORE_RecordData *rd to transmit over the - * network + * Convert a short hash to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! * - * @param dest where to write the serialized data - * @param rd_count number of elements in array - * @param rd array + * @param hc the short hash code + * @return string form; will be overwritten by next call to GNUNET_h2s. + */ +const char * +GNUNET_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc) +{ + static struct GNUNET_CRYPTO_ShortHashAsciiEncoded ret; + + GNUNET_CRYPTO_short_hash_to_enc (hc, &ret); + return (const char *) &ret; +} + + +/** + * Calculate how many bytes we will need to serialize the given + * records. + * + * @param rd_count number of records in the rd array + * @param rd array of GNUNET_NAMESTORE_RecordData with rd_count elements + * + * @return the required size to serialize * - * @return number of bytes written to destination dest */ size_t -GNUNET_NAMESTORE_records_serialize (char ** dest, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd) +GNUNET_NAMESTORE_records_get_size (unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) { - //size_t len = 0; - struct GNUNET_NAMESTORE_NetworkRecord * nr; - char * d = (*dest); - int c = 0; - int offset; + unsigned int i; + size_t ret; + ret = sizeof (struct NetworkRecord) * rd_count; + for (i=0;i= ret); + ret += rd[i].data_size; + } + return ret; +} - size_t total_len = rd_count * sizeof (struct GNUNET_NAMESTORE_NetworkRecord); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Struct size: %u\n", total_len); - /* figure out total len required */ - for (c = 0; c < rd_count; c ++) +/** + * Serialize the given records to the given destination buffer. + * + * @param rd_count number of records in the rd array + * @param rd array of GNUNET_NAMESTORE_RecordData with rd_count elements + * @param dest_size size of the destination array + * @param dest where to write the result + * + * @return the size of serialized records + */ +ssize_t +GNUNET_NAMESTORE_records_serialize (unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + size_t dest_size, + char *dest) +{ + struct NetworkRecord rec; + unsigned int i; + size_t off; + + off = 0; + for (i=0;i dest_size) + return -1; + memcpy (&dest[off], &rec, sizeof (rec)); + off += sizeof (rec); + if (off + rd[i].data_size > dest_size) + return -1; + memcpy (&dest[off], rd[i].data, rd[i].data_size); + off += rd[i].data_size; } + return off; +} + +/** + * Compares if two records are equal + * + * @param a record + * @param b record + * + * @return GNUNET_YES or GNUNET_NO + */ +int +GNUNET_NAMESTORE_records_cmp (const struct GNUNET_NAMESTORE_RecordData *a, + const struct GNUNET_NAMESTORE_RecordData *b) +{ + if ((a->record_type == b->record_type) && + (a->expiration.abs_value == b->expiration.abs_value) && + (a->data_size == b->data_size) && + (0 == memcmp (a->data, b->data, a->data_size))) + return GNUNET_YES; + else + return GNUNET_NO; +} - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serializing %i records with total length of %llu\n", rd_count, total_len); - (*dest) = GNUNET_malloc (total_len); - d = (*dest); +/** + * Deserialize the given records to the given destination. + * + * @param len size of the serialized record data + * @param src the serialized record data + * @param rd_count number of records in the rd array + * @param dest where to put the data + * + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_NAMESTORE_records_deserialize (size_t len, + const char *src, + unsigned int rd_count, + struct GNUNET_NAMESTORE_RecordData *dest) +{ + struct NetworkRecord rec; + unsigned int i; + size_t off; + + off = 0; + for (i=0;i len) + return GNUNET_SYSERR; + memcpy (&rec, &src[off], sizeof (rec)); + dest[i].expiration = GNUNET_TIME_absolute_ntoh (rec.expiration); + dest[i].data_size = ntohl ((uint32_t) rec.data_size); + dest[i].record_type = ntohl (rec.record_type); + dest[i].flags = ntohl (rec.flags); + off += sizeof (rec); - /* copy records */ - offset = 0; + if (off + dest[i].data_size > len) + return GNUNET_SYSERR; + dest[i].data = &src[off]; + off += dest[i].data_size; + } + return GNUNET_OK; +} - for (c = 0; c < rd_count; c ++) +/** + * Sign name and records + * + * @param key the private key + * @param expire block expiration + * @param name the name + * @param rd record data + * @param rd_count number of records + * + * @return the signature + */ +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key, + struct GNUNET_TIME_Absolute expire, + const char *name, + const struct GNUNET_NAMESTORE_RecordData *rd, + unsigned int rd_count) +{ + struct GNUNET_CRYPTO_RsaSignature *sig = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignature)); + struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose; + struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton(expire); + size_t rd_ser_len; + size_t name_len; + + struct GNUNET_TIME_AbsoluteNBO *expire_tmp; + char * name_tmp; + char * rd_tmp; + int res; + + if (name == NULL) + { + GNUNET_break (0); + GNUNET_free (sig); + return NULL; + } + name_len = strlen (name) + 1; + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser); + + sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len); + sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len); + sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); + expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1]; + name_tmp = (char *) &expire_tmp[1]; + rd_tmp = &name_tmp[name_len]; + memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO)); + memcpy (name_tmp, name, name_len); + memcpy (rd_tmp, rd_ser, rd_ser_len); + + res = GNUNET_CRYPTO_rsa_sign (key, sig_purpose, sig); + + GNUNET_free (sig_purpose); + + if (GNUNET_OK != res) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized record [%i]: data_size %i\n", c,rd[c].data_size); - - nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &d[offset]; - nr->data_size = htonl (rd[c].data_size); - nr->flags = htonl (rd[c].flags); - nr->record_type = htonl (rd[c].record_type); - nr->expiration = GNUNET_TIME_absolute_hton(rd[c].expiration); - - /*put data here */ - offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); - memcpy (&d[offset], rd[c].data, rd[c].data_size); - offset += rd[c].data_size; + GNUNET_break (0); + GNUNET_free (sig); + return NULL; } + return sig; +} - GNUNET_assert (offset == total_len); - return total_len; +/** + * Checks if a name is wellformed + * + * @param name the name to check + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_NAMESTORE_check_name (const char * name) +{ + if (name == NULL) + return GNUNET_SYSERR; + if (strlen (name) > 63) + return GNUNET_SYSERR; + return GNUNET_OK; } /** - * Deserialize an array of GNUNET_NAMESTORE_RecordData *rd after transmission - * over the network + * Convert the 'value' of a record to a string. * - * @param source where to read the data to deserialize - * @param rd_count number of elements in array - * @param rd array + * @param type type of the record + * @param data value in binary encoding + * @param data_size number of bytes in data + * @return NULL on error, otherwise human-readable representation of the value + */ +char * +GNUNET_NAMESTORE_value_to_string (uint32_t type, + const void *data, + size_t data_size) +{ + char tmp[INET6_ADDRSTRLEN]; + struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc; + uint16_t mx_pref; + char* result; + char* soa_rname; + char* soa_mname; + uint32_t* soa_data; + uint32_t soa_serial; + uint32_t soa_refresh; + uint32_t soa_retry; + uint32_t soa_expire; + uint32_t soa_min; + + switch (type) + { + case 0: + return NULL; + case GNUNET_DNSPARSER_TYPE_A: + if (data_size != sizeof (struct in_addr)) + return NULL; + if (NULL == inet_ntop (AF_INET, data, tmp, sizeof (tmp))) + return NULL; + return GNUNET_strdup (tmp); + case GNUNET_DNSPARSER_TYPE_NS: + return GNUNET_strndup (data, data_size); + case GNUNET_DNSPARSER_TYPE_CNAME: + return GNUNET_strndup (data, data_size); + case GNUNET_DNSPARSER_TYPE_SOA: + soa_rname = (char*)data; + soa_mname = (char*)data+strlen(soa_rname)+1; + soa_data = (uint32_t*)(soa_mname+strlen(soa_mname)+1); + soa_serial = ntohl(soa_data[0]); + soa_refresh = ntohl(soa_data[1]); + soa_retry = ntohl(soa_data[2]); + soa_expire = ntohl(soa_data[3]); + soa_min = ntohl(soa_data[4]); + if (GNUNET_asprintf(&result, "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", + soa_rname, soa_mname, + soa_serial, soa_refresh, soa_retry, soa_expire, soa_min)) + return result; + else + return NULL; + case GNUNET_DNSPARSER_TYPE_PTR: + return GNUNET_strndup (data, data_size); + case GNUNET_DNSPARSER_TYPE_MX: + mx_pref = ntohs(*((uint16_t*)data)); + if (GNUNET_asprintf(&result, "%hu,%s", mx_pref, data+sizeof(uint16_t)) + != 0) + return result; + else + return NULL; + case GNUNET_DNSPARSER_TYPE_TXT: + return GNUNET_strndup (data, data_size); + case GNUNET_DNSPARSER_TYPE_AAAA: + if (data_size != sizeof (struct in6_addr)) + return NULL; + if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof (tmp))) + return NULL; + return GNUNET_strdup (tmp); + case GNUNET_NAMESTORE_TYPE_PKEY: + if (data_size != sizeof (struct GNUNET_CRYPTO_ShortHashCode)) + return NULL; + GNUNET_CRYPTO_short_hash_to_enc (data, + &enc); + return GNUNET_strdup ((const char*) enc.short_encoding); + case GNUNET_NAMESTORE_TYPE_PSEU: + return GNUNET_strndup (data, data_size); + case GNUNET_NAMESTORE_TYPE_LEHO: + return GNUNET_strndup (data, data_size); + default: + GNUNET_break (0); + } + GNUNET_break (0); // not implemented + return NULL; +} + + +/** + * Convert human-readable version of a 'value' of a record to the binary + * representation. * - * @return number of elements deserialized + * @param type type of the record + * @param s human-readable string + * @param data set to value in binary encoding (will be allocated) + * @param data_size set to number of bytes in data + * @return GNUNET_OK on success */ int -GNUNET_NAMESTORE_records_deserialize ( struct GNUNET_NAMESTORE_RecordData **dest, char *src, size_t len) +GNUNET_NAMESTORE_string_to_value (uint32_t type, + const char *s, + void **data, + size_t *data_size) { - struct GNUNET_NAMESTORE_NetworkRecord * nr; - struct GNUNET_NAMESTORE_RecordData *d = (*dest); - int elements; - size_t offset; - uint32_t data_size; - int c; - - offset = 0; - elements = 0; - while (offset < len) + struct in_addr value_a; + struct in6_addr value_aaaa; + struct GNUNET_CRYPTO_ShortHashCode pkey; + uint16_t mx_pref; + uint16_t mx_pref_n; + uint32_t soa_data[5]; + char result[253]; + char soa_rname[63]; + char soa_mname[63]; + uint32_t soa_serial; + uint32_t soa_refresh; + uint32_t soa_retry; + uint32_t soa_expire; + uint32_t soa_min; + + switch (type) { - nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &src[offset]; - offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); + case 0: + return GNUNET_SYSERR; + case GNUNET_DNSPARSER_TYPE_A: + if (1 != inet_pton (AF_INET, s, &value_a)) + return GNUNET_SYSERR; + *data = GNUNET_malloc (sizeof (struct in_addr)); + memcpy (*data, &value_a, sizeof (value_a)); + *data_size = sizeof (value_a); + return GNUNET_OK; + case GNUNET_DNSPARSER_TYPE_NS: + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + case GNUNET_DNSPARSER_TYPE_CNAME: + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + case GNUNET_DNSPARSER_TYPE_SOA: + + if (SSCANF(s, "rname=%s mname=%s %u,%u,%u,%u,%u", + soa_rname, soa_mname, + &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min) + != 7) + return GNUNET_SYSERR; + + *data_size = sizeof (soa_data)+strlen(soa_rname)+strlen(soa_mname)+2; + *data = GNUNET_malloc (*data_size); + soa_data[0] = htonl(soa_serial); + soa_data[1] = htonl(soa_refresh); + soa_data[2] = htonl(soa_retry); + soa_data[3] = htonl(soa_expire); + soa_data[4] = htonl(soa_min); + strcpy(*data, soa_rname); + strcpy(*data+strlen(*data)+1, soa_mname); + memcpy(*data+strlen(*data)+1+strlen(soa_mname)+1, + soa_data, sizeof(soa_data)); + return GNUNET_OK; - data_size = ntohl (nr->data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Datasize record[%i]: %u\n", elements, data_size); - offset += data_size; - elements ++; + case GNUNET_DNSPARSER_TYPE_PTR: + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + case GNUNET_DNSPARSER_TYPE_MX: + if (SSCANF(s, "%hu,%s", &mx_pref, result) != 2) + return GNUNET_SYSERR; + *data_size = sizeof (uint16_t)+strlen(result)+1; + *data = GNUNET_malloc (*data_size); + mx_pref_n = htons(mx_pref); + memcpy(*data, &mx_pref_n, sizeof (uint16_t)); + strcpy((*data)+sizeof (uint16_t), result); + return GNUNET_OK; + case GNUNET_DNSPARSER_TYPE_TXT: + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + case GNUNET_DNSPARSER_TYPE_AAAA: + if (1 != inet_pton (AF_INET6, s, &value_aaaa)) + return GNUNET_SYSERR; + *data = GNUNET_malloc (sizeof (struct in6_addr)); + *data_size = sizeof (struct in6_addr); + memcpy (*data, &value_aaaa, sizeof (value_aaaa)); + return GNUNET_OK; + case GNUNET_NAMESTORE_TYPE_PKEY: + if (GNUNET_OK != + GNUNET_CRYPTO_short_hash_from_string (s, &pkey)) + return GNUNET_SYSERR; + *data = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode)); + memcpy (*data, &pkey, sizeof (pkey)); + *data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode); + return GNUNET_OK; + case GNUNET_NAMESTORE_TYPE_PSEU: + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + case GNUNET_NAMESTORE_TYPE_LEHO: + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + default: + GNUNET_break (0); } + return GNUNET_SYSERR; +} - GNUNET_assert (len == offset); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserializing %i records with total length of %u\n", elements, len); - (*dest) = GNUNET_malloc (elements * sizeof (struct GNUNET_NAMESTORE_RecordData)); - d = (*dest); +static struct { + const char *name; + uint32_t number; +} name_map[] = { + { "A", GNUNET_DNSPARSER_TYPE_A }, + { "NS", GNUNET_DNSPARSER_TYPE_NS }, + { "CNAME", GNUNET_DNSPARSER_TYPE_CNAME }, + { "SOA", GNUNET_DNSPARSER_TYPE_SOA }, + { "PTR", GNUNET_DNSPARSER_TYPE_PTR }, + { "MX", GNUNET_DNSPARSER_TYPE_MX }, + { "TXT", GNUNET_DNSPARSER_TYPE_TXT }, + { "AAAA", GNUNET_DNSPARSER_TYPE_AAAA }, + { "PKEY", GNUNET_NAMESTORE_TYPE_PKEY }, + { "PSEU", GNUNET_NAMESTORE_TYPE_PSEU }, + { "LEHO", GNUNET_NAMESTORE_TYPE_LEHO }, + { NULL, UINT32_MAX } +}; - offset = 0; - for (c = 0; c < elements; c++) - { - nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &src[offset]; - d[c].expiration = GNUNET_TIME_absolute_ntoh(nr->expiration); - d[c].record_type = ntohl (nr->record_type); - d[c].flags = ntohl (nr->flags); - d[c].data_size = ntohl (nr->data_size); - d[c].data = GNUNET_malloc (d[c].data_size); - GNUNET_assert (d[c].data != NULL); - - offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); - memcpy((char *) d[c].data, &src[offset], d[c].data_size); - - offset += d[c].data_size; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserialized record[%i] /w data_size %i\n", c, d[c].data_size); - } - GNUNET_assert(offset == len); - return elements; +/** + * Convert a type name (i.e. "AAAA") to the corresponding number. + * + * @param typename name to convert + * @return corresponding number, UINT32_MAX on error + */ +uint32_t +GNUNET_NAMESTORE_typename_to_number (const char *typename) +{ + unsigned int i; + + i=0; + while ( (name_map[i].name != NULL) && + (0 != strcasecmp (typename, name_map[i].name)) ) + i++; + return name_map[i].number; +} + + +/** + * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A") + * + * @param type number of a type to convert + * @return corresponding typestring, NULL on error + */ +const char * +GNUNET_NAMESTORE_number_to_typename (uint32_t type) +{ + unsigned int i; + + i=0; + while ( (name_map[i].name != NULL) && + (type != name_map[i].number) ) + i++; + return name_map[i].name; } -/* end of namestore_api.c */ + + +/* end of namestore_common.c */ diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index c297216..f685887 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c @@ -26,6 +26,8 @@ #include "platform.h" #include "gnunet_namestore_plugin.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" #include /** @@ -100,39 +102,15 @@ struct Plugin sqlite3_stmt *iterate_records; /** - * Precompiled SQL for delete zone + * Precompiled SQL to get the name for a given zone-value. */ - sqlite3_stmt *delete_zone; - -}; - - -/** - * Internal format of a record in the BLOB in the database. - */ -struct DbRecord -{ + sqlite3_stmt *zone_to_name; /** - * Expiration time for the DNS record. - */ - struct GNUNET_TIME_AbsoluteNBO expiration; - - /** - * Number of bytes in 'data', network byte order. - */ - uint32_t data_size; - - /** - * Type of the GNS/DNS record, network byte order. + * Precompiled SQL for delete zone */ - uint32_t record_type; + sqlite3_stmt *delete_zone; - /** - * Flags for the record, network byte order. - */ - uint32_t flags; - }; @@ -169,19 +147,22 @@ create_indices (sqlite3 * dbh) { /* create indices */ if ( (SQLITE_OK != - sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON ns090records (zone_hash,record_name_hash,rvalue)", + sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON ns091records (zone_hash,record_name_hash,rvalue)", + NULL, NULL, NULL)) || + (SQLITE_OK != + sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_delegation ON ns091records (zone_hash,zone_delegation)", NULL, NULL, NULL)) || (SQLITE_OK != - sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON ns090records (zone_hash,rvalue)", + sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON ns091records (zone_hash,rvalue)", NULL, NULL, NULL)) || (SQLITE_OK != - sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns090records (zone_hash)", + sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns091records (zone_hash)", NULL, NULL, NULL)) || (SQLITE_OK != - sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON ns090records (record_name_hash,rvalue)", + sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON ns091records (record_name_hash,rvalue)", NULL, NULL, NULL)) || (SQLITE_OK != - sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns090records (rvalue)", + sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns091records (rvalue)", NULL, NULL, NULL)) ) LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create indices: %s\n", sqlite3_errmsg (dbh)); @@ -280,13 +261,14 @@ database_setup (struct Plugin *plugin) /* Create tables */ CHECK (SQLITE_OK == sq_prepare (plugin->dbh, - "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns090records'", + "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns091records'", &stmt)); if ((sqlite3_step (stmt) == SQLITE_DONE) && (sqlite3_exec (plugin->dbh, - "CREATE TABLE ns090records (" + "CREATE TABLE ns091records (" " zone_key BLOB NOT NULL DEFAULT ''," + " zone_delegation BLOB NOT NULL DEFAULT ''," " zone_hash BLOB NOT NULL DEFAULT ''," " record_count INT NOT NULL DEFAULT 0," " record_data BLOB NOT NULL DEFAULT ''," @@ -309,36 +291,41 @@ database_setup (struct Plugin *plugin) #define ALL "zone_key, record_name, record_count, record_data, block_expiration_time, signature" if ((sq_prepare (plugin->dbh, - "INSERT INTO ns090records (" ALL ", zone_hash, record_name_hash, rvalue) VALUES " - "(?, ?, ?, ?, ?, ?, ?, ?, ?)", + "INSERT INTO ns091records (" ALL ", zone_delegation, zone_hash, record_name_hash, rvalue) VALUES " + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", &plugin->put_records) != SQLITE_OK) || (sq_prepare (plugin->dbh, - "DELETE FROM ns090records WHERE zone_hash=? AND record_name_hash=?", + "DELETE FROM ns091records WHERE zone_hash=? AND record_name_hash=?", &plugin->remove_records) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT " ALL - " FROM ns090records WHERE zone_hash=? AND record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", + " FROM ns091records WHERE zone_hash=? AND record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", &plugin->iterate_records) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT " ALL - " FROM ns090records WHERE zone_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", + " FROM ns091records WHERE zone_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", &plugin->iterate_by_zone) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT " ALL - " FROM ns090records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", + " FROM ns091records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", &plugin->iterate_by_name) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT " ALL - " FROM ns090records ORDER BY rvalue LIMIT 1 OFFSET ?", + " FROM ns091records ORDER BY rvalue LIMIT 1 OFFSET ?", &plugin->iterate_all) != SQLITE_OK) || + (sq_prepare + (plugin->dbh, + "SELECT " ALL + " FROM ns091records WHERE zone_hash=? AND zone_delegation=?", + &plugin->zone_to_name) != SQLITE_OK) || (sq_prepare (plugin->dbh, - "DELETE FROM ns090records WHERE zone_hash=?", + "DELETE FROM ns091records WHERE zone_hash=?", &plugin->delete_zone) != SQLITE_OK) ) { LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling"); @@ -366,12 +353,14 @@ database_shutdown (struct Plugin *plugin) sqlite3_finalize (plugin->remove_records); if (NULL != plugin->iterate_records) sqlite3_finalize (plugin->iterate_records); - if (NULL != plugin->iterate_records) + if (NULL != plugin->iterate_by_zone) sqlite3_finalize (plugin->iterate_by_zone); - if (NULL != plugin->iterate_records) + if (NULL != plugin->iterate_by_name) sqlite3_finalize (plugin->iterate_by_name); - if (NULL != plugin->iterate_records) + if (NULL != plugin->iterate_all) sqlite3_finalize (plugin->iterate_all); + if (NULL != plugin->zone_to_name) + sqlite3_finalize (plugin->zone_to_name); if (NULL != plugin->delete_zone) sqlite3_finalize (plugin->delete_zone); result = sqlite3_close (plugin->dbh); @@ -409,19 +398,18 @@ database_shutdown (struct Plugin *plugin) */ static int namestore_sqlite_remove_records (void *cls, - const GNUNET_HashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *zone, const char *name) { struct Plugin *plugin = cls; - GNUNET_HashCode nh; + struct GNUNET_CRYPTO_ShortHashCode nh; size_t name_len; int n; - name_len = strlen (name); - GNUNET_CRYPTO_hash (name, name_len, &nh); + GNUNET_CRYPTO_short_hash (name, name_len, &nh); - if ((SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || - (SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 2, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC))) + if ((SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 1, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) || + (SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 2, &nh, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC))) { LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind_XXXX"); @@ -478,22 +466,30 @@ namestore_sqlite_put_records (void *cls, { struct Plugin *plugin = cls; int n; - GNUNET_HashCode zone; - GNUNET_HashCode nh; + struct GNUNET_CRYPTO_ShortHashCode zone; + struct GNUNET_CRYPTO_ShortHashCode zone_delegation; + struct GNUNET_CRYPTO_ShortHashCode nh; size_t name_len; uint64_t rvalue; size_t data_size; - size_t off; unsigned int i; - GNUNET_CRYPTO_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone); + GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone); (void) namestore_sqlite_remove_records (plugin, &zone, name); name_len = strlen (name); - GNUNET_CRYPTO_hash (name, name_len, &nh); + GNUNET_CRYPTO_short_hash (name, name_len, &nh); + memset (&zone_delegation, 0, sizeof (zone_delegation)); + for (i=0;i 64 * 65536) { GNUNET_break (0); @@ -501,20 +497,12 @@ namestore_sqlite_put_records (void *cls, } { char data[data_size]; - struct DbRecord *rec; - - rec = (struct DbRecord *) data; - off = rd_count * sizeof (struct DbRecord); - for (i=0;iput_records, 1, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), SQLITE_STATIC)) || (SQLITE_OK != sqlite3_bind_text (plugin->put_records, 2, name, -1, SQLITE_STATIC)) || @@ -522,9 +510,10 @@ namestore_sqlite_put_records (void *cls, (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 4, data, data_size, SQLITE_STATIC)) || (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 5, expire.abs_value)) || (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 6, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature), SQLITE_STATIC)) || - (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || - (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || - (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 9, rvalue)) ) + (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone_delegation, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) || + (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) || + (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 9, &nh, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) || + (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 10, rvalue)) ) { LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, @@ -556,6 +545,83 @@ namestore_sqlite_put_records (void *cls, return GNUNET_SYSERR; } } + + +/** + * The given 'sqlite' statement has been prepared to be run. + * It will return a record which should be given to the iterator. + * Runs the statement and parses the returned record. + * + * @param plugin plugin context + * @param stmt to run (and then clean up) + * @param iter iterator to call with the result + * @param iter_cls closure for 'iter' + * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error + */ +static int +get_record_and_call_iterator (struct Plugin *plugin, + sqlite3_stmt *stmt, + GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) +{ + int ret; + int sret; + unsigned int record_count; + size_t data_size; + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; + const struct GNUNET_CRYPTO_RsaSignature *sig; + struct GNUNET_TIME_Absolute expiration; + const char *data; + const char *name; + + ret = GNUNET_NO; + if (SQLITE_ROW == (sret = sqlite3_step (stmt))) + { + ret = GNUNET_YES; + zone_key = sqlite3_column_blob (stmt, 0); + name = (const char*) sqlite3_column_text (stmt, 1); + record_count = sqlite3_column_int (stmt, 2); + data_size = sqlite3_column_bytes (stmt, 3); + data = sqlite3_column_blob (stmt, 3); + expiration.abs_value = (uint64_t) sqlite3_column_int64 (stmt, 4); + sig = sqlite3_column_blob (stmt, 5); + + if ( (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) != sqlite3_column_bytes (stmt, 0)) || + (sizeof (struct GNUNET_CRYPTO_RsaSignature) != sqlite3_column_bytes (stmt, 5)) ) + { + GNUNET_break (0); + ret = GNUNET_SYSERR; + } + else + { + struct GNUNET_NAMESTORE_RecordData rd[record_count]; + + if (GNUNET_OK != + GNUNET_NAMESTORE_records_deserialize (data_size, data, + record_count, rd)) + { + GNUNET_break (0); + ret = GNUNET_SYSERR; + record_count = 0; + } + else + { + iter (iter_cls, zone_key, expiration, name, + record_count, rd, sig); + } + } + } + else + { + if (SQLITE_DONE != sret) + LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); + iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); + } + if (SQLITE_OK != sqlite3_reset (stmt)) + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "sqlite3_reset"); + return ret; +} /** @@ -564,7 +630,7 @@ namestore_sqlite_put_records (void *cls, * * @param cls closure (internal context for the plugin) * @param zone hash of public key of the zone, NULL to iterate over all zones - * @param name_hash hash of name, NULL to iterate over all records of the zone + * @param name name as string, NULL to iterate over all records of the zone * @param offset offset in the list of all matching records * @param iter function to call with the result * @param iter_cls closure for iter @@ -572,32 +638,37 @@ namestore_sqlite_put_records (void *cls, */ static int namestore_sqlite_iterate_records (void *cls, - const GNUNET_HashCode *zone, - const GNUNET_HashCode *name_hash, + const struct GNUNET_CRYPTO_ShortHashCode *zone, + const char *name, uint64_t offset, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) { struct Plugin *plugin = cls; sqlite3_stmt *stmt; + struct GNUNET_CRYPTO_ShortHashCode name_hase; unsigned int boff; - int ret; - int sret; if (NULL == zone) - if (NULL == name_hash) + if (NULL == name) stmt = plugin->iterate_all; else + { + GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase); stmt = plugin->iterate_by_name; + } else - if (NULL == name_hash) + if (NULL == name) stmt = plugin->iterate_by_zone; else + { + GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase); stmt = plugin->iterate_records; + } boff = 0; if ( (NULL != zone) && (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, - zone, sizeof (GNUNET_HashCode), + zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ) { LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, @@ -608,11 +679,12 @@ namestore_sqlite_iterate_records (void *cls, "sqlite3_reset"); return GNUNET_SYSERR; } - if ( (NULL != name_hash) && + if ( (NULL != name) && (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, - name_hash, sizeof (GNUNET_HashCode), + &name_hase, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ITERATE NAME HASH: `%8s'", GNUNET_short_h2s(&name_hase)); LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind_XXXX"); if (SQLITE_OK != sqlite3_reset (stmt)) @@ -633,72 +705,49 @@ namestore_sqlite_iterate_records (void *cls, "sqlite3_reset"); return GNUNET_SYSERR; } - ret = GNUNET_NO; - if (SQLITE_ROW == (sret = sqlite3_step (stmt))) - { - unsigned int record_count; - size_t data_size; - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; - const struct GNUNET_CRYPTO_RsaSignature *sig; - struct GNUNET_TIME_Absolute expiration; - const char *data; - const char *name; - - ret = GNUNET_YES; - zone_key = sqlite3_column_blob (stmt, 0); - name = (const char*) sqlite3_column_text (stmt, 1); - record_count = sqlite3_column_int (stmt, 2); - data_size = sqlite3_column_bytes (stmt, 3); - data = sqlite3_column_blob (stmt, 3); - expiration.abs_value = (uint64_t) sqlite3_column_int64 (stmt, 4); - sig = sqlite3_column_blob (stmt, 5); - if ( (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) != sqlite3_column_bytes (stmt, 0)) || - (sizeof (struct GNUNET_CRYPTO_RsaSignature) != sqlite3_column_bytes (stmt, 5)) || - (sizeof (struct DbRecord) * record_count > data_size) ) - { - GNUNET_break (0); - ret = GNUNET_SYSERR; - } - else - { - const struct DbRecord *db = (const struct DbRecord*) data; - struct GNUNET_NAMESTORE_RecordData rd[record_count]; - unsigned int i; - size_t off; + return get_record_and_call_iterator (plugin, stmt, iter, iter_cls); +} - off = record_count * sizeof (struct DbRecord); - for (i=0;i data_size) - { - GNUNET_break (0); - ret = GNUNET_SYSERR; - record_count = i; - break; - } - rd[i].expiration = GNUNET_TIME_absolute_ntoh (db[i].expiration); - rd[i].data_size = ntohl (db[i].data_size); - rd[i].data = &data[off]; - rd[i].record_type = ntohl (db[i].record_type); - rd[i].flags = ntohl (db[i].flags); - off += rd[i].data_size; - } - iter (iter_cls, zone_key, expiration, name, - record_count, rd, sig); - } - } - else + +/** + * Look for an existing PKEY delegation record for a given public key. + * Returns at most one result to the iterator. + * + * @param cls closure (internal context for the plugin) + * @param zone hash of public key of the zone to look up in, never NULL + * @param value_zone hash of the public key of the target zone (value), never NULL + * @param iter function to call with the result + * @param iter_cls closure for iter + * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error + */ +static int +namestore_sqlite_zone_to_name (void *cls, + const struct GNUNET_CRYPTO_ShortHashCode *zone, + const struct GNUNET_CRYPTO_ShortHashCode *value_zone, + GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) +{ + struct Plugin *plugin = cls; + sqlite3_stmt *stmt; + + stmt = plugin->zone_to_name; + if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1, + zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), + SQLITE_STATIC)) || + (SQLITE_OK != sqlite3_bind_blob (stmt, 2, + value_zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), + SQLITE_STATIC)) ) { - if (SQLITE_DONE != sret) - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); - iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); - } - if (SQLITE_OK != sqlite3_reset (stmt)) - LOG_SQLITE (plugin, - GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "sqlite3_reset"); - return ret; + LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "sqlite3_bind_XXXX"); + if (SQLITE_OK != sqlite3_reset (stmt)) + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "sqlite3_reset"); + return GNUNET_SYSERR; + } + + return get_record_and_call_iterator (plugin, stmt, iter, iter_cls); } @@ -710,13 +759,13 @@ namestore_sqlite_iterate_records (void *cls, */ static void namestore_sqlite_delete_zone (void *cls, - const GNUNET_HashCode *zone) + const struct GNUNET_CRYPTO_ShortHashCode *zone) { struct Plugin *plugin = cls; sqlite3_stmt *stmt = plugin->delete_zone; int n; - if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) + if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) { LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind_XXXX"); @@ -774,6 +823,7 @@ libgnunet_plugin_namestore_sqlite_init (void *cls) api->put_records = &namestore_sqlite_put_records; api->remove_records = &namestore_sqlite_remove_records; api->iterate_records = &namestore_sqlite_iterate_records; + api->zone_to_name = &namestore_sqlite_zone_to_name; api->delete_zone = &namestore_sqlite_delete_zone; LOG (GNUNET_ERROR_TYPE_INFO, _("Sqlite database running\n")); diff --git a/src/namestore/test_hostkey b/src/namestore/test_hostkey new file mode 100644 index 0000000..2ffb55f Binary files /dev/null and b/src/namestore/test_hostkey differ diff --git a/src/namestore/test_namestore_api.c b/src/namestore/test_namestore_api.c index ebd8be3..039f1b9 100644 --- a/src/namestore/test_namestore_api.c +++ b/src/namestore/test_namestore_api.c @@ -36,7 +36,7 @@ static struct GNUNET_OS_Process *arm; static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; -static GNUNET_HashCode zone; +static struct GNUNET_CRYPTO_ShortHashCode zone; static int res; @@ -66,7 +66,7 @@ stop_arm () if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (arm); - GNUNET_OS_process_close (arm); + GNUNET_OS_process_destroy (arm); arm = NULL; } } @@ -142,20 +142,45 @@ void put_cont (void *cls, int32_t success, const char *emsg) GNUNET_NAMESTORE_lookup_record (nsh, &zone, name, 0, &name_lookup_proc, NULL); } +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { + delete_existing_db(cfg); endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); - privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey"); + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); GNUNET_assert (privkey != NULL); GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &zone); + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (pubkey), &zone); struct GNUNET_CRYPTO_RsaSignature signature; + memset (&signature, '\0', sizeof (signature)); struct GNUNET_NAMESTORE_RecordData rd; rd.expiration = GNUNET_TIME_absolute_get(); @@ -172,7 +197,7 @@ run (void *cls, char *const *args, const char *cfgfile, GNUNET_break (NULL != nsh); GNUNET_NAMESTORE_record_put (nsh, &pubkey, name, - GNUNET_TIME_absolute_get_forever(), + GNUNET_TIME_UNIT_FOREVER_ABS, 1, &rd, &signature, put_cont, name); GNUNET_free ((void *)rd.data); diff --git a/src/namestore/test_namestore_api.conf b/src/namestore/test_namestore_api.conf index 1b83e8f..33e07a4 100644 --- a/src/namestore/test_namestore_api.conf +++ b/src/namestore/test_namestore_api.conf @@ -4,12 +4,12 @@ DEFAULTSERVICES = namestore UNIXPATH = /tmp/gnunet-p1-service-arm.sock [namestore] -#PREFIX = valgrind --leak-check=full +#PREFIX = valgrind --leak-check=full --track-origins=yes AUTOSTART = YES UNIXPATH = /tmp/gnunet-service-namestore.sock UNIX_MATCH_UID = YES UNIX_MATCH_GID = YES -# PORT = 2099 +PORT = 2099 HOSTNAME = localhost HOME = $SERVICEHOME CONFIG = $DEFAULTCONFIG @@ -17,9 +17,10 @@ BINARY = gnunet-service-namestore ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; DATABASE = sqlite +ZONEFILE_DIRECTORY = zonefiles [namestore-sqlite] -FILENAME = $SERVICEHOME/namestore/sqlite.db +FILENAME = $SERVICEHOME/namestore/sqlite_test.db [namestore-postgres] CONFIG = connect_timeout=10; dbname=gnunet diff --git a/src/namestore/test_namestore_api_create.c b/src/namestore/test_namestore_api_create.c new file mode 100644 index 0000000..131c934 --- /dev/null +++ b/src/namestore/test_namestore_api_create.c @@ -0,0 +1,478 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 1 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_CREATE_RECORD_TYPE 4321 +#define TEST_CREATE_RECORD_DATALEN 255 +#define TEST_CREATE_RECORD_DATA 'b' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature *s_signature; +struct GNUNET_CRYPTO_RsaSignature *s_signature_updated; +static struct GNUNET_CRYPTO_ShortHashCode s_zone; +struct GNUNET_NAMESTORE_RecordData *s_first_record; +struct GNUNET_NAMESTORE_RecordData *s_second_record; +static char *s_name; + + + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_free ((void *) s_first_record->data); + GNUNET_free (s_first_record); + GNUNET_free_non_null (s_second_record); + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void name_lookup_second_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + static int found = GNUNET_NO; + int failed = GNUNET_NO; + int c; + + if (n != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n"); + if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != strcmp(n, s_name)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (2 != rd_count) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + for (c = 0; c < rd_count; c++) + { + if ((GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], s_first_record)) && + (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], s_second_record))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + } + + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(zone_key, expire, n, rd_count, rd, signature)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, n, rd_count, rd, signature)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + struct GNUNET_NAMESTORE_RecordData rd_new[2]; + rd_new[0] = *s_first_record; + rd_new[1] = *s_second_record; + s_signature_updated = GNUNET_NAMESTORE_create_signature(privkey, expire, s_name, rd_new, 2); + + if (0 != memcmp (s_signature_updated, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + found = GNUNET_YES; + if (failed == GNUNET_NO) + res = 0; + else + res = 1; + } + else + { + if (found != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name); + res = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name); + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + + +void +create_second_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Create second record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_second_proc, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } + +} + +void name_lookup_initial_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + char * name = cls; + static int found = GNUNET_NO; + int failed = GNUNET_NO; + int c; + + if (n != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n"); + if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != strcmp(n, s_name)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (RECORDS != rd_count) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + for (c = 0; c < RECORDS; c++) + { + if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], &s_first_record[c])) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + } + + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire,n, rd_count, rd, signature)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != memcmp (s_signature, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + found = GNUNET_YES; + if (failed == GNUNET_NO) + res = 0; + else + res = 1; + + /* create a second record */ + s_second_record = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_RecordData) + TEST_CREATE_RECORD_DATALEN); + s_second_record->expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + s_second_record->record_type = TEST_CREATE_RECORD_TYPE; + s_second_record->flags = GNUNET_NAMESTORE_RF_AUTHORITY; + s_second_record->data = &s_second_record[1]; + s_second_record->data_size = TEST_CREATE_RECORD_DATALEN; + memset ((char *) s_second_record->data, TEST_CREATE_RECORD_DATA, TEST_CREATE_RECORD_DATALEN); + + GNUNET_NAMESTORE_record_create (nsh, privkey, name, s_second_record, &create_second_cont, name); + + } + else + { + if (found != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name); + res = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name); + GNUNET_SCHEDULER_add_now (&end, NULL); + } +} + +void +create_first_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Create record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + /* check if record was created correct */ + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_initial_proc, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } + +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < count; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + size_t rd_ser_len; + + /* load privat key */ + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_first_record = create_record (1); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(1, s_first_record); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(1, s_first_record, rd_ser_len, rd_ser); + + s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_first_record->expiration, s_name, s_first_record, 1); + + /* create random zone hash */ + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone)); + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + GNUNET_break (s_first_record != NULL); + GNUNET_break (s_name != NULL); + + /* create initial record */ + GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_first_cont, s_name); +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + GNUNET_free (s_signature); + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_create_update.c b/src/namestore/test_namestore_api_create_update.c new file mode 100644 index 0000000..93570e4 --- /dev/null +++ b/src/namestore/test_namestore_api_create_update.c @@ -0,0 +1,517 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c for updating an existing record + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 1 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_CREATE_RECORD_TYPE 4321 +#define TEST_CREATE_RECORD_DATALEN 255 +#define TEST_CREATE_RECORD_DATA 'b' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature *s_signature; +struct GNUNET_CRYPTO_RsaSignature *s_signature_updated; +static struct GNUNET_CRYPTO_ShortHashCode s_zone; +struct GNUNET_NAMESTORE_RecordData *s_first_record; +struct GNUNET_NAMESTORE_RecordData *s_second_record; +static char *s_name; + + + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_free ((void *) s_first_record->data); + GNUNET_free (s_first_record); + GNUNET_free_non_null (s_second_record); + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void name_lookup_second_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + static int found = GNUNET_NO; + int failed = GNUNET_NO; + int c; + + if (n != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n"); + if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != strcmp(n, s_name)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (2 != rd_count) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + for (c = 0; c < rd_count; c++) + { + if ((GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], s_first_record)) && + (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], s_second_record))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + } + + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, n, rd_count, rd, signature)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + struct GNUNET_NAMESTORE_RecordData rd_new[2]; + rd_new[0] = *s_first_record; + rd_new[1] = *s_second_record; + s_signature_updated = GNUNET_NAMESTORE_create_signature(privkey, expire, s_name, rd_new, 2); + + if (0 != memcmp (s_signature_updated, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + found = GNUNET_YES; + if (failed == GNUNET_NO) + res = 0; + else + res = 1; + } + else + { + if (found != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name); + res = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name); + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + + +void +create_second_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Create second record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_second_proc, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } + +} + +void name_lookup_initial_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + char * name = cls; + static int found = GNUNET_NO; + int failed = GNUNET_NO; + int c; + + if (n != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n"); + if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != strcmp(n, s_name)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (RECORDS != rd_count) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + for (c = 0; c < RECORDS; c++) + { + if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], &s_first_record[c])) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + } + + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, n, rd_count, rd, signature)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != memcmp (s_signature, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + found = GNUNET_YES; + if (failed == GNUNET_NO) + res = 0; + else + res = 1; + + /* create a second record */ + s_second_record = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_RecordData) + TEST_CREATE_RECORD_DATALEN); + s_second_record->expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + s_second_record->record_type = TEST_CREATE_RECORD_TYPE; + s_second_record->flags = GNUNET_NAMESTORE_RF_AUTHORITY; + s_second_record->data = &s_second_record[1]; + s_second_record->data_size = TEST_CREATE_RECORD_DATALEN; + memset ((char *) s_second_record->data, TEST_CREATE_RECORD_DATA, TEST_CREATE_RECORD_DATALEN); + + GNUNET_NAMESTORE_record_create (nsh, privkey, name, s_second_record, &create_second_cont, name); + + } + else + { + if (found != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name); + res = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name); + GNUNET_SCHEDULER_add_now (&end, NULL); + } +} + + +void +create_updated_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating expiration for record `%s': %s `%s'\n", name, ((success == GNUNET_YES) || (success == GNUNET_NO)) ? "SUCCESS" : "FAIL", emsg); + if (success == GNUNET_NO) + { + res = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updated record for name `%s'\n", name); + } + else if (success == GNUNET_OK) + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "FAIL, Create new record for name `%s'\n", name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create records for name `%s'\n", name); + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + +void +create_identical_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating identical record for `%s': %s `%s'\n", name, ((success == GNUNET_YES) || (success == GNUNET_NO)) ? "SUCCESS" : "FAIL", emsg); + if (success == GNUNET_NO) + { + res = 0; + s_first_record->expiration = GNUNET_TIME_absolute_get (); + GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_updated_cont, s_name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating identical record for `%s': %s `%s'\n", name, ((success == GNUNET_YES) || (success == GNUNET_NO)) ? "SUCCESS" : "FAIL", emsg); + GNUNET_SCHEDULER_add_now(&end, NULL); + } + +} + +void +create_first_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Create record for `%s': %s `%s'\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL", emsg); + if (success == GNUNET_OK) + { + res = 0; + /* check if record was created correct */ + GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_identical_cont, s_name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } + +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s `%s'\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL", emsg); + if (success == GNUNET_OK) + { + + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < count; c++) + { + rd[c].expiration = GNUNET_TIME_UNIT_ZERO_ABS; + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + size_t rd_ser_len; + + /* load privat key */ + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_first_record = create_record (1); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(1, s_first_record); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(1, s_first_record, rd_ser_len, rd_ser); + + s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_first_record->expiration, s_name, s_first_record, 1); + + /* create random zone hash */ + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone)); + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + GNUNET_break (s_first_record != NULL); + GNUNET_break (s_name != NULL); + + /* create initial record */ + GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_first_cont, s_name); +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + GNUNET_free (s_signature); + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_lookup.c b/src/namestore/test_namestore_api_lookup.c new file mode 100644 index 0000000..818e710 --- /dev/null +++ b/src/namestore/test_namestore_api_lookup.c @@ -0,0 +1,317 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature *s_signature; +static struct GNUNET_CRYPTO_ShortHashCode s_zone; +struct GNUNET_NAMESTORE_RecordData *s_rd; +static char *s_name; + + + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + int c; + for (c = 0; c < RECORDS; c++) + GNUNET_free_non_null((void *) s_rd[c].data); + GNUNET_free (s_rd); + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void name_lookup_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + static int found = GNUNET_NO; + int c; + + if (n != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n"); + if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + { + GNUNET_break (0); + } + + if (0 != memcmp (signature, s_signature, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + GNUNET_break (0); + } + + if (0 != strcmp(n, s_name)) + { + GNUNET_break (0); + } + + if (RECORDS != rd_count) + { + GNUNET_break (0); + } + + for (c = 0; c < RECORDS; c++) + { + if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp (&rd[c], &s_rd[c])) + { + GNUNET_break (0); + } + } + found = GNUNET_YES; + res = 0; + } + else + { + if (found != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name); + res = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name); + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char * name = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_proc, NULL); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < RECORDS; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + + size_t rd_ser_len; + + /* load privat key from file not included in zonekey dir */ + privkey = GNUNET_CRYPTO_rsa_key_create_from_file("test_hostkey"); + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser); + + /* sign */ + s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[0].expiration, s_name, s_rd, RECORDS); + + /* create random zone hash */ + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + GNUNET_break (s_rd != NULL); + GNUNET_break (s_name != NULL); + + GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name, + GNUNET_TIME_UNIT_FOREVER_ABS, + RECORDS, s_rd, s_signature, put_cont, s_name); +} + + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + GNUNET_free (s_signature); + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_lookup_specific_type.c b/src/namestore/test_namestore_api_lookup_specific_type.c new file mode 100644 index 0000000..981e252 --- /dev/null +++ b/src/namestore/test_namestore_api_lookup_specific_type.c @@ -0,0 +1,399 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING 11111 +#define TEST_RECORD_LOOKUP_TYPE_EXISTING 22222 + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature *s_signature; +static struct GNUNET_CRYPTO_ShortHashCode s_zone; +struct GNUNET_NAMESTORE_RecordData *s_rd; +static char *s_name; + + + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + int c; + for (c = 0; c < RECORDS; c++) + { + GNUNET_free_non_null((void *) s_rd[c].data); + } + GNUNET_free (s_rd); + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + + +void name_lookup_existing_record_type (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + int failed = GNUNET_NO; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned %u records\n", rd_count); + + if ((NULL == n) || (0 != memcmp(zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + if ((NULL == n) || (0 != strcmp(n, s_name))) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + if (1 != rd_count) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + if (NULL == rd) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + if (NULL != signature) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + + if (failed == GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned invalid response\n"); + res = 1; + } + else + { + res = 0; + } + + GNUNET_SCHEDULER_add_now(&end, NULL); +} + + +void name_lookup_non_existing_record_type (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + int failed = GNUNET_NO; + /* We expect zone key != NULL, name != NULL, rd_count 0, rd NULL, signature NULL */ + if (NULL == zone_key) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + if (NULL == n) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name %s!\n", n); + GNUNET_break(0); + failed = GNUNET_YES; + } + if (0 != rd_count) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + if (NULL != rd) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + if (NULL != signature) + { + GNUNET_break(0); + failed = GNUNET_YES; + } + + if ((rd_count == 1) && (rd != NULL)) + { + if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(rd, &rd[RECORDS-1])) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Records are not equal!\n"); + failed = GNUNET_YES; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Records are equal!\n"); + } + } + + if (failed == GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned invalid response\n"); + res = 1; + + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned valid response\n"); + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, s_name, TEST_RECORD_LOOKUP_TYPE_EXISTING, &name_lookup_existing_record_type, NULL); + res = 0; + } +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char * name = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up non-existing record type %u for name `%s'\n", TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING, name); + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING, &name_lookup_non_existing_record_type, NULL); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < RECORDS-1; c++) + { + rd[c].expiration = GNUNET_TIME_UNIT_ZERO_ABS; + rd[c].record_type = 1; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_LOOKUP_TYPE_EXISTING; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + + + return rd; +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + + size_t rd_ser_len; + + /* load privat key */ + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser); + + /* sign */ + s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[RECORDS -1].expiration, s_name, s_rd, RECORDS); + + /* create random zone hash */ + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + GNUNET_break (s_rd != NULL); + GNUNET_break (s_name != NULL); + + GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name, + GNUNET_TIME_UNIT_FOREVER_ABS, + RECORDS, s_rd, s_signature, put_cont, s_name); + + + +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + GNUNET_free (s_signature); + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_put.c b/src/namestore/test_namestore_api_put.c new file mode 100644 index 0000000..9315fd3 --- /dev/null +++ b/src/namestore/test_namestore_api_put.c @@ -0,0 +1,249 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; + +struct GNUNET_NAMESTORE_RecordData *s_rd; + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char * name = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + res = 0; + else + res = 1; + + GNUNET_SCHEDULER_add_now(&end, NULL); +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < RECORDS; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + return rd; +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + + /* load privat key */ + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + struct GNUNET_CRYPTO_RsaSignature *signature; + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + /* create record */ + char * s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[0].expiration, s_name, s_rd, RECORDS); + + GNUNET_break (s_rd != NULL); + GNUNET_break (s_name != NULL); + + GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name, + GNUNET_TIME_UNIT_FOREVER_ABS, + RECORDS, s_rd, signature, put_cont, s_name); + + GNUNET_free (signature); + + int c; + for (c = 0; c < RECORDS; c++) + GNUNET_free_non_null((void *) s_rd[c].data); + GNUNET_free (s_rd); + +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_remove.c b/src/namestore/test_namestore_api_remove.c new file mode 100644 index 0000000..57bb4a8 --- /dev/null +++ b/src/namestore/test_namestore_api_remove.c @@ -0,0 +1,366 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_REMOVE_RECORD_TYPE 4321 +#define TEST_REMOVE_RECORD_DATALEN 255 +#define TEST_REMOVE_RECORD_DATA 'b' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature *s_signature; +static struct GNUNET_CRYPTO_ShortHashCode s_zone; +struct GNUNET_NAMESTORE_RecordData *s_rd; +static char *s_name; + + + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + int c; + for (c = 0; c < RECORDS; c++) + GNUNET_free_non_null((void *) s_rd[c].data); + GNUNET_free (s_rd); + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void name_lookup_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + static int found = GNUNET_NO; + int failed = GNUNET_NO; + int c; + + if (n != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup for name `%s' returned %u records\n", n, rd_count); + if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != strcmp(n, s_name)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (RECORDS-1 != rd_count) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + for (c = 0; c < rd_count; c++) + { + if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp (&rd[c], &s_rd[c+1])) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + } + + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, n, rd_count, rd, signature)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (failed == GNUNET_NO) + res = 0; + else + res = 1; + } + else + { + if (found != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name); + res = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name); + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + +void +remove_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Remove record for `%s': %s\n", name, (success == GNUNET_YES) ? "SUCCESS" : "FAIL", emsg); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_proc, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove record for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } + +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for `%s'\n", name); + + GNUNET_NAMESTORE_record_remove (nsh, privkey, name, &s_rd[0], &remove_cont, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + rd[0].expiration = GNUNET_TIME_absolute_get(); + rd[0].record_type = 0; + rd[0].data_size = TEST_REMOVE_RECORD_DATALEN; + rd[0].data = GNUNET_malloc(TEST_REMOVE_RECORD_DATALEN); + memset ((char *) rd[0].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + + for (c = 1; c < RECORDS; c++) + { + rd[c].expiration = GNUNET_TIME_UNIT_ZERO_ABS; + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + size_t rd_ser_len; + + /* load privat key */ + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser); + + /* sign */ + s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[0].expiration, s_name, s_rd, RECORDS); + + /* create random zone hash */ + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone)); + + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + GNUNET_break (s_rd != NULL); + GNUNET_break (s_name != NULL); + + GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name, + GNUNET_TIME_UNIT_FOREVER_ABS, + RECORDS, s_rd, s_signature, put_cont, s_name); + + + +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + GNUNET_free (s_signature); + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_remove_not_existing_record.c b/src/namestore/test_namestore_api_remove_not_existing_record.c new file mode 100644 index 0000000..8c32278 --- /dev/null +++ b/src/namestore/test_namestore_api_remove_not_existing_record.c @@ -0,0 +1,299 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_REMOVE_RECORD_TYPE 4321 +#define TEST_REMOVE_RECORD_DATALEN 255 +#define TEST_REMOVE_RECORD_DATA 'b' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature *s_signature; +static GNUNET_HashCode s_zone; +struct GNUNET_NAMESTORE_RecordData *s_rd; +static char *s_name; + + + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + int c; + for (c = 0; c < RECORDS; c++) + GNUNET_free_non_null((void *) s_rd[c].data); + GNUNET_free (s_rd); + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void +remove_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Remove record for `%s': %s `%s'\n", name, (success == GNUNET_YES) ? "SUCCESS" : "FAIL", emsg); + if (GNUNET_NO == success) + { + res = 0; + } + else + { + res = 1; + GNUNET_break (0); + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing non existing record for `%s'\n", name); + + struct GNUNET_NAMESTORE_RecordData rd; + char data[TEST_REMOVE_RECORD_DATALEN]; + rd.expiration = GNUNET_TIME_absolute_get(); + rd.record_type = TEST_REMOVE_RECORD_TYPE; + rd.data_size = TEST_REMOVE_RECORD_DATALEN; + rd.data = &data; + + GNUNET_NAMESTORE_record_remove (nsh, privkey, name, &rd, &remove_cont, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < RECORDS; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + size_t rd_ser_len; + + /* load privat key */ + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser); + + /* sign */ + s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_rd[0].expiration, s_name, s_rd, RECORDS); + + /* create random zone hash */ + GNUNET_CRYPTO_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_h2s_full(&s_zone)); + + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + GNUNET_break (s_rd != NULL); + GNUNET_break (s_name != NULL); + + GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name, + GNUNET_TIME_UNIT_FOREVER_ABS, + RECORDS, s_rd, s_signature, put_cont, s_name); + + +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + GNUNET_free (s_signature); + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_sign_verify.c b/src/namestore/test_namestore_api_sign_verify.c new file mode 100644 index 0000000..17bfb1e --- /dev/null +++ b/src/namestore/test_namestore_api_sign_verify.c @@ -0,0 +1,150 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api_sign_verify.c + * @brief testcase for signing and verifying + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_REMOVE_RECORD_TYPE 4321 +#define TEST_REMOVE_RECORD_DATALEN 255 +#define TEST_REMOVE_RECORD_DATA 'b' + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature s_signature; +struct GNUNET_NAMESTORE_RecordData *s_rd; +static char *s_name; + +static int res; + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < RECORDS; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_CRYPTO_RsaSignature * signature; + + /* load privat key */ + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey != NULL); + struct GNUNET_TIME_Absolute expire = GNUNET_TIME_absolute_get(); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + int res_c; + int res_w; + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + signature = GNUNET_NAMESTORE_create_signature (privkey, expire, s_name, s_rd, RECORDS); + GNUNET_assert (signature != NULL); + + res_c = GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name, RECORDS, s_rd, signature); + GNUNET_break (res == GNUNET_OK); + + GNUNET_free (signature); + + signature = GNUNET_NAMESTORE_create_signature (privkey, expire, s_name, s_rd, RECORDS); + GNUNET_break (signature != NULL); + + GNUNET_log_skip(1, GNUNET_NO); + res_w = GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name, RECORDS - 1, s_rd, signature); + GNUNET_break (res_w == GNUNET_SYSERR); + + GNUNET_free (signature); + + if ((res_c == GNUNET_OK) && (res_w == GNUNET_SYSERR)) + res = 0; + else + res = 1; + +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_namestore_api_sign_verify.c */ diff --git a/src/namestore/test_namestore_api_zone_iteration.c b/src/namestore/test_namestore_api_zone_iteration.c index c0ef8c8..0665541 100644 --- a/src/namestore/test_namestore_api_zone_iteration.c +++ b/src/namestore/test_namestore_api_zone_iteration.c @@ -19,11 +19,12 @@ */ /** * @file namestore/test_namestore_api_zone_iteration.c - * @brief testcase for namestore_api.c zone iteration functionality + * @brief testcase for zone iteration functionality: iterate of a specific zone */ #include "platform.h" #include "gnunet_common.h" #include "gnunet_namestore_service.h" +#include "namestore.h" #define VERBOSE GNUNET_NO @@ -39,8 +40,25 @@ static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; static GNUNET_HashCode zone; +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey2; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey2; +static GNUNET_HashCode zone2; + static struct GNUNET_NAMESTORE_ZoneIterator *zi; static int res; +static int returned_records; + +struct GNUNET_CRYPTO_RsaSignature *sig_1; +char * s_name_1; +struct GNUNET_NAMESTORE_RecordData *s_rd_1; + +struct GNUNET_CRYPTO_RsaSignature *sig_2; +char * s_name_2; +struct GNUNET_NAMESTORE_RecordData *s_rd_2; + +struct GNUNET_CRYPTO_RsaSignature *sig_3; +char * s_name_3; +struct GNUNET_NAMESTORE_RecordData *s_rd_3; static void start_arm (const char *cfgname) @@ -63,7 +81,7 @@ stop_arm () if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (arm); - GNUNET_OS_process_close (arm); + GNUNET_OS_process_destroy (arm); arm = NULL; } } @@ -87,10 +105,37 @@ endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); nsh = NULL; + GNUNET_free_non_null(sig_1); + GNUNET_free_non_null(sig_2); + GNUNET_free_non_null(sig_3); + GNUNET_free_non_null(s_name_1); + GNUNET_free_non_null(s_name_2); + GNUNET_free_non_null(s_name_3); + + if (s_rd_1 != NULL) + { + GNUNET_free ((void *)s_rd_1->data); + GNUNET_free (s_rd_1); + } + if (s_rd_2 != NULL) + { + GNUNET_free ((void *)s_rd_2->data); + GNUNET_free (s_rd_2); + } + if (s_rd_3 != NULL) + { + GNUNET_free ((void *)s_rd_3->data); + GNUNET_free (s_rd_3); + } + if (privkey != NULL) GNUNET_CRYPTO_rsa_key_free (privkey); privkey = NULL; + if (privkey2 != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey2); + privkey2 = NULL; + if (NULL != arm) stop_arm(); @@ -113,11 +158,36 @@ end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) endbadly_task = GNUNET_SCHEDULER_NO_TASK; } - if (privkey != NULL) GNUNET_CRYPTO_rsa_key_free (privkey); privkey = NULL; + if (privkey2 != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey2); + privkey2 = NULL; + + GNUNET_free (sig_1); + GNUNET_free (sig_2); + GNUNET_free (sig_3); + GNUNET_free (s_name_1); + GNUNET_free (s_name_2); + GNUNET_free (s_name_3); + if (s_rd_1 != NULL) + { + GNUNET_free ((void *)s_rd_1->data); + GNUNET_free (s_rd_1); + } + if (s_rd_2 != NULL) + { + GNUNET_free ((void *)s_rd_2->data); + GNUNET_free (s_rd_2); + } + if (s_rd_3 != NULL) + { + GNUNET_free ((void *)s_rd_3->data); + GNUNET_free (s_rd_3); + } + if (nsh != NULL) GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); nsh = NULL; @@ -125,19 +195,6 @@ end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (NULL != arm) stop_arm(); - - res = 0; -} - -static void -stop_iteration (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - stopiteration_task = GNUNET_SCHEDULER_NO_TASK; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping iteration for zone `%s'\n", GNUNET_h2s (&zone)); - GNUNET_NAMESTORE_zone_iteration_stop (zi); - - GNUNET_SCHEDULER_add_now (&end, NULL); } void zone_proc (void *cls, @@ -148,22 +205,226 @@ void zone_proc (void *cls, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for zone `%s'\n", GNUNET_h2s (&zone)); + int failed = GNUNET_NO; + if ((zone_key == NULL) && (name == NULL)) + { + GNUNET_break (3 == returned_records); + if (3 == returned_records) + res = 0; + else + res = 1; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received last result, iteration done after receing %u results\n",returned_records ); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + else + { + /* verify signature returned from name store */ + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature (zone_key, expire, name, rd_count, rd, signature)) + { + GNUNET_HashCode zone_key_hash; + GNUNET_CRYPTO_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Verifying signature for `%s' in zone `%s' with %u records and expiration %llu failed\n", name, GNUNET_h2s(&zone_key_hash), rd_count, expire.abs_value); + + failed = GNUNET_YES; + GNUNET_break (0); + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing results name %s \n", name); + if (0 == strcmp (name, s_name_1)) + { + if (rd_count == 1) + { + if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_1)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + failed = GNUNET_YES; + GNUNET_break (0); + } + if (0 != memcmp (signature, sig_1, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else if (0 == strcmp (name, s_name_2)) + { + if (rd_count == 1) + { + if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_2)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + failed = GNUNET_YES; + GNUNET_break (0); + } + if (0 != memcmp (signature, sig_2, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else if (0 == strcmp (name, s_name_3)) + { + if (rd_count == 1) + { + if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_3)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + failed = GNUNET_YES; + GNUNET_break (0); + } + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(zone_key, expire, name, rd_count, rd, signature)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + + if (0 != memcmp (signature, sig_3, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing result failed: got name `%s'\n", name); + res = 1; + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + + if (failed == GNUNET_NO) + { + returned_records ++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Telling namestore to send the next result\n"); + GNUNET_NAMESTORE_zone_iterator_next (zi); + } + else + { + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + } +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } - stopiteration_task = GNUNET_SCHEDULER_add_now (&stop_iteration, NULL); +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + static int c = 0; + + if (success == GNUNET_OK) + { + c++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records\n"); + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); + } + + if (c == 3) + { + res = 1; + returned_records = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over all zones \n"); + zi = GNUNET_NAMESTORE_zone_iteration_start(nsh, + NULL, + GNUNET_NAMESTORE_RF_NONE, + GNUNET_NAMESTORE_RF_NONE, + zone_proc, + &zone); + if (zi == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone iterator\n"); + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); + } + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < count; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = 1111; + rd[c].data_size = 50; + rd[c].data = GNUNET_malloc(50); + memset ((char *) rd[c].data, 'a', 50); + } + return rd; } static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { + delete_existing_db(cfg); endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,&endbadly, NULL); - privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey"); + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); GNUNET_assert (privkey != NULL); GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + GNUNET_CRYPTO_hash(&pubkey, sizeof (pubkey), &zone); + + + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey2 = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + + GNUNET_assert (privkey2 != NULL); + GNUNET_CRYPTO_rsa_key_get_public(privkey2, &pubkey2); + GNUNET_CRYPTO_hash(&pubkey2, sizeof (pubkey), &zone2); - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &zone); start_arm (cfgfile); GNUNET_assert (arm != NULL); @@ -171,18 +432,27 @@ run (void *cls, char *const *args, const char *cfgfile, nsh = GNUNET_NAMESTORE_connect (cfg); GNUNET_break (NULL != nsh); - zi = GNUNET_NAMESTORE_zone_iteration_start(nsh, - &zone, - GNUNET_NAMESTORE_RF_NONE, - GNUNET_NAMESTORE_RF_NONE, - zone_proc, - &zone); - if (zi == NULL) - { - GNUNET_break (0); - GNUNET_SCHEDULER_cancel (endbadly_task); - endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); - } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n"); + + GNUNET_asprintf(&s_name_1, "dummy1"); + s_rd_1 = create_record(1); + sig_1 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_1->expiration, s_name_1, s_rd_1, 1); + GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL); + + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); + GNUNET_asprintf(&s_name_2, "dummy2"); + s_rd_2 = create_record(1); + + sig_2 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_2->expiration, s_name_2, s_rd_2, 1); + GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); + /* name in different zone */ + GNUNET_asprintf(&s_name_3, "dummy3"); + s_rd_3 = create_record(1); + sig_3 = GNUNET_NAMESTORE_create_signature(privkey2, s_rd_3->expiration, s_name_3, s_rd_3, 1); + GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL); } static int diff --git a/src/namestore/test_namestore_api_zone_iteration_specific_zone.c b/src/namestore/test_namestore_api_zone_iteration_specific_zone.c new file mode 100644 index 0000000..b21c860 --- /dev/null +++ b/src/namestore/test_namestore_api_zone_iteration_specific_zone.c @@ -0,0 +1,451 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api_zone_iteration_specific_zone.c + * @brief testcase for zone iteration functionality: iterate of a specific zone + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" + +#define VERBOSE GNUNET_NO + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static GNUNET_SCHEDULER_TaskIdentifier stopiteration_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +static struct GNUNET_CRYPTO_ShortHashCode zone; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey2; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey2; +static struct GNUNET_CRYPTO_ShortHashCode zone2; + +static struct GNUNET_NAMESTORE_ZoneIterator *zi; +static int res; +static int returned_records; + +struct GNUNET_CRYPTO_RsaSignature *sig_1; +char * s_name_1; +struct GNUNET_NAMESTORE_RecordData *s_rd_1; + +struct GNUNET_CRYPTO_RsaSignature *sig_2; +char * s_name_2; +struct GNUNET_NAMESTORE_RecordData *s_rd_2; + +struct GNUNET_CRYPTO_RsaSignature *sig_3; +char * s_name_3; +struct GNUNET_NAMESTORE_RecordData *s_rd_3; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (stopiteration_task); + stopiteration_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + GNUNET_free_non_null(sig_1); + GNUNET_free_non_null(sig_2); + GNUNET_free_non_null(sig_3); + GNUNET_free_non_null(s_name_1); + GNUNET_free_non_null(s_name_2); + GNUNET_free_non_null(s_name_3); + + if (s_rd_1 != NULL) + { + GNUNET_free ((void *)s_rd_1->data); + GNUNET_free (s_rd_1); + } + if (s_rd_2 != NULL) + { + GNUNET_free ((void *)s_rd_2->data); + GNUNET_free (s_rd_2); + } + if (s_rd_3 != NULL) + { + GNUNET_free ((void *)s_rd_3->data); + GNUNET_free (s_rd_3); + } + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (privkey2 != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey2); + privkey2 = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (stopiteration_task); + stopiteration_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (privkey2 != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey2); + privkey2 = NULL; + + GNUNET_free (sig_1); + GNUNET_free (sig_2); + GNUNET_free (sig_3); + GNUNET_free (s_name_1); + GNUNET_free (s_name_2); + GNUNET_free (s_name_3); + if (s_rd_1 != NULL) + { + GNUNET_free ((void *)s_rd_1->data); + GNUNET_free (s_rd_1); + } + if (s_rd_2 != NULL) + { + GNUNET_free ((void *)s_rd_2->data); + GNUNET_free (s_rd_2); + } + if (s_rd_3 != NULL) + { + GNUNET_free ((void *)s_rd_3->data); + GNUNET_free (s_rd_3); + } + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + + if (NULL != arm) + stop_arm(); +} + +void zone_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + int failed = GNUNET_NO; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for zone `%s'\n", GNUNET_short_h2s (&zone)); + if ((zone_key == NULL) && (name == NULL)) + { + GNUNET_break (2 == returned_records); + if (2 == returned_records) + res = 0; + else + res = 1; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received last result, iteration done after %u records\n", returned_records); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing results name %s \n", name); + if (0 == strcmp (name, s_name_1)) + { + if (rd_count == 1) + { + if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_1)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + failed = GNUNET_YES; + GNUNET_break (0); + } + if (0 != memcmp (signature, sig_1, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else if (0 == strcmp (name, s_name_2)) + { + if (rd_count == 1) + { + if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_2)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + failed = GNUNET_YES; + GNUNET_break (0); + } + if (0 != memcmp (signature, sig_2, sizeof (struct GNUNET_CRYPTO_RsaSignature))) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing result failed: got name `%s'\n", name); + res = 1; + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + + if (failed == GNUNET_NO) + { + returned_records ++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Telling namestore to send the next result\n"); + GNUNET_NAMESTORE_zone_iterator_next (zi); + } + else + { + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + } +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + static int c = 0; + + if (success == GNUNET_OK) + { + c++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records\n"); + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); + } + + if (c == 3) + { + res = 1; + returned_records = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over zone `%s'\n", + GNUNET_short_h2s(&zone)); + zi = GNUNET_NAMESTORE_zone_iteration_start(nsh, + &zone, + GNUNET_NAMESTORE_RF_NONE, + GNUNET_NAMESTORE_RF_NONE, + zone_proc, + &zone); + if (zi == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone iterator\n"); + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); + } + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < count; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = 1111; + rd[c].data_size = 50; + rd[c].data = GNUNET_malloc(50); + memset ((char *) rd[c].data, 'a', 50); + } + return rd; +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,&endbadly, NULL); + + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey != NULL); + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (pubkey), &zone); + + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey2 = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey2 != NULL); + GNUNET_CRYPTO_rsa_key_get_public(privkey2, &pubkey2); + GNUNET_CRYPTO_short_hash (&pubkey2, sizeof (pubkey), &zone2); + + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n"); + + GNUNET_asprintf(&s_name_1, "dummy1"); + s_rd_1 = create_record(1); + sig_1 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_1[0].expiration ,s_name_1, s_rd_1, 1); + GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL); + + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); + GNUNET_asprintf(&s_name_2, "dummy2"); + s_rd_2 = create_record(1); + + sig_2 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_2[0].expiration, s_name_2, s_rd_2, 1); + GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); + /* name in different zone */ + GNUNET_asprintf(&s_name_3, "dummy3"); + s_rd_3 = create_record(1); + sig_3 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_3[0].expiration, s_name_3, s_rd_3, 1); + GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL); +} + +static int +check () +{ + static char *const argv[] = { "test_namestore_api_zone_iteration", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test_namestore_api_zone_iteration", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_namestore_api_zone_iteration_specific_zone.c */ diff --git a/src/namestore/test_namestore_api_zone_iteration_stop.c b/src/namestore/test_namestore_api_zone_iteration_stop.c new file mode 100644 index 0000000..9f62c73 --- /dev/null +++ b/src/namestore/test_namestore_api_zone_iteration_stop.c @@ -0,0 +1,501 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api_zone_iteration.c + * @brief testcase for zone iteration functionality: iterate of a specific zone + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" + +#define VERBOSE GNUNET_NO + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static GNUNET_SCHEDULER_TaskIdentifier stopiteration_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +static GNUNET_HashCode zone; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey2; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey2; +static GNUNET_HashCode zone2; + +static struct GNUNET_NAMESTORE_ZoneIterator *zi; +static int res; +static int returned_records; + +struct GNUNET_CRYPTO_RsaSignature *sig_1; +char * s_name_1; +struct GNUNET_NAMESTORE_RecordData *s_rd_1; + +struct GNUNET_CRYPTO_RsaSignature *sig_2; +char * s_name_2; +struct GNUNET_NAMESTORE_RecordData *s_rd_2; + +struct GNUNET_CRYPTO_RsaSignature *sig_3; +char * s_name_3; +struct GNUNET_NAMESTORE_RecordData *s_rd_3; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (stopiteration_task); + stopiteration_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + GNUNET_free_non_null(sig_1); + GNUNET_free_non_null(sig_2); + GNUNET_free_non_null(sig_3); + GNUNET_free_non_null(s_name_1); + GNUNET_free_non_null(s_name_2); + GNUNET_free_non_null(s_name_3); + + if (s_rd_1 != NULL) + { + GNUNET_free ((void *)s_rd_1->data); + GNUNET_free (s_rd_1); + } + if (s_rd_2 != NULL) + { + GNUNET_free ((void *)s_rd_2->data); + GNUNET_free (s_rd_2); + } + if (s_rd_3 != NULL) + { + GNUNET_free ((void *)s_rd_3->data); + GNUNET_free (s_rd_3); + } + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (privkey2 != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey2); + privkey2 = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (stopiteration_task); + stopiteration_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (privkey2 != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey2); + privkey2 = NULL; + + GNUNET_free (sig_1); + GNUNET_free (sig_2); + GNUNET_free (sig_3); + GNUNET_free (s_name_1); + GNUNET_free (s_name_2); + GNUNET_free (s_name_3); + if (s_rd_1 != NULL) + { + GNUNET_free ((void *)s_rd_1->data); + GNUNET_free (s_rd_1); + } + if (s_rd_2 != NULL) + { + GNUNET_free ((void *)s_rd_2->data); + GNUNET_free (s_rd_2); + } + if (s_rd_3 != NULL) + { + GNUNET_free ((void *)s_rd_3->data); + GNUNET_free (s_rd_3); + } + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); + if (returned_records == 1) + res = 0; + else + res = 1; + +} + +void zone_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + int failed = GNUNET_NO; + + if ((zone_key == NULL) && (name == NULL)) + { + GNUNET_break (3 == returned_records); + if (3 == returned_records) + res = 0; + else + res = 1; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received last result, iteration done after receing %u results\n",returned_records ); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + else + { + + /* verify signature returned from name store */ + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(zone_key, expire, name, rd_count, rd, signature)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing results name %s \n", name); + if (0 == strcmp (name, s_name_1)) + { /* name_1 */ + if (rd_count == 1) + { + if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_1)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + failed = GNUNET_YES; + GNUNET_break (0); + } + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name_1, 1, s_rd_1, signature)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else if (0 == strcmp (name, s_name_2)) + { /* name_2 */ + if (rd_count == 1) + { + if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_2)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + failed = GNUNET_YES; + GNUNET_break (0); + } + + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name_2, 1, s_rd_2, signature)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else if (0 == strcmp (name, s_name_3)) + { /* name_3 */ + if (rd_count == 1) + { + if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_3)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + failed = GNUNET_YES; + GNUNET_break (0); + } + if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey2, expire, s_name_3, 1, s_rd_3, signature)) + { + failed = GNUNET_YES; + GNUNET_break (0); + } + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing result failed: got name `%s'\n", name); + res = 1; + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + + if (failed == GNUNET_NO) + { + returned_records ++; + + if (1 == returned_records) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping zone iteration after %u received record \n",returned_records ); + GNUNET_NAMESTORE_zone_iteration_stop (zi); + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3), &end , NULL); + return; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Telling namestore to send the next result\n"); + GNUNET_NAMESTORE_zone_iterator_next (zi); + } + } + else + { + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&end, NULL); + } + } +} + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + static int c = 0; + + if (success == GNUNET_OK) + { + c++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records\n"); + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); + } + + if (c == 3) + { + res = 1; + returned_records = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over all zones \n"); + zi = GNUNET_NAMESTORE_zone_iteration_start(nsh, + NULL, + GNUNET_NAMESTORE_RF_NONE, + GNUNET_NAMESTORE_RF_NONE, + zone_proc, + &zone); + if (zi == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone iterator\n"); + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); + } + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < count; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = 1111; + rd[c].data_size = 50; + rd[c].data = GNUNET_malloc(50); + memset ((char *) rd[c].data, 'a', 50); + } + return rd; +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,&endbadly, NULL); + + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey != NULL); + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + GNUNET_CRYPTO_hash(&pubkey, sizeof (pubkey), &zone); + + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey2 = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey2 != NULL); + GNUNET_CRYPTO_rsa_key_get_public(privkey2, &pubkey2); + GNUNET_CRYPTO_hash(&pubkey2, sizeof (pubkey), &zone2); + + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n"); + + GNUNET_asprintf(&s_name_1, "dummy1"); + s_rd_1 = create_record(1); + sig_1 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_1[0].expiration, s_name_1, s_rd_1, 1); + GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL); + + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); + GNUNET_asprintf(&s_name_2, "dummy2"); + s_rd_2 = create_record(1); + + sig_2 = GNUNET_NAMESTORE_create_signature(privkey, s_rd_2[0].expiration, s_name_2, s_rd_2, 1); + GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); + /* name in different zone */ + GNUNET_asprintf(&s_name_3, "dummy3"); + s_rd_3 = create_record(1); + sig_3 = GNUNET_NAMESTORE_create_signature(privkey2, s_rd_3[0].expiration, s_name_3, s_rd_3, 1); + GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL); +} + +static int +check () +{ + static char *const argv[] = { "test_namestore_api_zone_iteration", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test_namestore_api_zone_iteration", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_namestore_api_zone_iteration.c */ diff --git a/src/namestore/test_namestore_api_zone_to_name.c b/src/namestore/test_namestore_api_zone_to_name.c new file mode 100644 index 0000000..6efbaf5 --- /dev/null +++ b/src/namestore/test_namestore_api_zone_to_name.c @@ -0,0 +1,288 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file namestore/test_namestore_api_zone_to_name.c + * @brief testcase for zone to name translation + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; + +struct GNUNET_TIME_Absolute expire; + +static struct GNUNET_CRYPTO_ShortHashCode s_zone; +static struct GNUNET_CRYPTO_ShortHashCode s_zone_value; + +char * s_name; + +struct GNUNET_NAMESTORE_RecordData *s_rd; +struct GNUNET_CRYPTO_RsaSignature *s_signature; + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_destroy (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void zone_to_name_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + int fail = GNUNET_NO; + + if ((zone_key == NULL) && (n == NULL) && (rd_count == 0) && (rd == NULL) && (signature == NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No result found\n"); + res = 1; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result found: `%s'\n", n); + if ((n == NULL) || (0 != strcmp(n, s_name))) + { + fail = GNUNET_YES; + GNUNET_break (0); + } + if (rd_count != 1) + { + fail = GNUNET_YES; + GNUNET_break (0); + } + if ((zone_key == NULL) || (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))) + { + fail = GNUNET_YES; + GNUNET_break (0); + } + if (fail == GNUNET_NO) + res = 0; + else + res = 1; + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + + +void +delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char *afsdir; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", + "FILENAME", &afsdir)) + { + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); + GNUNET_free (afsdir); + } + +} + + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + + /* create initial record */ + GNUNET_NAMESTORE_zone_to_name (nsh, &s_zone, &s_zone_value, zone_to_name_proc, NULL); + + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + delete_existing_db(cfg); + + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + GNUNET_asprintf(&s_name, "dummy"); + + + /* load privat key */ + char *hostkey_file; + GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, + "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file); + GNUNET_free (hostkey_file); + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* zone hash */ + GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + GNUNET_CRYPTO_short_hash (s_name, strlen (s_name) + 1, &s_zone_value); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using PKEY `%s' \n", GNUNET_short_h2s (&s_zone_value)); + + struct GNUNET_NAMESTORE_RecordData rd; + rd.expiration = GNUNET_TIME_absolute_get(); + rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY; + rd.data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode); + rd.data = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_ShortHashCode)); + memcpy ((char *) rd.data, &s_zone_value, sizeof (struct GNUNET_CRYPTO_ShortHashCode)); + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + expire = GNUNET_TIME_absolute_get (); + s_signature = GNUNET_NAMESTORE_create_signature(privkey, rd.expiration, s_name, &rd, 1); + GNUNET_NAMESTORE_record_put(nsh, &pubkey, s_name, expire, 1, &rd, s_signature, put_cont, NULL); + + GNUNET_free ((void *) rd.data); +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_record_serialization.c b/src/namestore/test_namestore_record_serialization.c index 5ea345b..5e95253 100644 --- a/src/namestore/test_namestore_record_serialization.c +++ b/src/namestore/test_namestore_record_serialization.c @@ -36,15 +36,12 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { - char * dest = NULL; size_t len; int c; - int elem = 0; int rd_count = 3; size_t data_len; struct GNUNET_NAMESTORE_RecordData src[rd_count]; - struct GNUNET_NAMESTORE_RecordData *dst = NULL; memset(src, '\0', rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); @@ -61,25 +58,27 @@ run (void *cls, char *const *args, const char *cfgfile, } res = 0; - len = GNUNET_NAMESTORE_records_serialize (&dest, rd_count, src); + len = GNUNET_NAMESTORE_records_get_size(rd_count, src); + char rd_ser[len]; + GNUNET_assert (len == GNUNET_NAMESTORE_records_serialize(rd_count, src, len, rd_ser)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized data len: %u\n",len); - GNUNET_assert (dest != NULL); + GNUNET_assert (rd_ser != NULL); - elem = GNUNET_NAMESTORE_records_deserialize(&dst, dest, len); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserialized elements: %u\n",elem); + struct GNUNET_NAMESTORE_RecordData dst[rd_count]; + GNUNET_assert (GNUNET_OK == GNUNET_NAMESTORE_records_deserialize (len, rd_ser, rd_count, dst)); - GNUNET_assert (elem == rd_count); GNUNET_assert (dst != NULL); - for (c = 0; c < elem; c++) + for (c = 0; c < rd_count; c++) { if (src[c].data_size != dst[c].data_size) { GNUNET_break (0); res = 1; } - if (GNUNET_TIME_absolute_get_difference(src[c].expiration, dst[c].expiration).rel_value != GNUNET_TIME_relative_get_zero().rel_value) + if (0 != GNUNET_TIME_absolute_get_difference(src[c].expiration, dst[c].expiration).rel_value) { GNUNET_break (0); res = 1; @@ -115,12 +114,12 @@ run (void *cls, char *const *args, const char *cfgfile, } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Element [%i]: EQUAL\n", c); - /* clean up */ - GNUNET_free((char *) dst[c].data); - GNUNET_free((char *) src[c].data); } - GNUNET_free (dest); - GNUNET_free (dst); + + for (c = 0; c < rd_count; c++) + { + GNUNET_free ((void *)src[c].data); + } } static int diff --git a/src/namestore/test_plugin_namestore.c b/src/namestore/test_plugin_namestore.c index 0b0008f..3e93d73 100644 --- a/src/namestore/test_plugin_namestore.c +++ b/src/namestore/test_plugin_namestore.c @@ -176,7 +176,7 @@ run (void *cls, char *const *args, const char *cfgfile, { struct GNUNET_NAMESTORE_PluginFunctions *nsp; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key; - GNUNET_HashCode zone; + struct GNUNET_CRYPTO_ShortHashCode zone; ok = 0; nsp = load_plugin (cfg); @@ -187,13 +187,16 @@ run (void *cls, char *const *args, const char *cfgfile, "Failed to initialize namestore. Database likely not setup, skipping test.\n"); return; } + put_record (nsp, 1); + get_record (nsp, 1); memset (&zone_key, 1, sizeof (zone_key)); - GNUNET_CRYPTO_hash (&zone_key, sizeof (zone_key), &zone); + GNUNET_CRYPTO_short_hash (&zone_key, sizeof (zone_key), &zone); nsp->delete_zone (nsp->cls, &zone); unload_plugin (nsp); + } @@ -235,8 +238,6 @@ main (int argc, char *argv[]) GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_plugin_namestore_%s.conf", plugin_name); - if (pos != plugin_name) - pos[0] = '.'; GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, "test-plugin-namestore", "nohelp", options, &run, NULL); if (ok != 0) diff --git a/src/namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey b/src/namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey new file mode 100644 index 0000000..eac1d1e Binary files /dev/null and b/src/namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey differ diff --git a/src/namestore/zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey b/src/namestore/zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey new file mode 100644 index 0000000..871fc90 Binary files /dev/null and b/src/namestore/zonefiles/N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey differ diff --git a/src/nat/Makefile.in b/src/nat/Makefile.in index 00ef188..1387216 100644 --- a/src/nat/Makefile.in +++ b/src/nat/Makefile.in @@ -232,6 +232,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -265,6 +266,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/nat/gnunet-nat-server.c b/src/nat/gnunet-nat-server.c index 0336ecc..9b6846c 100644 --- a/src/nat/gnunet-nat-server.c +++ b/src/nat/gnunet-nat-server.c @@ -55,11 +55,9 @@ try_anat (uint32_t dst_ipv4, uint16_t dport, int is_tcp) struct GNUNET_NAT_Handle *h; struct sockaddr_in sa; -#if DEBUG_NAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking for connection reversal with %x and code %u\n", (unsigned int) dst_ipv4, (unsigned int) dport); -#endif h = GNUNET_NAT_register (cfg, is_tcp, dport, 0, NULL, NULL, NULL, NULL, NULL); memset (&sa, 0, sizeof (sa)); sa.sin_family = AF_INET; @@ -107,9 +105,7 @@ tcp_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (-1 == GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data))) { -#if DEBUG_NAT GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send"); -#endif } GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR); } @@ -146,10 +142,8 @@ try_send_tcp (uint32_t dst_ipv4, uint16_t dport, uint16_t data) #endif sa.sin_addr.s_addr = dst_ipv4; sa.sin_port = htons (dport); -#if DEBUG_NAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TCP message to `%s'\n", GNUNET_a2s ((struct sockaddr *) &sa, sizeof (sa))); -#endif if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, (const struct sockaddr *) &sa, sizeof (sa))) && (errno != EINPROGRESS)) @@ -192,10 +186,8 @@ try_send_udp (uint32_t dst_ipv4, uint16_t dport, uint16_t data) #endif sa.sin_addr.s_addr = dst_ipv4; sa.sin_port = htons (dport); -#if DEBUG_NAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending UDP packet to `%s'\n", GNUNET_a2s ((struct sockaddr *) &sa, sizeof (sa))); -#endif if (-1 == GNUNET_NETWORK_socket_sendto (s, &data, sizeof (data), (const struct sockaddr *) &sa, sizeof (sa))) @@ -219,9 +211,7 @@ test (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_NAT_TestMessage *tm; uint16_t dport; -#if DEBUG_NAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received test request\n"); -#endif tm = (const struct GNUNET_NAT_TestMessage *) msg; dport = ntohs (tm->dport); if (0 == dport) diff --git a/src/nat/nat.c b/src/nat/nat.c index 5117f5d..79604da 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c @@ -422,10 +422,8 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h, lal->addrlen = arg_size; lal->source = src; GNUNET_CONTAINER_DLL_insert (h->lal_head, h->lal_tail, lal); -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding address `%s' from source %d\n", GNUNET_a2s (arg, arg_size), src); -#endif if (NULL != h->address_callback) h->address_callback (h->callback_cls, GNUNET_YES, arg, arg_size); } @@ -750,14 +748,12 @@ nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_DISK_file_read (h->server_stdout_handle, mybuf, sizeof (mybuf)); if (bytes < 1) { -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished reading from server stdout with code: %d\n", bytes); -#endif if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); GNUNET_OS_process_wait (h->server_proc); - GNUNET_OS_process_close (h->server_proc); + GNUNET_OS_process_destroy (h->server_proc); h->server_proc = NULL; GNUNET_DISK_pipe_close (h->server_stdout); h->server_stdout = NULL; @@ -795,7 +791,7 @@ nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) #if HAVE_SOCKADDR_IN_SIN_LEN sin_addr.sin_len = sizeof (sin_addr); #endif - if ((NULL == port_start) || (1 != sscanf (port_start, "%d", &port)) || + if ((NULL == port_start) || (1 != SSCANF (port_start, "%d", &port)) || (-1 == inet_pton (AF_INET, mybuf, &sin_addr.sin_addr))) { /* should we restart gnunet-helper-nat-server? */ @@ -809,10 +805,8 @@ nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) return; } sin_addr.sin_port = htons ((uint16_t) port); -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "gnunet-helper-nat-server read: %s:%d\n", mybuf, port); -#endif h->reversal_callback (h->callback_cls, (const struct sockaddr *) &sin_addr, sizeof (sin_addr)); h->server_read_task = @@ -837,10 +831,8 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) (h->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES)))) { -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting `%s' at `%s'\n", "gnunet-helper-nat-server", h->internal_address); -#endif /* Start the server process */ h->server_proc = GNUNET_OS_start_process (GNUNET_NO, NULL, h->server_stdout, @@ -1079,11 +1071,9 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, struct in_addr in_addr; unsigned int i; -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Registered with NAT service at port %u with %u IP bound local addresses\n", (unsigned int) adv_port, num_addrs); -#endif h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; h->cfg = cfg; @@ -1273,7 +1263,7 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); GNUNET_OS_process_wait (h->server_proc); - GNUNET_OS_process_close (h->server_proc); + GNUNET_OS_process_destroy (h->server_proc); h->server_proc = NULL; GNUNET_DISK_pipe_close (h->server_stdout); h->server_stdout = NULL; @@ -1308,50 +1298,51 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) * gnunet-helper-nat-client to send dummy ICMP responses to cause * that peer to connect to us (connection reversal). * - * @param h NAT handle for us (largely used for configuration) - * @param sa the address of the peer (IPv4-only) + * @return GNUNET_SYSERR on error, GNUNET_NO if nat client is disabled, + * GNUNET_OK otherwise */ -void +int GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, const struct sockaddr_in *sa) + + { char inet4[INET_ADDRSTRLEN]; char port_as_string[6]; struct GNUNET_OS_Process *proc; if (GNUNET_YES != h->enable_nat_client) - return; /* not permitted / possible */ + return GNUNET_NO; /* not permitted / possible */ if (h->internal_address == NULL) { LOG (GNUNET_ERROR_TYPE_WARNING, "nat", _ ("Internal IP address not known, cannot use ICMP NAT traversal method\n")); - return; + return GNUNET_SYSERR; } GNUNET_assert (sa->sin_family == AF_INET); if (NULL == inet_ntop (AF_INET, &sa->sin_addr, inet4, INET_ADDRSTRLEN)) { GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "inet_ntop"); - return; + return GNUNET_SYSERR; } GNUNET_snprintf (port_as_string, sizeof (port_as_string), "%d", h->adv_port); -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, _("Running gnunet-helper-nat-client %s %s %u\n"), h->internal_address, inet4, (unsigned int) h->adv_port); -#endif proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "gnunet-helper-nat-client", "gnunet-helper-nat-client", h->internal_address, inet4, port_as_string, NULL); if (NULL == proc) - return; + return GNUNET_SYSERR; /* we know that the gnunet-helper-nat-client will terminate virtually * instantly */ GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); + return GNUNET_OK; } diff --git a/src/nat/nat.h b/src/nat/nat.h index efab3a7..a0ef465 100644 --- a/src/nat/nat.h +++ b/src/nat/nat.h @@ -28,7 +28,6 @@ #define NAT_H #include "gnunet_util_lib.h" -#define DEBUG_NAT GNUNET_EXTRA_LOGGING GNUNET_NETWORK_STRUCT_BEGIN diff --git a/src/nat/nat_mini.c b/src/nat/nat_mini.c index 830fdfd..82697a9 100644 --- a/src/nat/nat_mini.c +++ b/src/nat/nat_mini.c @@ -202,7 +202,7 @@ void GNUNET_NAT_mini_get_external_ipv4_cancel (struct GNUNET_NAT_ExternalHandle *eh) { (void) GNUNET_OS_process_kill (eh->eip, SIGKILL); - GNUNET_OS_process_close (eh->eip); + GNUNET_OS_process_destroy (eh->eip); GNUNET_DISK_pipe_close (eh->opipe); if (GNUNET_SCHEDULER_NO_TASK != eh->task) GNUNET_SCHEDULER_cancel (eh->task); @@ -378,7 +378,7 @@ process_refresh_output (void *cls, const char *line) if (NULL == strstr (s, pstr)) return; /* skip */ if (1 != - sscanf (line, + SSCANF (line, (mini->is_tcp) ? "%*u TCP %u->%*s:%*u %*s" : "%*u UDP %u->%*s:%*u %*s", &nport)) return; /* skip */ @@ -446,7 +446,7 @@ process_map_output (void *cls, const char *line) */ if ((NULL == (ipaddr = strstr (line, " "))) || (NULL == (pstr = strstr (ipaddr, ":"))) || - (1 != sscanf (pstr + 1, "%u", &port))) + (1 != SSCANF (pstr + 1, "%u", &port))) { return; /* skip line */ } @@ -524,9 +524,7 @@ process_unmap_output (void *cls, const char *line) if (NULL == line) { -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "UPnP unmap done\n"); -#endif GNUNET_OS_command_stop (mini->unmap_cmd); mini->unmap_cmd = NULL; GNUNET_free (mini); @@ -577,10 +575,8 @@ GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini) * often are the same, but it might... */ GNUNET_snprintf (pstr, sizeof (pstr), "%u", (unsigned int) ntohs (mini->current_addr.sin_port)); -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Unmapping port %u with UPnP\n", ntohs (mini->current_addr.sin_port)); -#endif mini->unmap_cmd = GNUNET_OS_command_run (&process_unmap_output, mini, UNMAP_TIMEOUT, "upnpc", "upnpc", "-d", pstr, diff --git a/src/nat/nat_test.c b/src/nat/nat_test.c index b6e2a74..387a68d 100644 --- a/src/nat/nat_test.c +++ b/src/nat/nat_test.c @@ -30,6 +30,8 @@ #define LOG(kind,...) GNUNET_log_from (kind, "nat", __VA_ARGS__) +#define NAT_SERVER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) + /** * Entry we keep for each incoming connection. */ @@ -178,10 +180,8 @@ reversal_cb (void *cls, const struct sockaddr *addr, socklen_t addrlen) sa = (const struct sockaddr_in *) addr; if (h->data != sa->sin_port) { -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Received connection reversal request for wrong port\n"); -#endif return; /* wrong port */ } /* report success */ @@ -212,17 +212,13 @@ do_udp_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (data == tst->data) tst->report (tst->report_cls, GNUNET_OK); -#if DEBUG_NAT else LOG (GNUNET_ERROR_TYPE_DEBUG, "Received data mismatches expected value\n"); -#endif } -#if DEBUG_NAT else LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to receive data from inbound connection\n"); -#endif } @@ -250,17 +246,13 @@ do_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (data == tst->data) tst->report (tst->report_cls, GNUNET_OK); -#if DEBUG_NAT else LOG (GNUNET_ERROR_TYPE_DEBUG, "Received data mismatches expected value\n"); -#endif } -#if DEBUG_NAT else LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to receive data from inbound connection\n"); -#endif GNUNET_NETWORK_socket_close (na->sock); GNUNET_free (na); } @@ -292,10 +284,8 @@ do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept"); return; /* odd error */ } -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an inbound connection, waiting for data\n"); -#endif wl = GNUNET_malloc (sizeof (struct NatActivity)); wl->sock = s; wl->h = tst; @@ -328,11 +318,14 @@ addr_cb (void *cls, int add_remove, const struct sockaddr *addr, if (GNUNET_YES != add_remove) return; if (addrlen != sizeof (struct sockaddr_in)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "NAT test ignores IPv6 address `%s' returned from NAT library\n", + GNUNET_a2s (addr, addrlen)); return; /* ignore IPv6 here */ -#if DEBUG_NAT + } LOG (GNUNET_ERROR_TYPE_DEBUG, "Asking gnunet-nat-server to connect to `%s'\n", GNUNET_a2s (addr, addrlen)); -#endif sa = (const struct sockaddr_in *) addr; msg.header.size = htons (sizeof (struct GNUNET_NAT_TestMessage)); msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAT_TEST); @@ -353,7 +346,7 @@ addr_cb (void *cls, int add_remove, const struct sockaddr *addr, GNUNET_CONTAINER_DLL_insert (h->ca_head, h->ca_tail, ca); GNUNET_break (GNUNET_OK == GNUNET_CLIENT_transmit_and_get_response (client, &msg.header, - GNUNET_TIME_UNIT_SECONDS, + NAT_SERVER_TIMEOUT, GNUNET_YES, NULL, NULL)); } @@ -436,6 +429,10 @@ GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ret->lsock, &do_udp_read, ret); } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "NAT test listens on port %u (%s)\n", + bnd_port, + (GNUNET_YES == is_tcp) ? "tcp" : "udp"); ret->nat = GNUNET_NAT_register (cfg, is_tcp, adv_port, 1, addrs, addrlens, &addr_cb, NULL, ret); @@ -455,10 +452,12 @@ GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst) struct NatActivity *pos; struct ClientActivity *cpos; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Stopping NAT test\n"); while (NULL != (cpos = tst->ca_head)) { GNUNET_CONTAINER_DLL_remove (tst->ca_head, tst->ca_tail, cpos); - GNUNET_CLIENT_disconnect (cpos->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (cpos->client); GNUNET_free (cpos); } while (NULL != (pos = tst->na_head)) diff --git a/src/nat/test_nat.c b/src/nat/test_nat.c index 98b57b3..e7325eb 100644 --- a/src/nat/test_nat.c +++ b/src/nat/test_nat.c @@ -41,9 +41,6 @@ #include "gnunet_nat_lib.h" -#define VERBOSE GNUNET_NO - - /** * Time to wait before stopping NAT, in seconds */ @@ -164,28 +161,14 @@ main (int argc, char *const argv[]) "test-nat", "-c", "test_nat_data.conf", - "-L", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif NULL }; - GNUNET_log_setup ("test-nat", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Testing NAT library, timeout set to %d seconds\n", TIMEOUT); - - GNUNET_PROGRAM_run (5, argv_prog, "test-nat", "nohelp", options, &run, NULL); - + GNUNET_PROGRAM_run (3, argv_prog, "test-nat", "nohelp", options, &run, NULL); return 0; } diff --git a/src/nat/test_nat_data.conf b/src/nat/test_nat_data.conf index 83bcf83..7ad00a0 100644 --- a/src/nat/test_nat_data.conf +++ b/src/nat/test_nat_data.conf @@ -36,8 +36,8 @@ USE_LOCALADDR = YES # Should we use ICMP-based NAT traversal to try connect to NATed peers # or, if we are behind NAT, to allow connections to us? -ENABLE_ICMP_CLIENT = YES -ENABLE_ICMP_SERVER = YES +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO # IP address of the interface connected to the NAT box; IPv4 dotted-decimal ONLY; # normal interface IP address for non-NATed peers; diff --git a/src/nat/test_nat_test.c b/src/nat/test_nat_test.c index 6461788..891a763 100644 --- a/src/nat/test_nat_test.c +++ b/src/nat/test_nat_test.c @@ -30,10 +30,6 @@ #include "gnunet_util_lib.h" #include "gnunet_nat_lib.h" - -#define VERBOSE GNUNET_NO - - /** * Time to wait before stopping NAT test, in seconds */ @@ -84,28 +80,16 @@ main (int argc, char *const argv[]) GNUNET_GETOPT_OPTION_END }; struct GNUNET_OS_Process *gns; - int nat_res; - char *const argv_prog[] = { "test-nat-test", "-c", "test_nat_test_data.conf", - "-L", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif NULL }; GNUNET_log_setup ("test-nat-test", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); nat_res = GNUNET_OS_check_helper_binary ("gnunet-nat-server"); @@ -120,16 +104,15 @@ main (int argc, char *const argv[]) gns = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-nat-server", "gnunet-nat-server", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", "test_nat_test_data.conf", "12345", NULL); GNUNET_assert (NULL != gns); - GNUNET_PROGRAM_run (5, argv_prog, "test-nat-test", "nohelp", options, &run, + GNUNET_PROGRAM_run (3, argv_prog, "test-nat-test", "nohelp", options, &run, NULL); GNUNET_break (0 == GNUNET_OS_process_kill (gns, SIGTERM)); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (gns)); - GNUNET_OS_process_close (gns); + GNUNET_OS_process_destroy (gns); + if (0 != ret) + fprintf (stderr, "NAT test failed to report success\n"); return ret; } diff --git a/src/nat/test_nat_test_data.conf b/src/nat/test_nat_test_data.conf index f153e17..1128b37 100644 --- a/src/nat/test_nat_test_data.conf +++ b/src/nat/test_nat_test_data.conf @@ -12,16 +12,17 @@ PORT = 12345 [nat] # Are we behind NAT? -BEHIND_NAT = YES +BEHIND_NAT = NO # Is the NAT hole-punched? -PUNCHED_NAT = NO +PUNCHED_NAT = YES # Disable UPNP by default until it gets cleaner! -ENABLE_UPNP = YES +ENABLE_UPNP = NO # Use addresses from the local network interfaces (inluding loopback, but also others) USE_LOCALADDR = YES +RETURN_LOCAL_ADDRESSES = YES # External IP address of the NAT box (if known); IPv4 dotted-decimal ONLY at this time (should allow DynDNS!) # normal interface IP address for non-NATed peers; @@ -30,8 +31,8 @@ USE_LOCALADDR = YES # Should we use ICMP-based NAT traversal to try connect to NATed peers # or, if we are behind NAT, to allow connections to us? -ENABLE_ICMP_CLIENT = YES -ENABLE_ICMP_SERVER = YES +ENABLE_ICMP_CLIENT = NO +ENABLE_ICMP_SERVER = NO # IP address of the interface connected to the NAT box; IPv4 dotted-decimal ONLY; # normal interface IP address for non-NATed peers; diff --git a/src/nse/Makefile.in b/src/nse/Makefile.in index 7c03cbe..43d533b 100644 --- a/src/nse/Makefile.in +++ b/src/nse/Makefile.in @@ -208,6 +208,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -241,6 +242,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/nse/gnunet-nse-profiler.c b/src/nse/gnunet-nse-profiler.c index a10d237..4a4bea5 100644 --- a/src/nse/gnunet-nse-profiler.c +++ b/src/nse/gnunet-nse-profiler.c @@ -371,7 +371,9 @@ connect_nse_service (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) #endif for (i = 0; i < num_peers; i++) { - if ((connection_limit > 0) && (i % (num_peers / connection_limit) != 0)) + if ((connection_limit > 0) && + (num_peers > connection_limit) && + (i % (num_peers / connection_limit) != 0)) continue; #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -894,7 +896,7 @@ run (void *cls, char *const *args, const char *cfgfile, &connect_cb, &my_cb, NULL, hosts); GNUNET_assert (pg != NULL); shutdown_handle = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_get_forever (), + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); } diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c index 3af9bb7..9c31ab8 100644 --- a/src/nse/gnunet-service-nse.c +++ b/src/nse/gnunet-service-nse.c @@ -410,9 +410,7 @@ handle_start_message (void *cls, struct GNUNET_SERVER_Client *client, { struct GNUNET_NSE_ClientMessage em; -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n"); -#endif GNUNET_SERVER_notification_context_add (nc, client); setup_estimate_message (&em); GNUNET_SERVER_notification_context_unicast (nc, client, &em.header, @@ -457,11 +455,9 @@ get_delay_randomization (uint32_t matching_bits) d = get_matching_bits_delay (matching_bits); i = (uint32_t) (d / (double) (hop_count_max + 1)); -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Randomizing flood using latencies up to %u ms\n", (unsigned int) i); -#endif ret.rel_value = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, i + 1); return ret; #else @@ -514,11 +510,9 @@ get_transmit_delay (int round_offset) #else ret = GNUNET_TIME_UNIT_ZERO; #endif -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting previous round behind schedule in %llu ms\n", (unsigned long long) ret.rel_value); -#endif return ret; case 0: /* current round is based on best-known matching_bits */ @@ -527,13 +521,11 @@ get_transmit_delay (int round_offset) dist_delay = get_matching_bits_delay (matching_bits); dist_delay += get_delay_randomization (matching_bits).rel_value; ret.rel_value = (uint64_t) dist_delay; -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "For round %llu, delay for %u matching bits is %llu ms\n", (unsigned long long) current_timestamp.abs_value, (unsigned int) matching_bits, (unsigned long long) ret.rel_value); -#endif /* now consider round start time and add delay to it */ tgt = GNUNET_TIME_absolute_add (current_timestamp, ret); return GNUNET_TIME_absolute_get_remaining (tgt); @@ -569,14 +561,14 @@ transmit_ready (void *cls, size_t size, void *buf) unsigned int idx; peer_entry->th = NULL; - if (buf == NULL) + if (NULL == buf) { /* client disconnected */ return 0; } GNUNET_assert (size >= sizeof (struct GNUNET_NSE_FloodMessage)); idx = estimate_index; - if (peer_entry->previous_round == GNUNET_NO) + if (GNUNET_NO == peer_entry->previous_round) { idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE; peer_entry->previous_round = GNUNET_YES; @@ -599,7 +591,6 @@ transmit_ready (void *cls, size_t size, void *buf) 1, GNUNET_NO); return 0; } -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In round %llu, sending to `%s' estimate with %u bits\n", (unsigned long long) @@ -607,7 +598,6 @@ transmit_ready (void *cls, size_t size, void *buf) timestamp).abs_value, GNUNET_i2s (&peer_entry->id), (unsigned int) ntohl (size_estimate_messages[idx].matching_bits)); -#endif if (ntohl (size_estimate_messages[idx].hop_count) == 0) GNUNET_STATISTICS_update (stats, "# flood messages started", 1, GNUNET_NO); GNUNET_STATISTICS_update (stats, "# flood messages transmitted", 1, @@ -635,6 +625,7 @@ transmit_task_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct NSEPeerEntry *peer_entry = cls; peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_assert (NULL == peer_entry->th); peer_entry->th = GNUNET_CORE_notify_transmit_ready (coreAPI, GNUNET_NO, NSE_PRIORITY, @@ -713,12 +704,12 @@ schedule_current_round (void *cls, const GNUNET_HashCode * key, void *value) struct NSEPeerEntry *peer_entry = value; struct GNUNET_TIME_Relative delay; - if (peer_entry->th != NULL) + if (NULL != peer_entry->th) { peer_entry->previous_round = GNUNET_NO; return GNUNET_OK; } - if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != peer_entry->transmit_task) { GNUNET_SCHEDULER_cancel (peer_entry->transmit_task); peer_entry->previous_round = GNUNET_NO; @@ -762,14 +753,16 @@ update_flood_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_SCHEDULER_add_delayed (offset, &update_flood_message, NULL); return; } - current_timestamp = next_timestamp; - next_timestamp = - GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval); estimate_index = (estimate_index + 1) % HISTORY_SIZE; if (estimate_count < HISTORY_SIZE) estimate_count++; - if (next_timestamp.abs_value == - GNUNET_TIME_absolute_ntoh (next_message.timestamp).abs_value) + current_timestamp = next_timestamp; + next_timestamp = + GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval); + if ((current_timestamp.abs_value == + GNUNET_TIME_absolute_ntoh (next_message.timestamp).abs_value) && + (get_matching_bits (current_timestamp, &my_identity) < + ntohl(next_message.matching_bits))) { /* we received a message for this round way early, use it! */ size_estimate_messages[estimate_index] = next_message; @@ -823,7 +816,7 @@ check_proof_of_work (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey, uint64_t val) { char buf[sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + - sizeof (val)]; + sizeof (val)] GNUNET_ALIGN; GNUNET_HashCode result; memcpy (buf, &val, sizeof (val)); @@ -868,7 +861,7 @@ find_proof (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) #define ROUND_SIZE 10 uint64_t counter; char buf[sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + - sizeof (uint64_t)]; + sizeof (uint64_t)] GNUNET_ALIGN; GNUNET_HashCode result; unsigned int i; @@ -884,10 +877,8 @@ find_proof (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (nse_work_required <= count_leading_zeroes (&result)) { my_proof = counter; -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Proof of work found: %llu!\n", (unsigned long long) GNUNET_ntohll (counter)); -#endif write_proof (); setup_flood_message (estimate_index, current_timestamp); return; @@ -897,10 +888,8 @@ find_proof (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } if (my_proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE)) { -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing proofs currently at %llu\n", (unsigned long long) counter); -#endif /* remember progress every 100 rounds */ my_proof = counter; write_proof (); @@ -977,7 +966,11 @@ update_flood_times (void *cls, const GNUNET_HashCode * key, void *value) { /* still stuck in previous round, no point to update, check that * we are active here though... */ - GNUNET_break (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK); + if (GNUNET_SCHEDULER_NO_TASK == peer_entry->transmit_task && + NULL == peer_entry->th) + { + GNUNET_break (0); + } return GNUNET_OK; } if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK) @@ -1015,7 +1008,7 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer, #if ENABLE_HISTOGRAM if (NULL != wh) - GNUNET_BIO_write_int64 (wh, GNUNET_TIME_absolute_get ().abs_value); + GNUNET_break (GNUNET_OK == GNUNET_BIO_write_int64 (wh, GNUNET_TIME_absolute_get ().abs_value)); #endif incoming_flood = (const struct GNUNET_NSE_FloodMessage *) message; GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO); @@ -1054,14 +1047,12 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer, #endif ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp); - if (ts.abs_value == current_timestamp.abs_value) idx = estimate_index; else if (ts.abs_value == current_timestamp.abs_value - gnunet_nse_interval.rel_value) idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE; - else if (ts.abs_value == - next_timestamp.abs_value - gnunet_nse_interval.rel_value) + else if (ts.abs_value == next_timestamp.abs_value) { if (matching_bits <= ntohl (next_message.matching_bits)) return GNUNET_OK; /* ignore, simply too early/late */ @@ -1117,8 +1108,9 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer, } if (matching_bits < ntohl (size_estimate_messages[idx].matching_bits)) { - if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES)) + if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES)) { peer_entry->previous_round = GNUNET_NO; + } /* push back our result now, that peer is spreading bad information... */ if (NULL == peer_entry->th) { @@ -1140,7 +1132,10 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer, } GNUNET_assert (matching_bits > ntohl (size_estimate_messages[idx].matching_bits)); - /* cancel transmission from us to this peer for this round */ + /* Cancel transmission in the other direction, as this peer clearly has + * up-to-date information already. + */ + peer_entry->previous_round = GNUNET_YES; if (idx == estimate_index) { /* cancel any activity for current round */ @@ -1155,11 +1150,6 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer, peer_entry->th = NULL; } } - else - { - /* cancel previous round only */ - peer_entry->previous_round = GNUNET_YES; - } size_estimate_messages[idx] = *incoming_flood; size_estimate_messages[idx].hop_count = htonl (ntohl (incoming_flood->hop_count) + 1); @@ -1181,7 +1171,8 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer, /** - * Method called whenever a peer connects. + * Method called whenever a peer connects. Sets up the PeerEntry and + * schedules the initial size info transmission to this peer. * * @param cls closure * @param peer peer identity this notification is about @@ -1195,10 +1186,8 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, { struct NSEPeerEntry *peer_entry; -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s' connected to us\n", GNUNET_i2s (peer)); -#endif peer_entry = GNUNET_malloc (sizeof (struct NSEPeerEntry)); peer_entry->id = *peer; GNUNET_assert (GNUNET_OK == @@ -1208,12 +1197,13 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, peer_entry->transmit_task = GNUNET_SCHEDULER_add_delayed (get_transmit_delay (-1), &transmit_task_cb, peer_entry); - GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO); + GNUNET_STATISTICS_update (stats, "# peers connected", 1, GNUNET_NO); } /** - * Method called whenever a peer disconnects. + * Method called whenever a peer disconnects. Deletes the PeerEntry and cancels + * any pending transmission requests to that peer. * * @param cls closure * @param peer peer identity this notification is about @@ -1223,10 +1213,8 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) { struct NSEPeerEntry *pos; -#if DEBUG_NSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s' disconnected from us\n", GNUNET_i2s (peer)); -#endif pos = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey); if (NULL == pos) { @@ -1236,15 +1224,17 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (peers, &peer->hashPubKey, pos)); - if (pos->transmit_task != GNUNET_SCHEDULER_NO_TASK) + if (pos->transmit_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (pos->transmit_task); + pos->transmit_task = GNUNET_SCHEDULER_NO_TASK; + } if (pos->th != NULL) { GNUNET_CORE_notify_transmit_ready_cancel (pos->th); pos->th = NULL; } GNUNET_free (pos); - GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO); + GNUNET_STATISTICS_update (stats, "# peers connected", -1, GNUNET_NO); } @@ -1296,7 +1286,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) #if ENABLE_HISTOGRAM if (wh != NULL) { - GNUNET_BIO_write_close (wh); + GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (wh)); wh = NULL; } #endif @@ -1317,11 +1307,9 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server, struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute prev_time; - if (server == NULL) + if (NULL == server) { -#if DEBUG_NSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection to core FAILED!\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to core FAILED!\n"); GNUNET_SCHEDULER_shutdown (); return; } @@ -1338,9 +1326,11 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server, estimate_count = 0; if (GNUNET_YES == check_proof_of_work (&my_public_key, my_proof)) { + int idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE; prev_time.abs_value = current_timestamp.abs_value - gnunet_nse_interval.rel_value; - setup_flood_message (estimate_index, prev_time); + setup_flood_message (idx, prev_time); + setup_flood_message (estimate_index, current_timestamp); estimate_count++; } flood_task = diff --git a/src/nse/nse.conf.in b/src/nse/nse.conf.in index b04f5ac..bc49e05 100644 --- a/src/nse/nse.conf.in +++ b/src/nse/nse.conf.in @@ -1,6 +1,6 @@ [nse] AUTOSTART = YES -@UNIXONLY@ PORT = 2097 +@JAVAPORT@PORT = 2097 HOSTNAME = localhost HOME = $SERVICEHOME CONFIG = $DEFAULTCONFIG diff --git a/src/nse/nse_api.c b/src/nse/nse_api.c index 4d5f6bb..9a44197 100644 --- a/src/nse/nse_api.c +++ b/src/nse/nse_api.c @@ -106,7 +106,7 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg) if (msg == NULL) { /* Error, timeout, death */ - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h); @@ -145,15 +145,13 @@ reschedule_connect (struct GNUNET_NSE_Handle *h) } if (NULL != h->client) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } -#if DEBUG_NSE LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling task to reconnect to nse service in %llu ms.\n", h->reconnect_delay.rel_value); -#endif h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h); if (h->reconnect_delay.rel_value == 0) @@ -187,16 +185,12 @@ send_start (void *cls, size_t size, void *buf) if (buf == NULL) { /* Connect error... */ -#if DEBUG_NSE LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutdown while trying to transmit `%s' request.\n", "START"); -#endif reschedule_connect (h); return 0; } -#if DEBUG_NSE LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "START"); -#endif GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); msg = (struct GNUNET_MessageHeader *) buf; @@ -225,10 +219,8 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) /* shutdown, just give up */ return; } -#if DEBUG_NSE LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to network size estimation service.\n"); -#endif GNUNET_assert (h->client == NULL); h->client = GNUNET_CLIENT_connect ("nse", h->cfg); GNUNET_assert (h->client != NULL); @@ -289,7 +281,7 @@ GNUNET_NSE_disconnect (struct GNUNET_NSE_Handle *h) } if (h->client != NULL) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } GNUNET_free (h); diff --git a/src/nse/nse_profiler_test.conf b/src/nse/nse_profiler_test.conf index 964cceb..3a3217d 100644 --- a/src/nse/nse_profiler_test.conf +++ b/src/nse/nse_profiler_test.conf @@ -8,7 +8,7 @@ UNIXPATH = /tmp/test-nse-service-nse.unix BINARY = gnunet-service-nse #BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/nse/.libs/gnunet-service-nse #PREFIX = valgrind --leak-check=full --log-file=valgrind_nse.%p -AUTOSTART = YES +AUTOSTART = NO DEBUG = YES CONFIG = $DEFAULTCONFIG # Overriding network settings for faster testing (do NOT use @@ -104,7 +104,7 @@ AUTOSTART = NO AUTOSTART = NO [testing] -NUM_PEERS = 4000 +NUM_PEERS = 2000 WEAKRANDOM = YES TOPOLOGY = NONE #CONNECT_TOPOLOGY = SMALL_WORLD_RING @@ -122,7 +122,7 @@ HOSTKEYSFILE = hostkeys.dat MAX_CONCURRENT_SSH = 20 USE_PROGRESSBARS = YES PEERGROUP_TIMEOUT = 1000 s -TOPOLOGY_OUTPUT_FILE = nse_topo_4000_peers_initial +TOPOLOGY_OUTPUT_FILE = nse_topo_2000_peers_initial MAX_OUTSTANDING_CONNECTIONS = 100 #SINGLE_PEERINFO_PER_HOST = YES #NUM_PEERINFO_PER_HOST = 10 @@ -132,20 +132,20 @@ DELETE_FILES = NO #SKEW_VARIANCE = 30000 [nse-profiler] -OUTPUT_FILE = nse_output_4000_peers.dat -TOPOLOGY_OUTPUT_FILE = nse_topo_4000_peers -DATA_OUTPUT_FILE = nse_stats_4000_peers -ROUND0 = 4000 -ROUND1 = 4000 -ROUND2 = 4000 -ROUND3 = 4000 -ROUND4 = 4000 -ROUND5 = 4000 -ROUND6 = 4000 -ROUND7 = 4000 -ROUND8 = 4000 -ROUND9 = 4000 -ROUND10 = 4000 +OUTPUT_FILE = nse_output_2000_peers.dat +TOPOLOGY_OUTPUT_FILE = nse_topo_2000_peers +DATA_OUTPUT_FILE = nse_stats_2000_peers +ROUND0 = 1000 +#ROUND1 = 2000 +ROUND2 = 2000 +ROUND3 = 2000 +ROUND4 = 2000 +ROUND5 = 2000 +ROUND6 = 2000 +ROUND7 = 2000 +ROUND8 = 2000 +ROUND9 = 2000 +ROUND10 = 2000 ROUND11 = 1000 ROUND12 = 1000 ROUND13 = 1000 diff --git a/src/nse/test_nse_api.c b/src/nse/test_nse_api.c index f6cde3f..f99cb3b 100644 --- a/src/nse/test_nse_api.c +++ b/src/nse/test_nse_api.c @@ -29,8 +29,6 @@ #include "gnunet_scheduler_lib.h" #include "gnunet_nse_service.h" -#define DEBUG_NSE GNUNET_YES - #define START_ARM GNUNET_YES static struct GNUNET_NSE_Handle *h; @@ -55,7 +53,7 @@ stop_arm (struct PeerContext *p) if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (p->arm_proc); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; #endif GNUNET_CONFIGURATION_destroy (p->cfg); @@ -147,11 +145,7 @@ check () char *const argv[] = { "test-nse-api", "-c", "test_nse.conf", -#if DEBUG_NSE - "-L", "DEBUG", -#else "-L", "WARNING", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -173,14 +167,9 @@ main (int argc, char *argv[]) int ret; GNUNET_log_setup ("test_nse_api", -#if DEBUG_NSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); - return ret; } diff --git a/src/peerinfo-tool/Makefile.am b/src/peerinfo-tool/Makefile.am index 8c5fd8f..2182e8a 100644 --- a/src/peerinfo-tool/Makefile.am +++ b/src/peerinfo-tool/Makefile.am @@ -13,11 +13,14 @@ bin_PROGRAMS = \ gnunet-peerinfo gnunet_peerinfo_SOURCES = \ - gnunet-peerinfo.c + gnunet-peerinfo.c \ + gnunet-peerinfo_plugins.c gnunet-peerinfo_plugins.h + gnunet_peerinfo_LDADD = \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la if HAVE_PYTHON_PEXPECT diff --git a/src/peerinfo-tool/Makefile.in b/src/peerinfo-tool/Makefile.in index 1984b45..c348769 100644 --- a/src/peerinfo-tool/Makefile.in +++ b/src/peerinfo-tool/Makefile.in @@ -59,12 +59,14 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) -am_gnunet_peerinfo_OBJECTS = gnunet-peerinfo.$(OBJEXT) +am_gnunet_peerinfo_OBJECTS = gnunet-peerinfo.$(OBJEXT) \ + gnunet-peerinfo_plugins.$(OBJEXT) gnunet_peerinfo_OBJECTS = $(am_gnunet_peerinfo_OBJECTS) gnunet_peerinfo_DEPENDENCIES = \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) @@ -157,6 +159,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -190,6 +193,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -311,12 +315,14 @@ INCLUDES = -I$(top_srcdir)/src/include @USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0 @USE_COVERAGE_TRUE@XLIB = -lgcov gnunet_peerinfo_SOURCES = \ - gnunet-peerinfo.c + gnunet-peerinfo.c \ + gnunet-peerinfo_plugins.c gnunet-peerinfo_plugins.h gnunet_peerinfo_LDADD = \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/transport/libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la @HAVE_PYTHON_PEXPECT_TRUE@check_SCRIPTS = \ @@ -417,6 +423,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-peerinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-peerinfo_plugins.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c index 21c9966..de27cd2 100644 --- a/src/peerinfo-tool/gnunet-peerinfo.c +++ b/src/peerinfo-tool/gnunet-peerinfo.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2003, 2004, 2006, 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2001-2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -30,26 +30,252 @@ #include "gnunet_peerinfo_service.h" #include "gnunet_transport_service.h" #include "gnunet_program_lib.h" +#include "gnunet_transport_plugin.h" +#include "gnunet-peerinfo_plugins.h" +/** + * Prefix that every HELLO URI must start with. + */ +#define HELLO_URI_PREFIX "gnunet://hello/" + +/** + * How long until we time out during peerinfo iterations? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) + +/** + * Structure we use to collect printable address information. + */ +struct PrintContext; + +/** + * Record we keep for each printable address. + */ +struct AddressRecord +{ + /** + * Current address-to-string context (if active, otherwise NULL). + */ + struct GNUNET_TRANSPORT_AddressToStringContext *atsc; + + /** + * Printable address. + */ + char *result; + + /** + * Print context this address record belongs to. + */ + struct PrintContext *pc; +}; + + +/** + * Structure we use to collect printable address information. + */ +struct PrintContext +{ + + /** + * Kept in DLL. + */ + struct PrintContext *next; + + /** + * Kept in DLL. + */ + struct PrintContext *prev; + + /** + * Identity of the peer. + */ + struct GNUNET_PeerIdentity peer; + + /** + * List of printable addresses. + */ + struct AddressRecord *address_list; + + /** + * Number of completed addresses in 'address_list'. + */ + unsigned int num_addresses; + + /** + * Number of addresses allocated in 'address_list'. + */ + unsigned int address_list_size; + + /** + * Current offset in 'address_list' (counted down). + */ + unsigned int off; + +}; + + +/** + * Context used for building our own URI. + */ +struct GetUriContext +{ + /** + * Final URI. + */ + char *uri; + +}; + + +/** + * Context for 'add_address_to_hello'. + */ +struct GNUNET_PEERINFO_HelloAddressParsingContext +{ + /** + * Position in the URI with the next address to parse. + */ + const char *pos; + + /** + * Set to GNUNET_SYSERR to indicate parse errors. + */ + int ret; + +}; + + +/** + * Option '-n' + */ static int no_resolve; +/** + * Option '-q' + */ static int be_quiet; +/** + * Option '-s' + */ static int get_self; +/** + * Option + */ +static int get_uri; + +/** + * Option '-i' + */ +static int get_info; + +/** + * Option + */ +static char *put_uri; + +/** + * Handle to peerinfo service. + */ static struct GNUNET_PEERINFO_Handle *peerinfo; +/** + * Configuration handle. + */ static const struct GNUNET_CONFIGURATION_Handle *cfg; -struct PrintContext +/** + * Main state machine task (if active). + */ +static GNUNET_SCHEDULER_TaskIdentifier tt; + +/** + * Current iterator context (if active, otherwise NULL). + */ +static struct GNUNET_PEERINFO_IteratorContext *pic; + +/** + * My peer identity. + */ +static struct GNUNET_PeerIdentity my_peer_identity; + +/** + * My public key. + */ +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; + +/** + * Head of list of print contexts. + */ +static struct PrintContext *pc_head; + +/** + * Tail of list of print contexts. + */ +static struct PrintContext *pc_tail; + +/** + * Handle to current 'GNUNET_PEERINFO_add_peer' operation. + */ +static struct GNUNET_PEERINFO_AddContext *ac; + + +/** + * Main state machine that goes over all options and + * runs the next requested function. + * + * @param cls unused + * @param tc unused + */ +static void +state_machine (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc); + + + +/** + * Replace all characters in the input 'in' according + * to the mapping. The mapping says to map each character + * in 'oldchars' to the corresponding character (by offset) + * in 'newchars'. + * + * @param in input string to remap + * @param oldchars characters to replace + * @param newchars replacement characters, must have same length as 'oldchars' + * @return copy of string with replacement applied. + */ +static char * +map_characters (const char *in, + const char *oldchars, + const char *newchars) { - struct GNUNET_PeerIdentity peer; - char **address_list; - unsigned int num_addresses; - uint32_t off; -}; + char *ret; + const char *off; + size_t i; + + GNUNET_assert (strlen (oldchars) == strlen (newchars)); + ret = GNUNET_strdup (in); + i = 0; + while (ret[i] != '\0') + { + off = strchr (oldchars, ret[i]); + if (NULL != off) + ret[i] = newchars[off - oldchars]; + i++; + } + return ret; +} + + +/* ********************* 'get_info' ******************* */ +/** + * Print the collected address information to the console and free 'pc'. + * + * @param pc printing context + */ static void dump_pc (struct PrintContext *pc) { @@ -57,18 +283,31 @@ dump_pc (struct PrintContext *pc) unsigned int i; GNUNET_CRYPTO_hash_to_enc (&pc->peer.hashPubKey, &enc); - printf (_("Peer `%s'\n"), (const char *) &enc); + printf (_("Peer `%s'\n"), + (const char *) &enc); for (i = 0; i < pc->num_addresses; i++) { - printf ("\t%s\n", pc->address_list[i]); - GNUNET_free (pc->address_list[i]); + if (NULL != pc->address_list[i].result) + { + printf ("\t%s\n", pc->address_list[i].result); + GNUNET_free (pc->address_list[i].result); + } } printf ("\n"); - GNUNET_array_grow (pc->address_list, pc->num_addresses, 0); + GNUNET_free_non_null (pc->address_list); + GNUNET_CONTAINER_DLL_remove (pc_head, + pc_tail, + pc); GNUNET_free (pc); + if ( (NULL == pc_head) && + (NULL == pic) ) + tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); } +/* ************************* list all known addresses **************** */ + + /** * Function to call with a human-readable format of an address * @@ -78,24 +317,26 @@ dump_pc (struct PrintContext *pc) static void process_resolved_address (void *cls, const char *address) { - struct PrintContext *pc = cls; + struct AddressRecord * ar = cls; + struct PrintContext *pc = ar->pc; - if (address == NULL) + if (NULL != address) { - pc->off--; - if (pc->off == 0) - dump_pc (pc); + if (NULL == ar->result) + ar->result = GNUNET_strdup (address); return; } - GNUNET_array_append (pc->address_list, pc->num_addresses, - GNUNET_strdup (address)); + ar->atsc = NULL; + pc->num_addresses++; + if (pc->num_addresses == pc->address_list_size) + dump_pc (pc); } /** - * Iterator callback to go over all addresses. + * Iterator callback to go over all addresses and count them. * - * @param cls closure + * @param cls 'struct PrintContext' with 'off' to increment * @param address the address * @param expiration expiration time * @return GNUNET_OK to keep the address and continue @@ -124,19 +365,27 @@ print_address (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct PrintContext *pc = cls; + struct AddressRecord *ar; - GNUNET_TRANSPORT_address_to_string (cfg, address, no_resolve, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 10), - &process_resolved_address, pc); + GNUNET_assert (0 < pc->off); + ar = &pc->address_list[--pc->off]; + ar->pc = pc; + ar->atsc = GNUNET_TRANSPORT_address_to_string (cfg, address, no_resolve, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 10), + &process_resolved_address, ar); return GNUNET_OK; } /** * Print information about the peer. - * Currently prints the GNUNET_PeerIdentity and the IP. - * Could of course do more (e.g. resolve via DNS). + * Currently prints the GNUNET_PeerIdentity and the transport address. + * + * @param cls the 'struct PrintContext' + * @param peer identity of the peer + * @param hello addresses of the peer + * @param err_msg error message */ static void print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, @@ -147,26 +396,403 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, if (peer == NULL) { + pic = NULL; /* end of iteration */ if (err_msg != NULL) - FPRINTF (stderr, "%s", _("Error in communication with PEERINFO service\n")); - GNUNET_PEERINFO_disconnect (peerinfo); + { + FPRINTF (stderr, + _("Error in communication with PEERINFO service: %s\n"), + err_msg); + } + if (NULL == pc_head) + tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); return; } - if ((be_quiet) || (NULL == hello)) + if ((GNUNET_YES == be_quiet) || (NULL == hello)) { GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc); printf ("%s\n", (const char *) &enc); return; } pc = GNUNET_malloc (sizeof (struct PrintContext)); + GNUNET_CONTAINER_DLL_insert (pc_head, + pc_tail, + pc); pc->peer = *peer; - GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_address, pc); + GNUNET_HELLO_iterate_addresses (hello, + GNUNET_NO, + &count_address, + pc); if (0 == pc->off) { dump_pc (pc); return; } - GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &print_address, pc); + pc->address_list_size = pc->off; + pc->address_list = GNUNET_malloc (sizeof (struct AddressRecord) * pc->off); + GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, + &print_address, pc); +} + + +/* ************************* GET URI ************************** */ + + +/** + * Function that is called on each address of this peer. + * Expands the corresponding URI string. + * + * @param cls the 'GetUriContext' + * @param address address to add + * @param expiration expiration time for the address + * @return GNUNET_OK (continue iteration). + */ +static int +compose_uri (void *cls, const struct GNUNET_HELLO_Address *address, + struct GNUNET_TIME_Absolute expiration) +{ + struct GetUriContext *guc = cls; + struct GNUNET_TRANSPORT_PluginFunctions *papi; + const char *addr; + char *uri_addr; + char *ret; + char tbuf[16]; + struct tm *t; + time_t seconds; + + papi = GPI_plugins_find (address->transport_name); + if (papi == NULL) + { + /* Not an error - we might just not have the right plugin. */ + return GNUNET_OK; + } + if (NULL == papi->address_to_string) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "URI conversion not implemented for plugin `%s'\n", + address->transport_name); + return GNUNET_OK; + } + addr = papi->address_to_string (papi->cls, address->address, address->address_length); + if ( (addr == NULL) || (strlen(addr) == 0) ) + return GNUNET_OK; + /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved + characters in URIs */ + uri_addr = map_characters (addr, "[]", "()"); + seconds = expiration.abs_value / 1000; + t = gmtime (&seconds); + GNUNET_assert (0 != strftime (tbuf, sizeof (tbuf), + "%Y%m%d%H%M%S", + t)); + GNUNET_asprintf (&ret, + "%s!%s!%s!%s", + guc->uri, + tbuf, + address->transport_name, + uri_addr); + GNUNET_free (uri_addr); + GNUNET_free (guc->uri); + guc->uri = ret; + return GNUNET_OK; +} + + +/** + * Print URI of the peer. + * + * @param cls the 'struct GetUriContext' + * @param peer identity of the peer (unused) + * @param hello addresses of the peer + * @param err_msg error message + */ +static void +print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Message *hello, + const char *err_msg) +{ + struct GetUriContext *guc = cls; + + if (peer == NULL) + { + pic = NULL; + if (err_msg != NULL) + FPRINTF (stderr, + _("Error in communication with PEERINFO service: %s\n"), + err_msg); + GNUNET_free_non_null (guc->uri); + GNUNET_free (guc); + tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); + return; + } + if (NULL != hello) + GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &compose_uri, guc); + printf ("%s\n", (const char *) guc->uri); +} + + +/* ************************* import HELLO by URI ********************* */ + + +/** + * We're building a HELLO. Parse the next address from the + * parsing context and append it. + * + * @param cls the 'struct GNUNET_PEERINFO_HelloAddressParsingContext' + * @param max number of bytes available for HELLO construction + * @param buffer where to copy the next address (in binary format) + * @return number of bytes added to buffer + */ +static size_t +add_address_to_hello (void *cls, size_t max, void *buffer) +{ + struct GNUNET_PEERINFO_HelloAddressParsingContext *ctx = cls; + const char *tname; + const char *address; + char *uri_address; + char *plugin_address; + const char *end; + char *plugin_name; + struct tm expiration_time; + time_t expiration_seconds; + struct GNUNET_TIME_Absolute expire; + struct GNUNET_TRANSPORT_PluginFunctions *papi; + void *addr; + size_t addr_len; + struct GNUNET_HELLO_Address haddr; + size_t ret; + + if (NULL == ctx->pos) + return 0; + if ('!' != ctx->pos[0]) + { + ctx->ret = GNUNET_SYSERR; + GNUNET_break (0); + return 0; + } + ctx->pos++; + memset (&expiration_time, 0, sizeof (expiration_time)); + tname = strptime (ctx->pos, + "%Y%m%d%H%M%S", + &expiration_time); + + if (NULL == tname) + { + ctx->ret = GNUNET_SYSERR; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to parse HELLO message: missing expiration time\n")); + GNUNET_break (0); + return 0; + } + expiration_seconds = mktime (&expiration_time); + if (expiration_seconds == (time_t) -1) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to parse HELLO message: invalid expiration time\n")); + ctx->ret = GNUNET_SYSERR; + GNUNET_break (0); + return 0; + } + expire.abs_value = expiration_seconds * 1000; + if ('!' != tname[0]) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to parse HELLO message: malformed\n")); + ctx->ret = GNUNET_SYSERR; + GNUNET_break (0); + return 0; + } + tname++; + address = strchr (tname, (int) '!'); + if (NULL == address) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to parse HELLO message: missing transport plugin\n")); + ctx->ret = GNUNET_SYSERR; + GNUNET_break (0); + return 0; + } + address++; + end = strchr (address, (int) '!'); + ctx->pos = end; + plugin_name = GNUNET_strndup (tname, address - (tname+1)); + papi = GPI_plugins_find (plugin_name); + if (NULL == papi) + { + /* Not an error - we might just not have the right plugin. + * Skip this part, advance to the next one and recurse. + * But only if this is not the end of string. + */ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin `%s' not found\n"), + plugin_name); + GNUNET_free (plugin_name); + GNUNET_break (0); + return 0; + } + if (NULL == papi->string_to_address) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Plugin `%s' does not support URIs yet\n"), + plugin_name); + GNUNET_free (plugin_name); + GNUNET_break (0); + return 0; + } + uri_address = GNUNET_strndup (address, end - address); + /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved + characters in URIs; need to convert back to '[]' for the plugin */ + plugin_address = map_characters (uri_address, "()", "[]"); + GNUNET_free (uri_address); + if (GNUNET_OK != + papi->string_to_address (papi->cls, + plugin_address, + strlen (plugin_address) + 1, + &addr, + &addr_len)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to parse `%s' as an address for plugin `%s'\n"), + plugin_address, + plugin_name); + GNUNET_free (plugin_name); + GNUNET_free (plugin_address); + return 0; + } + GNUNET_free (plugin_address); + /* address.peer is unset - not used by add_address() */ + haddr.address_length = addr_len; + haddr.address = addr; + haddr.transport_name = plugin_name; + ret = GNUNET_HELLO_add_address (&haddr, expire, buffer, max); + GNUNET_free (addr); + GNUNET_free (plugin_name); + return ret; +} + + +/** + * Continuation called from 'GNUNET_PEERINFO_add_peer' + * + * @param cls closure, NULL + * @param emsg error message, NULL on success + */ +static void +add_continuation (void *cls, + const char *emsg) +{ + ac = NULL; + if (NULL != emsg) + fprintf (stderr, + _("Failure adding HELLO: %s\n"), + emsg); + tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); +} + + +/** + * Parse the PUT URI given at the command line and add it to our peerinfo + * database. + * + * @param put_uri URI string to parse + * @return GNUNET_OK on success, GNUNET_SYSERR if the URI was invalid, GNUNET_NO on other errors + */ +static int +parse_hello_uri (const char *put_uri) +{ + const char *pks; + const char *exc; + struct GNUNET_HELLO_Message *hello; + struct GNUNET_PEERINFO_HelloAddressParsingContext ctx; + + if (0 != strncmp (put_uri, + HELLO_URI_PREFIX, + strlen (HELLO_URI_PREFIX))) + return GNUNET_SYSERR; + pks = &put_uri[strlen (HELLO_URI_PREFIX)]; + exc = strstr (pks, "!"); + + if (GNUNET_OK != GNUNET_STRINGS_string_to_data (pks, + (NULL == exc) ? strlen (pks) : (exc - pks), + (unsigned char *) &my_public_key, + sizeof (my_public_key))) + return GNUNET_SYSERR; + ctx.pos = exc; + ctx.ret = GNUNET_OK; + hello = GNUNET_HELLO_create (&my_public_key, &add_address_to_hello, &ctx); + + if (NULL != hello) + { + /* WARNING: this adds the address from URI WITHOUT verification! */ + if (GNUNET_OK == ctx.ret) + ac = GNUNET_PEERINFO_add_peer (peerinfo, hello, &add_continuation, NULL); + else + tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); + GNUNET_free (hello); + } + + /* wait 1s to give peerinfo operation a chance to succeed */ + /* FIXME: current peerinfo API sucks to require this; not to mention + that we get no feedback to determine if the operation actually succeeded */ + return ctx.ret; +} + + +/* ************************ Main state machine ********************* */ + + +/** + * Main state machine that goes over all options and + * runs the next requested function. + * + * @param cls unused + * @param tc scheduler context + */ +static void +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PrintContext *pc; + struct AddressRecord *ar; + unsigned int i; + + if (NULL != ac) + { + GNUNET_PEERINFO_add_peer_cancel (ac); + ac = NULL; + } + if (GNUNET_SCHEDULER_NO_TASK != tt) + { + GNUNET_SCHEDULER_cancel (tt); + tt = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != pic) + { + GNUNET_PEERINFO_iterate_cancel (pic); + pic = NULL; + } + while (NULL != (pc = pc_head)) + { + GNUNET_CONTAINER_DLL_remove (pc_head, + pc_tail, + pc); + for (i=0;iaddress_list_size;i++) + { + ar = &pc->address_list[i]; + GNUNET_free_non_null (ar->result); + if (NULL != ar->atsc) + { + GNUNET_TRANSPORT_address_to_string_cancel (ar->atsc); + ar->atsc = NULL; + } + } + GNUNET_free_non_null (pc->address_list); + GNUNET_free (pc); + } + GPI_plugins_unload (); + if (NULL != peerinfo) + { + GNUNET_PEERINFO_disconnect (peerinfo); + peerinfo = NULL; + } } @@ -183,9 +809,6 @@ run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { struct GNUNET_CRYPTO_RsaPrivateKey *priv; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; - struct GNUNET_PeerIdentity pid; - struct GNUNET_CRYPTO_HashAsciiEncoded enc; char *fn; cfg = c; @@ -194,46 +817,107 @@ run (void *cls, char *const *args, const char *cfgfile, FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); return; } - if (get_self != GNUNET_YES) + peerinfo = GNUNET_PEERINFO_connect (cfg); + if (peerinfo == NULL) { - peerinfo = GNUNET_PEERINFO_connect (cfg); - if (peerinfo == NULL) - { - FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n")); - return; - } - GNUNET_PEERINFO_iterate (peerinfo, NULL, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), &print_peer_info, - NULL); + FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n")); + return; } - else + if ( (GNUNET_YES == get_self) || (GNUNET_YES == get_uri) ) { + /* load private key */ if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", - &fn)) + GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", + &fn)) { FPRINTF (stderr, _("Could not find option `%s:%s' in configuration.\n"), - "GNUNETD", "HOSTKEYFILE"); + "GNUNETD", "HOSTKEYFILE"); return; } - priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn); - if (priv == NULL) + + if (NULL == (priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn))) { FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), fn); GNUNET_free (fn); return; } GNUNET_free (fn); - GNUNET_CRYPTO_rsa_key_get_public (priv, &pub); + GNUNET_CRYPTO_rsa_key_get_public (priv, &my_public_key); GNUNET_CRYPTO_rsa_key_free (priv); - GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); - GNUNET_CRYPTO_hash_to_enc (&pid.hashPubKey, &enc); + GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), &my_peer_identity.hashPubKey); + } + + tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &shutdown_task, + NULL); +} + + +/** + * Main state machine that goes over all options and + * runs the next requested function. + * + * @param cls unused + * @param tc scheduler context + */ +static void +state_machine (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + tt = GNUNET_SCHEDULER_NO_TASK; + + if (NULL != put_uri) + { + GPI_plugins_load (cfg); + if (GNUNET_SYSERR == parse_hello_uri (put_uri)) + fprintf (stderr, + _("Invalid URI `%s'\n"), + put_uri); + GNUNET_free (put_uri); + put_uri = NULL; + return; + } + if (GNUNET_YES == get_info) + { + get_info = GNUNET_NO; + GPI_plugins_load (cfg); + pic = GNUNET_PEERINFO_iterate (peerinfo, NULL, + TIMEOUT, + &print_peer_info, NULL); + return; + } + if (GNUNET_YES == get_self) + { + struct GNUNET_CRYPTO_HashAsciiEncoded enc; + + get_self = GNUNET_NO; + GNUNET_CRYPTO_hash_to_enc (&my_peer_identity.hashPubKey, &enc); if (be_quiet) printf ("%s\n", (char *) &enc); else printf (_("I am peer `%s'.\n"), (const char *) &enc); } + if (GNUNET_YES == get_uri) + { + struct GetUriContext *guc; + char *pkey; + + guc = GNUNET_malloc (sizeof (struct GetUriContext)); + pkey = GNUNET_CRYPTO_rsa_public_key_to_string (&my_public_key); + GNUNET_asprintf (&guc->uri, + "%s%s", + HELLO_URI_PREFIX, + pkey); + GNUNET_free (pkey); + GPI_plugins_load (cfg); + pic = GNUNET_PEERINFO_iterate (peerinfo, &my_peer_identity, + TIMEOUT, + &print_my_uri, guc); + get_uri = GNUNET_NO; + return; + } + GNUNET_SCHEDULER_shutdown (); } @@ -257,6 +941,15 @@ main (int argc, char *const *argv) {'s', "self", NULL, gettext_noop ("output our own identity only"), 0, &GNUNET_GETOPT_set_one, &get_self}, + {'i', "info", NULL, + gettext_noop ("list all known peers"), + 0, &GNUNET_GETOPT_set_one, &get_info}, + {'g', "get-hello", NULL, + gettext_noop ("also output HELLO uri(s)"), + 0, &GNUNET_GETOPT_set_one, &get_uri}, + {'p', "put-hello", "HELLO", + gettext_noop ("add given HELLO uri to the database"), + 1, &GNUNET_GETOPT_set_string, &put_uri}, GNUNET_GETOPT_OPTION_END }; return (GNUNET_OK == diff --git a/src/peerinfo-tool/gnunet-peerinfo_plugins.c b/src/peerinfo-tool/gnunet-peerinfo_plugins.c new file mode 100644 index 0000000..ba7c1d3 --- /dev/null +++ b/src/peerinfo-tool/gnunet-peerinfo_plugins.c @@ -0,0 +1,178 @@ +/* + This file is part of GNUnet. + (C) 2010,2011 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file peerinfo-tool/gnunet-peerinfo_plugins.c + * @brief plugin management + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet-peerinfo_plugins.h" +#include "gnunet_transport_plugin.h" +#include "gnunet_hello_lib.h" + +/** + * Entry in doubly-linked list of all of our plugins. + */ +struct TransportPlugin +{ + /** + * This is a doubly-linked list. + */ + struct TransportPlugin *next; + + /** + * This is a doubly-linked list. + */ + struct TransportPlugin *prev; + + /** + * API of the transport as returned by the plugin's + * initialization function. + */ + struct GNUNET_TRANSPORT_PluginFunctions *api; + + /** + * Short name for the plugin (i.e. "tcp"). + */ + char *short_name; + + /** + * Name of the library (i.e. "gnunet_plugin_transport_tcp"). + */ + char *lib_name; + + /** + * Environment this transport service is using + * for this plugin. + */ + struct GNUNET_TRANSPORT_PluginEnvironment env; + +}; + +/** + * Head of DLL of all loaded plugins. + */ +static struct TransportPlugin *plugins_head; + +/** + * Head of DLL of all loaded plugins. + */ +static struct TransportPlugin *plugins_tail; + + + +/** + * Load and initialize all plugins. The respective functions will be + * invoked by the plugins when the respective events happen. The + * closure will be set to a 'const char*' containing the name of the + * plugin that caused the call. + * + * @param cfg configuration to use + */ +void +GPI_plugins_load (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct TransportPlugin *plug; + struct TransportPlugin *next; + char *libname; + char *plugs; + char *pos; + + if (NULL != plugins_head) + return; /* already loaded */ + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, "TRANSPORT", "PLUGINS", + &plugs)) + return; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting transport plugins `%s'\n"), + plugs); + for (pos = strtok (plugs, " "); pos != NULL; pos = strtok (NULL, " ")) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' transport plugin\n"), + pos); + GNUNET_asprintf (&libname, "libgnunet_plugin_transport_%s", pos); + plug = GNUNET_malloc (sizeof (struct TransportPlugin)); + plug->short_name = GNUNET_strdup (pos); + plug->lib_name = libname; + plug->env.cfg = cfg; + plug->env.cls = plug->short_name; + GNUNET_CONTAINER_DLL_insert (plugins_head, plugins_tail, plug); + } + GNUNET_free (plugs); + next = plugins_head; + while (next != NULL) + { + plug = next; + next = plug->next; + plug->api = GNUNET_PLUGIN_load (plug->lib_name, &plug->env); + if (plug->api == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to load transport plugin for `%s'\n"), + plug->lib_name); + GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug); + GNUNET_free (plug->short_name); + GNUNET_free (plug->lib_name); + GNUNET_free (plug); + } + } +} + + +/** + * Unload all plugins + */ +void +GPI_plugins_unload () +{ + struct TransportPlugin *plug; + + while (NULL != (plug = plugins_head)) + { + GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api)); + GNUNET_free (plug->lib_name); + GNUNET_free (plug->short_name); + GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug); + GNUNET_free (plug); + } +} + + +/** + * Obtain the plugin API based on a plugin name. + * + * @param name name of the plugin + * @return the plugin's API, NULL if the plugin is not loaded + */ +struct GNUNET_TRANSPORT_PluginFunctions * +GPI_plugins_find (const char *name) +{ + struct TransportPlugin *head = plugins_head; + + while ((head != NULL) && (0 != strcmp (name, head->short_name))) + head = head->next; + if (NULL == head) + return NULL; + return head->api; +} + + +/* end of file gnunet-peerinfo_plugins.c */ diff --git a/src/peerinfo-tool/gnunet-peerinfo_plugins.h b/src/peerinfo-tool/gnunet-peerinfo_plugins.h new file mode 100644 index 0000000..9640ed5 --- /dev/null +++ b/src/peerinfo-tool/gnunet-peerinfo_plugins.h @@ -0,0 +1,58 @@ +/* + This file is part of GNUnet. + (C) 2010,2011 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file peerinfo-tool/gnunet-peerinfo_plugins.h + * @brief plugin management API + * @author Christian Grothoff + */ +#ifndef GNUNET_PEERINFO_PLUGINS_H +#define GNUNET_PEERINFO_PLUGINS_H + +#include "gnunet_util_lib.h" + +/** + * Load transport plugins. + * + * @param cfg configuration to use + */ +void +GPI_plugins_load (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Unload all plugins + */ +void +GPI_plugins_unload (void); + + +/** + * Obtain the plugin API based on a plugin name. + * + * @param name name of the plugin + * @return the plugin's API, NULL if the plugin is not loaded + */ +struct GNUNET_TRANSPORT_PluginFunctions * +GPI_plugins_find (const char *name); + + +#endif +/* end of file gnunet-peerinfo_plugins.h */ diff --git a/src/peerinfo-tool/test_gnunet_peerinfo.py.in b/src/peerinfo-tool/test_gnunet_peerinfo.py.in old mode 100755 new mode 100644 index ee8bc4a..bff673e --- a/src/peerinfo-tool/test_gnunet_peerinfo.py.in +++ b/src/peerinfo-tool/test_gnunet_peerinfo.py.in @@ -42,8 +42,8 @@ elif os.name == 'nt': pinfo = pexpect () -pinfo.spawn (None, [peerinfo, '-c', 'test_gnunet_peerinfo_data.conf', '-L', 'ERROR'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) -pinfo.expect ("stdout", re.compile (r'Error in communication with PEERINFO service\r?\n')) +pinfo.spawn (None, [peerinfo, '-i', '-c', 'test_gnunet_peerinfo_data.conf', '-L', 'ERROR'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) +pinfo.expect ("stdout", re.compile (r'Error in communication with PEERINFO service: Timeout transmitting iteration request to `PEERINFO\' service.\r?\n')) pinfo.expect ("stdout", "EOF") if os.name == "nt": @@ -67,13 +67,13 @@ try: arm.communicate () time.sleep (1) - pinfo.spawn (None, [peerinfo, '-c', 'test_gnunet_peerinfo_data.conf'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + pinfo.spawn (None, [peerinfo, '-i', '-c', 'test_gnunet_peerinfo_data.conf'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) pinfo.expect ("stdout", re.compile ("Peer `.*'\r?\n")) m = pinfo.expect ("stdout", re.compile ("\s.*:24357\r?\n")) while len (m.group (0)) > 0: m = pinfo.expect ("stdout", re.compile ("(\s.*:24357\r?\n|\r?\n|)")) - pinfo.spawn (None, [peerinfo, '-c', 'test_gnunet_peerinfo_data.conf', '-n'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + pinfo.spawn (None, [peerinfo, '-i', '-c', 'test_gnunet_peerinfo_data.conf', '-n'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) pinfo.expect ("stdout", re.compile ("Peer `.*'\r?\n")) m = pinfo.expect ("stdout", re.compile ("\s.*:24357\r?\n")) while len (m.group (0)) > 0: diff --git a/src/peerinfo/Makefile.in b/src/peerinfo/Makefile.in index 639e43f..dc407f5 100644 --- a/src/peerinfo/Makefile.in +++ b/src/peerinfo/Makefile.in @@ -215,6 +215,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -248,6 +249,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c index d6e52d4..df3486e 100644 --- a/src/peerinfo/gnunet-service-peerinfo.c +++ b/src/peerinfo/gnunet-service-peerinfo.c @@ -32,12 +32,9 @@ */ #include "platform.h" -#include "gnunet_crypto_lib.h" -#include "gnunet_container_lib.h" -#include "gnunet_disk_lib.h" +#include "gnunet_util_lib.h" #include "gnunet_hello_lib.h" #include "gnunet_protocols.h" -#include "gnunet_service_lib.h" #include "gnunet_statistics_service.h" #include "peerinfo.h" @@ -51,6 +48,7 @@ */ #define DATA_HOST_CLEAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60) + /** * In-memory cache of known hosts. */ @@ -95,6 +93,9 @@ static struct GNUNET_STATISTICS_Handle *stats; /** * Notify all clients in the notify list about the * given host entry changing. + * + * @param he entry of the host for which we generate a notification + * @return generated notification message */ static struct InfoMessage * make_info_message (const struct HostEntry *he) @@ -141,6 +142,8 @@ discard_expired (void *cls, const struct GNUNET_HELLO_Address *address, /** * Get the filename under which we would store the GNUNET_HELLO_Message * for the given host and protocol. + * + * @param id peer for which we need the filename for the HELLO * @return filename of the form DIRECTORY/HOSTID */ static char * @@ -173,6 +176,42 @@ notify_all (struct HostEntry *entry) } +/** + * Try to read the HELLO in the given filename and discard expired addresses. + * + * @param fn name of the file + * @return HELLO of the file, NULL on error + */ +static struct GNUNET_HELLO_Message * +read_host_file (const char *fn) +{ + char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; + const struct GNUNET_HELLO_Message *hello; + struct GNUNET_HELLO_Message *hello_clean; + int size; + struct GNUNET_TIME_Absolute now; + + if (GNUNET_YES != GNUNET_DISK_file_test (fn)) + return NULL; + size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); + hello = (const struct GNUNET_HELLO_Message *) buffer; + if ((size < sizeof (struct GNUNET_MessageHeader)) || + (size != ntohs ((((const struct GNUNET_MessageHeader *) hello)->size))) + || (size != GNUNET_HELLO_size (hello))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to parse HELLO in file `%s'\n"), + fn); + return NULL; + } + now = GNUNET_TIME_absolute_get (); + hello_clean = + GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, + &now); + return hello_clean; +} + + /** * Add a host to the list. * @@ -182,11 +221,6 @@ static void add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) { struct HostEntry *entry; - char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; - const struct GNUNET_HELLO_Message *hello; - struct GNUNET_HELLO_Message *hello_clean; - int size; - struct GNUNET_TIME_Absolute now; char *fn; entry = GNUNET_CONTAINER_multihashmap_get (hostmap, &identity->hashPubKey); @@ -196,32 +230,11 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) GNUNET_NO); entry = GNUNET_malloc (sizeof (struct HostEntry)); entry->identity = *identity; - - fn = get_host_filename (identity); - if (GNUNET_DISK_file_test (fn) == GNUNET_YES) - { - size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); - hello = (const struct GNUNET_HELLO_Message *) buffer; - if ((size < sizeof (struct GNUNET_MessageHeader)) || - (size != ntohs ((((const struct GNUNET_MessageHeader *) hello)->size))) - || (size != GNUNET_HELLO_size (hello))) - { - GNUNET_break (0); - if (0 != UNLINK (fn)) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); - } - else - { - now = GNUNET_TIME_absolute_get (); - hello_clean = - GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, - &now); - entry->hello = hello_clean; - } - } - GNUNET_free (fn); GNUNET_CONTAINER_multihashmap_put (hostmap, &identity->hashPubKey, entry, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + fn = get_host_filename (identity); + entry->hello = read_host_file (fn); + GNUNET_free (fn); notify_all (entry); } @@ -229,6 +242,8 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) /** * Remove a file that should not be there. LOG * success or failure. + * + * @param fullname name of the file to remove */ static void remove_garbage (const char *fullname) @@ -244,18 +259,30 @@ remove_garbage (const char *fullname) } +/** + * Function that is called on each HELLO file in a particular directory. + * Try to parse the file and add the HELLO to our list. + * + * @param cls pointer to 'unsigned int' to increment for each file, or NULL + * if the file is from a read-only, read-once resource directory + * @param fullname name of the file to parse + * @return GNUNET_OK (continue iteration) + */ static int hosts_directory_scan_callback (void *cls, const char *fullname) { unsigned int *matched = cls; struct GNUNET_PeerIdentity identity; const char *filename; + struct HostEntry *entry; + struct GNUNET_HELLO_Message *hello; if (GNUNET_DISK_file_test (fullname) != GNUNET_YES) return GNUNET_OK; /* ignore non-files */ if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) { - remove_garbage (fullname); + if (NULL != matched) + remove_garbage (fullname); return GNUNET_OK; } filename = @@ -263,16 +290,34 @@ hosts_directory_scan_callback (void *cls, const char *fullname) sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1]; if (filename[-1] != DIR_SEPARATOR) { - remove_garbage (fullname); + if (NULL != matched) + remove_garbage (fullname); return GNUNET_OK; } if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (filename, &identity.hashPubKey)) { - remove_garbage (fullname); + if (NULL != (hello = read_host_file (filename))) + { + entry = GNUNET_malloc (sizeof (struct HostEntry)); + if (GNUNET_OK == + GNUNET_HELLO_get_id (hello, + &entry->identity)) + { + GNUNET_CONTAINER_multihashmap_put (hostmap, &entry->identity.hashPubKey, entry, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + entry->hello = hello; + notify_all (entry); + return GNUNET_OK; + } + GNUNET_free (entry); + } + if (NULL != matched) + remove_garbage (fullname); return GNUNET_OK; } - (*matched)++; + if (NULL != matched) + (*matched)++; add_host_to_known_hosts (&identity); return GNUNET_OK; } @@ -280,6 +325,9 @@ hosts_directory_scan_callback (void *cls, const char *fullname) /** * Call this method periodically to scan data/hosts for new hosts. + * + * @param cls unused + * @param tc scheduler context, aborted if reason is shutdown */ static void cron_scan_directory_data_hosts (void *cls, @@ -362,7 +410,6 @@ bind_address (const struct GNUNET_PeerIdentity *peer, } - /** * Do transmit info about peer to given host. * @@ -378,7 +425,7 @@ add_to_tc (void *cls, const GNUNET_HashCode * key, void *value) struct HostEntry *pos = value; struct InfoMessage *im; uint16_t hs; - char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; + char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; hs = 0; im = (struct InfoMessage *) buf; @@ -401,12 +448,16 @@ add_to_tc (void *cls, const GNUNET_HashCode * key, void *value) /** * @brief delete expired HELLO entries in data/hosts/ + * + * @param cls pointer to current time (struct GNUNET_TIME_Absolute) + * @param fn filename to test to see if the HELLO expired + * @return GNUNET_OK (continue iteration) */ static int discard_hosts_helper (void *cls, const char *fn) { struct GNUNET_TIME_Absolute *now = cls; - char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; + char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; const struct GNUNET_HELLO_Message *hello; struct GNUNET_HELLO_Message *new_hello; int size; @@ -442,7 +493,11 @@ discard_hosts_helper (void *cls, const char *fn) /** - * Call this method periodically to scan data/hosts for new hosts. + * Call this method periodically to scan data/hosts for ancient + * HELLOs to expire. + * + * @param cls unused + * @param tc scheduler context, aborted if reason is shutdown */ static void cron_clean_data_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) @@ -479,10 +534,8 @@ handle_hello (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_PEERINFO GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received for peer `%4s'\n", "HELLO", GNUNET_i2s (&pid)); -#endif bind_address (&pid, hello); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -504,10 +557,8 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, lpm = (const struct ListPeerMessage *) message; GNUNET_break (0 == ntohl (lpm->reserved)); -#if DEBUG_PEERINFO GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received for peer `%4s'\n", "GET", GNUNET_i2s (&lpm->peer)); -#endif tc = GNUNET_SERVER_transmit_context_create (client); GNUNET_CONTAINER_multihashmap_get_multiple (hostmap, &lpm->peer.hashPubKey, &add_to_tc, tc); @@ -530,9 +581,7 @@ handle_get_all (void *cls, struct GNUNET_SERVER_Client *client, { struct GNUNET_SERVER_TransmitContext *tc; -#if DEBUG_PEERINFO GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received\n", "GET_ALL"); -#endif tc = GNUNET_SERVER_transmit_context_create (client); GNUNET_CONTAINER_multihashmap_iterate (hostmap, &add_to_tc, tc); GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, @@ -541,6 +590,9 @@ handle_get_all (void *cls, struct GNUNET_SERVER_Client *client, } +/** + * FIXME. + */ static int do_notify_entry (void *cls, const GNUNET_HashCode * key, void *value) { @@ -567,15 +619,17 @@ static void handle_notify (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { -#if DEBUG_PEERINFO GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received\n", "NOTIFY"); -#endif + GNUNET_SERVER_client_mark_monitor (client); GNUNET_SERVER_notification_context_add (notify_list, client); GNUNET_CONTAINER_multihashmap_iterate (hostmap, &do_notify_entry, client); GNUNET_SERVER_receive_done (client, GNUNET_OK); } +/** + * FIXME. + */ static int free_host_entry (void *cls, const GNUNET_HashCode * key, void *value) { @@ -586,6 +640,7 @@ free_host_entry (void *cls, const GNUNET_HashCode * key, void *value) return GNUNET_YES; } + /** * Clean up our state. Called during shutdown. * @@ -608,7 +663,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) /** - * Process statistics requests. + * Start up peerinfo service. * * @param cls closure * @param server the initialized server @@ -628,6 +683,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, sizeof (struct GNUNET_MessageHeader)}, {NULL, NULL, 0, 0} }; + char *peerdir; + char *ip; hostmap = GNUNET_CONTAINER_multihashmap_create (1024); stats = GNUNET_STATISTICS_create ("peerinfo", cfg); @@ -644,11 +701,22 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); GNUNET_SERVER_add_handlers (server, handlers); + ip = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); + GNUNET_asprintf (&peerdir, + "%shellos", + ip); + GNUNET_free (ip); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Importing HELLOs from `%s'\n"), + peerdir); + GNUNET_DISK_directory_scan (peerdir, + &hosts_directory_scan_callback, NULL); + GNUNET_free (peerdir); } /** - * The main function for the statistics service. + * The main function for the peerinfo service. * * @param argc number of arguments from the command line * @param argv command line arguments diff --git a/src/peerinfo/peerinfo.h b/src/peerinfo/peerinfo.h index bf56774..919645e 100644 --- a/src/peerinfo/peerinfo.h +++ b/src/peerinfo/peerinfo.h @@ -27,7 +27,6 @@ #include "gnunet_time_lib.h" #include "gnunet_peerinfo_service.h" -#define DEBUG_PEERINFO GNUNET_EXTRA_LOGGING GNUNET_NETWORK_STRUCT_BEGIN diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c index 4c5d795..c13224e 100644 --- a/src/peerinfo/peerinfo_api.c +++ b/src/peerinfo/peerinfo_api.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -31,53 +31,109 @@ #include "gnunet_time_lib.h" #include "peerinfo.h" -#define LOG(kind,...) GNUNET_log_from (kind, "nse-api",__VA_ARGS__) - -/** - * Function to call after transmission has succeeded. - * - * @param cls closure - * @param success GNUNET_OK if transmission worked, GNUNET_SYSERR on error - */ -typedef void (*TransmissionContinuation) (void *cls, int success); +#define LOG(kind,...) GNUNET_log_from (kind, "peerinfo-api",__VA_ARGS__) /** - * Entry in the transmission queue to PEERINFO service. + * Entry in the transmission queue to PEERINFO service. We use + * the same structure for queueing 'iteration' requests and + * actual 'add' messages. */ -struct TransmissionQueueEntry +struct GNUNET_PEERINFO_AddContext { /** * This is a linked list. */ - struct TransmissionQueueEntry *next; + struct GNUNET_PEERINFO_AddContext *next; /** * This is a linked list. */ - struct TransmissionQueueEntry *prev; + struct GNUNET_PEERINFO_AddContext *prev; /** - * Function to call after request has been transmitted, or NULL (in which - * case we must consider sending the next entry immediately). + * Handle to the PEERINFO service. */ - TransmissionContinuation cont; + struct GNUNET_PEERINFO_Handle *h; + + /** + * Function to call after request has been transmitted, or NULL. + */ + GNUNET_PEERINFO_Continuation cont; /** * Closure for 'cont'. */ void *cont_cls; + /** + * Number of bytes of the request message (follows after this struct). + */ + size_t size; + +}; + + +/** + * Context for an iteration request. + */ +struct GNUNET_PEERINFO_IteratorContext +{ + + /** + * Kept in a DLL. + */ + struct GNUNET_PEERINFO_IteratorContext *next; + + /** + * Kept in a DLL. + */ + struct GNUNET_PEERINFO_IteratorContext *prev; + + /** + * Handle to the PEERINFO service. + */ + struct GNUNET_PEERINFO_Handle *h; + + /** + * Function to call with the results. + */ + GNUNET_PEERINFO_Processor callback; + + /** + * Closure for 'callback'. + */ + void *callback_cls; + + /** + * Our entry in the transmission queue. + */ + struct GNUNET_PEERINFO_AddContext *ac; + + /** + * Task responsible for timeout. + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + /** * Timeout for the operation. */ struct GNUNET_TIME_Absolute timeout; /** - * Number of bytes of the request message (follows after this struct). + * Peer we are interested in (only valid if iteration was restricted to one peer). */ - size_t size; + struct GNUNET_PeerIdentity peer; + + /** + * Is 'peer' set? + */ + int have_peer; + /** + * Are we now receiving? + */ + int in_receive; }; @@ -99,18 +155,28 @@ struct GNUNET_PEERINFO_Handle /** * Head of transmission queue. */ - struct TransmissionQueueEntry *tq_head; + struct GNUNET_PEERINFO_AddContext *ac_head; /** * Tail of transmission queue. */ - struct TransmissionQueueEntry *tq_tail; + struct GNUNET_PEERINFO_AddContext *ac_tail; /** * Handle for the current transmission request, or NULL if none is pending. */ struct GNUNET_CLIENT_TransmitHandle *th; + /** + * Head of iterator DLL. + */ + struct GNUNET_PEERINFO_IteratorContext *ic_head; + + /** + * Tail of iterator DLL. + */ + struct GNUNET_PEERINFO_IteratorContext *ic_tail; + /** * ID for a reconnect task. */ @@ -135,12 +201,12 @@ struct GNUNET_PEERINFO_Handle struct GNUNET_PEERINFO_Handle * GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct GNUNET_PEERINFO_Handle *ret; + struct GNUNET_PEERINFO_Handle *h; - ret = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_Handle)); - ret->client = GNUNET_CLIENT_connect ("peerinfo", cfg); - ret->cfg = cfg; - return ret; + h = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_Handle)); + h->client = GNUNET_CLIENT_connect ("peerinfo", cfg); + h->cfg = cfg; + return h; } @@ -156,23 +222,30 @@ GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) void GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h) { - struct TransmissionQueueEntry *tqe; + struct GNUNET_PEERINFO_AddContext *ac; + struct GNUNET_PEERINFO_IteratorContext *ic; - while (NULL != (tqe = h->tq_head)) + while (NULL != (ic = h->ic_head)) { - GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe); - if (tqe->cont != NULL) - tqe->cont (tqe->cont_cls, GNUNET_SYSERR); - GNUNET_free (tqe); + GNUNET_break (GNUNET_YES == ic->in_receive); + ic->in_receive = GNUNET_NO; + GNUNET_PEERINFO_iterate_cancel (ic); } - if (h->th != NULL) + while (NULL != (ac = h->ac_head)) + { + GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac); + if (NULL != ac->cont) + ac->cont (ac->cont_cls, _("aborted due to explicit disconnect request")); + GNUNET_free (ac); + } + if (NULL != h->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); h->th = NULL; } if (NULL != h->client) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } if (GNUNET_SCHEDULER_NO_TASK != h->r_task) @@ -202,6 +275,7 @@ trigger_transmit (struct GNUNET_PEERINFO_Handle *h); static void reconnect (struct GNUNET_PEERINFO_Handle *h); + /** * Task scheduled to re-try connecting to the peerinfo service. * @@ -226,7 +300,7 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void reconnect (struct GNUNET_PEERINFO_Handle *h) { - if (h->r_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != h->r_task) { GNUNET_SCHEDULER_cancel (h->r_task); h->r_task = GNUNET_SCHEDULER_NO_TASK; @@ -238,9 +312,10 @@ reconnect (struct GNUNET_PEERINFO_Handle *h) } if (NULL != h->client) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_SYSERR); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } + h->in_receive = GNUNET_NO; h->client = GNUNET_CLIENT_connect ("peerinfo", h->cfg); if (NULL == h->client) { @@ -266,38 +341,39 @@ static size_t do_transmit (void *cls, size_t size, void *buf) { struct GNUNET_PEERINFO_Handle *h = cls; - struct TransmissionQueueEntry *tqe = h->tq_head; + struct GNUNET_PEERINFO_AddContext *ac = h->ac_head; size_t ret; h->th = NULL; - if (tqe == NULL) - return 0; - if (buf == NULL) + if (NULL == ac) + return 0; /* request was cancelled in the meantime */ + if (NULL == buf) { -#if DEBUG_PEERINFO + /* peerinfo service died */ LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - _("Failed to transmit message to `%s' service.\n"), "PEERINFO"); -#endif - GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe); + "Failed to transmit message to `%s' service.\n", "PEERINFO"); + GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac); reconnect (h); - if (tqe->cont != NULL) - tqe->cont (tqe->cont_cls, GNUNET_SYSERR); - GNUNET_free (tqe); + if (NULL != ac->cont) + ac->cont (ac->cont_cls, _("failed to transmit request (service down?)")); + GNUNET_free (ac); + return 0; + } + ret = ac->size; + if (size < ret) + { + /* change in head of queue (i.e. cancel + add), try again */ + trigger_transmit (h); return 0; } - ret = tqe->size; - GNUNET_assert (size >= ret); - memcpy (buf, &tqe[1], ret); -#if DEBUG_PEERINFO LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting request of size %u to `%s' service.\n", ret, "PEERINFO"); -#endif - GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe); - if (tqe->cont != NULL) - tqe->cont (tqe->cont_cls, GNUNET_OK); - else - trigger_transmit (h); - GNUNET_free (tqe); + memcpy (buf, &ac[1], ret); + GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac); + trigger_transmit (h); + if (NULL != ac->cont) + ac->cont (ac->cont_cls, NULL); + GNUNET_free (ac); return ret; } @@ -311,24 +387,25 @@ do_transmit (void *cls, size_t size, void *buf) static void trigger_transmit (struct GNUNET_PEERINFO_Handle *h) { - struct TransmissionQueueEntry *tqe; + struct GNUNET_PEERINFO_AddContext *ac; - if (NULL == (tqe = h->tq_head)) - return; - if (h->th != NULL) - return; - if (h->in_receive == GNUNET_YES) - return; + if (NULL == (ac = h->ac_head)) + return; /* no requests queued */ + if (NULL != h->th) + return; /* request already pending */ + if (GNUNET_YES == h->in_receive) + return; /* still reading replies from last request */ if (NULL == h->client) { + /* disconnected, try to reconnect */ reconnect (h); return; } h->th = - GNUNET_CLIENT_notify_transmit_ready (h->client, tqe->size, - GNUNET_TIME_absolute_get_remaining - (tqe->timeout), GNUNET_YES, - &do_transmit, h); + GNUNET_CLIENT_notify_transmit_ready (h->client, ac->size, + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, + &do_transmit, h); } @@ -342,76 +419,61 @@ trigger_transmit (struct GNUNET_PEERINFO_Handle *h) * * @param h handle to the peerinfo service * @param hello the verified (!) HELLO message + * @param cont continuation to call when done, NULL is allowed + * @param cont_cls closure for 'cont' + * @return handle to cancel add operation; all pending + * 'add' operations will be cancelled automatically + * on disconnect, so it is not necessary to keep this + * handle (unless 'cont' is NULL and at some point + * calling 'cont' must be prevented) */ -void +struct GNUNET_PEERINFO_AddContext * GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h, - const struct GNUNET_HELLO_Message *hello) + const struct GNUNET_HELLO_Message *hello, + GNUNET_PEERINFO_Continuation cont, + void *cont_cls) { uint16_t hs = GNUNET_HELLO_size (hello); - struct TransmissionQueueEntry *tqe; - -#if DEBUG_PEERINFO + struct GNUNET_PEERINFO_AddContext *ac; struct GNUNET_PeerIdentity peer; GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id (hello, &peer)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding peer `%s' to PEERINFO database (%u bytes of `%s')\n", GNUNET_i2s (&peer), hs, "HELLO"); -#endif - tqe = GNUNET_malloc (sizeof (struct TransmissionQueueEntry) + hs); - tqe->size = hs; - tqe->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; - memcpy (&tqe[1], hello, hs); - GNUNET_CONTAINER_DLL_insert_after (h->tq_head, h->tq_tail, h->tq_tail, tqe); + ac = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) + hs); + ac->h = h; + ac->size = hs; + ac->cont = cont; + ac->cont_cls = cont_cls; + memcpy (&ac[1], hello, hs); + GNUNET_CONTAINER_DLL_insert_tail (h->ac_head, h->ac_tail, ac); trigger_transmit (h); + return ac; } /** - * Context for an iteration request. + * Cancel pending 'add' operation. Must only be called before + * either 'cont' or 'GNUNET_PEERINFO_disconnect' are invoked. + * + * @param ac handle for the add operation to cancel */ -struct GNUNET_PEERINFO_IteratorContext +void +GNUNET_PEERINFO_add_peer_cancel (struct GNUNET_PEERINFO_AddContext *ac) { - /** - * Handle to the PEERINFO service. - */ - struct GNUNET_PEERINFO_Handle *h; - - /** - * Function to call with the results. - */ - GNUNET_PEERINFO_Processor callback; + struct GNUNET_PEERINFO_Handle *h = ac->h; - /** - * Closure for 'callback'. - */ - void *callback_cls; - - /** - * Our entry in the transmission queue. - */ - struct TransmissionQueueEntry *tqe; - - /** - * Task responsible for timeout. - */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; - - /** - * Timeout for the operation. - */ - struct GNUNET_TIME_Absolute timeout; - - /** - * Are we now receiving? - */ - int in_receive; -}; + GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac); + GNUNET_free (ac); +} /** - * Type of a function to call when we receive a message - * from the service. + * Type of a function to call when we receive a message from the + * service. Call the iterator with the result and (if applicable) + * continue to receive more messages or trigger processing the next + * event (if applicable). * * @param cls closure * @param msg message received, NULL on timeout or fatal error @@ -419,81 +481,125 @@ struct GNUNET_PEERINFO_IteratorContext static void peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg) { - struct GNUNET_PEERINFO_IteratorContext *ic = cls; + struct GNUNET_PEERINFO_Handle *h = cls; + struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head; const struct InfoMessage *im; const struct GNUNET_HELLO_Message *hello; + GNUNET_PEERINFO_Processor cb; + struct GNUNET_PeerIdentity id; + void *cb_cls; uint16_t ms; - ic->h->in_receive = GNUNET_NO; - if (msg == NULL) + GNUNET_assert (NULL != ic); + h->in_receive = GNUNET_NO; + ic->in_receive = GNUNET_NO; + cb = ic->callback; + cb_cls = ic->callback_cls; + if (NULL == msg) { - reconnect (ic->h); - if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (ic->timeout_task); - if (ic->callback != NULL) - ic->callback (ic->callback_cls, NULL, NULL, - _("Failed to receive response from `PEERINFO' service.")); - GNUNET_free (ic); + /* peerinfo service died, signal error */ + GNUNET_PEERINFO_iterate_cancel (ic); + reconnect (h); + if (NULL != cb) + cb (cb_cls, NULL, NULL, + _("Failed to receive response from `PEERINFO' service.")); return; } - if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END) + + if (GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END == ntohs (msg->type)) { -#if DEBUG_PEERINFO + /* normal end of list of peers, signal end, process next pending request */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Received end of list of peers from `%s' service\n", "PEERINFO"); -#endif - trigger_transmit (ic->h); - if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (ic->timeout_task); - if (ic->callback != NULL) - ic->callback (ic->callback_cls, NULL, NULL, NULL); - GNUNET_free (ic); + GNUNET_PEERINFO_iterate_cancel (ic); + trigger_transmit (h); + if (NULL != cb) + cb (cb_cls, NULL, NULL, NULL); return; } + ms = ntohs (msg->size); if ((ms < sizeof (struct InfoMessage)) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO)) { + /* malformed message */ GNUNET_break (0); - reconnect (ic->h); - if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (ic->timeout_task); - if (ic->callback != NULL) - ic->callback (ic->callback_cls, NULL, NULL, - _("Received invalid message from `PEERINFO' service.\n")); - GNUNET_free (ic); + GNUNET_PEERINFO_iterate_cancel (ic); + reconnect (h); + if (NULL != cb) + cb (cb_cls, NULL, NULL, + _("Received invalid message from `PEERINFO' service.")); return; } im = (const struct InfoMessage *) msg; GNUNET_break (0 == ntohl (im->reserved)); + if ( (GNUNET_YES == ic->have_peer) && + (0 != memcmp (&ic->peer, &im->peer, sizeof (struct GNUNET_PeerIdentity))) ) + { + /* bogus message (from a different iteration call?); out of sequence! */ + LOG (GNUNET_ERROR_TYPE_ERROR, + "Received HELLO for peer `%s', expected peer `%s'\n", + GNUNET_h2s (&im->peer.hashPubKey), + GNUNET_i2s (&ic->peer)); + + GNUNET_break (0); + GNUNET_PEERINFO_iterate_cancel (ic); + reconnect (h); + if (NULL != cb) + cb (cb_cls, NULL, NULL, + _("Received invalid message from `PEERINFO' service.")); + return; + } hello = NULL; if (ms > sizeof (struct InfoMessage) + sizeof (struct GNUNET_MessageHeader)) { hello = (const struct GNUNET_HELLO_Message *) &im[1]; if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello)) { + /* malformed message */ GNUNET_break (0); - reconnect (ic->h); - if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (ic->timeout_task); - if (ic->callback != NULL) - ic->callback (ic->callback_cls, NULL, NULL, - _("Received invalid message from `PEERINFO' service.\n")); - GNUNET_free (ic); + GNUNET_PEERINFO_iterate_cancel (ic); + reconnect (h); + if (NULL != cb) + cb (cb_cls, NULL, NULL, + _("Received invalid message from `PEERINFO' service.")); + return; + } + if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &id)) + { + /* malformed message */ + GNUNET_break (0); + GNUNET_PEERINFO_iterate_cancel (ic); + reconnect (h); + if (NULL != cb) + cb (cb_cls, NULL, NULL, + _("Received invalid message from `PEERINFO' service.")); + return; + } + if (0 != memcmp (&im->peer, &id, sizeof (struct GNUNET_PeerIdentity))) + { + /* malformed message */ + GNUNET_break (0); + GNUNET_PEERINFO_iterate_cancel (ic); + reconnect (h); + if (NULL != cb) + cb (cb_cls, NULL, NULL, + _("Received invalid message from `PEERINFO' service.")); return; } } -#if DEBUG_PEERINFO + + /* normal data message */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Received %u bytes of `%s' information about peer `%s' from `%s' service\n", (hello == NULL) ? 0 : (unsigned int) GNUNET_HELLO_size (hello), "HELLO", GNUNET_i2s (&im->peer), "PEERINFO"); -#endif - ic->h->in_receive = GNUNET_YES; - if (ic->callback != NULL) - ic->callback (ic->callback_cls, &im->peer, hello, NULL); - GNUNET_CLIENT_receive (ic->h->client, &peerinfo_handler, ic, + h->in_receive = GNUNET_YES; + ic->in_receive = GNUNET_YES; + GNUNET_CLIENT_receive (h->client, &peerinfo_handler, h, GNUNET_TIME_absolute_get_remaining (ic->timeout)); + if (NULL != cb) + cb (cb_cls, &im->peer, hello, NULL); } @@ -502,37 +608,36 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg) * the results (or handle transmission error). * * @param cls the 'struct GNUNET_PEERINFO_IteratorContext' - * @param transmit_success GNUNET_OK if transmission worked + * @param emsg error message, NULL if transmission worked */ static void -iterator_start_receive (void *cls, int transmit_success) +iterator_start_receive (void *cls, const char *emsg) { struct GNUNET_PEERINFO_IteratorContext *ic = cls; + struct GNUNET_PEERINFO_Handle *h = ic->h; + GNUNET_PEERINFO_Processor cb; + void *cb_cls; - if (GNUNET_OK != transmit_success) + ic->ac = NULL; + if (NULL != emsg) { - if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (ic->timeout_task); - ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - reconnect (ic->h); - if (ic->callback != NULL) - ic->callback (ic->callback_cls, NULL, NULL, - _ - ("Failed to transmit iteration request to `PEERINFO' service\n")); - GNUNET_free (ic); + cb = ic->callback; + cb_cls = ic->callback_cls; + GNUNET_PEERINFO_iterate_cancel (ic); + reconnect (h); + if (NULL != cb) + cb (cb_cls, NULL, NULL, emsg); return; } -#if DEBUG_PEERINFO LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for response from `%s' service.\n", "PEERINFO"); -#endif - ic->h->in_receive = GNUNET_YES; ic->in_receive = GNUNET_YES; - ic->tqe = NULL; - GNUNET_CLIENT_receive (ic->h->client, &peerinfo_handler, ic, - GNUNET_TIME_absolute_get_remaining (ic->timeout)); + if (GNUNET_NO == h->in_receive) + { + h->in_receive = GNUNET_YES; + GNUNET_CLIENT_receive (h->client, &peerinfo_handler, h, + GNUNET_TIME_absolute_get_remaining (ic->timeout)); + } } @@ -546,18 +651,16 @@ static void signal_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_PEERINFO_IteratorContext *ic = cls; + GNUNET_PEERINFO_Processor cb; + void *cb_cls; ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; - if (!ic->in_receive) - GNUNET_CONTAINER_DLL_remove (ic->h->tq_head, ic->h->tq_tail, ic->tqe); - else - reconnect (ic->h); - ic->callback (ic->callback_cls, NULL, NULL, - _ - ("Timeout transmitting iteration request to `PEERINFO' service.\n")); - ic->callback = NULL; - GNUNET_free_non_null (ic->tqe); - GNUNET_free (ic); + cb = ic->callback; + cb_cls = ic->callback_cls; + GNUNET_PEERINFO_iterate_cancel (ic); + if (NULL != cb) + cb (cb_cls, NULL, NULL, + _("Timeout transmitting iteration request to `PEERINFO' service.")); } @@ -586,51 +689,50 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h, struct GNUNET_MessageHeader *lapm; struct ListPeerMessage *lpm; struct GNUNET_PEERINFO_IteratorContext *ic; - struct TransmissionQueueEntry *tqe; + struct GNUNET_PEERINFO_AddContext *ac; - if (peer == NULL) + ic = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_IteratorContext)); + if (NULL == peer) { -#if DEBUG_PEERINFO LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting list of peers from PEERINFO service\n"); -#endif - tqe = - GNUNET_malloc (sizeof (struct TransmissionQueueEntry) + + ac = + GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) + sizeof (struct GNUNET_MessageHeader)); - tqe->size = sizeof (struct GNUNET_MessageHeader); - lapm = (struct GNUNET_MessageHeader *) &tqe[1]; + ac->size = sizeof (struct GNUNET_MessageHeader); + lapm = (struct GNUNET_MessageHeader *) &ac[1]; lapm->size = htons (sizeof (struct GNUNET_MessageHeader)); lapm->type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL); } else { -#if DEBUG_PEERINFO LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting information on peer `%4s' from PEERINFO service\n", GNUNET_i2s (peer)); -#endif - tqe = - GNUNET_malloc (sizeof (struct TransmissionQueueEntry) + + ac = + GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) + sizeof (struct ListPeerMessage)); - tqe->size = sizeof (struct ListPeerMessage); - lpm = (struct ListPeerMessage *) &tqe[1]; + ac->size = sizeof (struct ListPeerMessage); + lpm = (struct ListPeerMessage *) &ac[1]; lpm->header.size = htons (sizeof (struct ListPeerMessage)); lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET); memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity)); + ic->have_peer = GNUNET_YES; + ic->peer = *peer; } - ic = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_IteratorContext)); ic->h = h; - ic->tqe = tqe; + ic->ac = ac; ic->callback = callback; ic->callback_cls = callback_cls; ic->timeout = GNUNET_TIME_relative_to_absolute (timeout); ic->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, &signal_timeout, ic); - tqe->timeout = ic->timeout; - tqe->cont = &iterator_start_receive; - tqe->cont_cls = ic; - tqe->timeout = ic->timeout; - GNUNET_CONTAINER_DLL_insert_after (h->tq_head, h->tq_tail, h->tq_tail, tqe); + ac->cont = &iterator_start_receive; + ac->cont_cls = ic; + GNUNET_CONTAINER_DLL_insert_tail (h->ac_head, h->ac_tail, ac); + GNUNET_CONTAINER_DLL_insert_tail (h->ic_head, + h->ic_tail, + ic); trigger_transmit (h); return ic; } @@ -644,7 +746,10 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h, void GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic) { - if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) + struct GNUNET_PEERINFO_Handle *h; + + h = ic->h; + if (GNUNET_SCHEDULER_NO_TASK != ic->timeout_task) { GNUNET_SCHEDULER_cancel (ic->timeout_task); ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; @@ -652,8 +757,14 @@ GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic) ic->callback = NULL; if (GNUNET_YES == ic->in_receive) return; /* need to finish processing */ - GNUNET_CONTAINER_DLL_remove (ic->h->tq_head, ic->h->tq_tail, ic->tqe); - GNUNET_free (ic->tqe); + GNUNET_CONTAINER_DLL_remove (h->ic_head, + h->ic_tail, + ic); + if (NULL != ic->ac) + { + GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ic->ac); + GNUNET_free (ic->ac); + } GNUNET_free (ic); } diff --git a/src/peerinfo/peerinfo_api_notify.c b/src/peerinfo/peerinfo_api_notify.c index a0588db..b9e83c9 100644 --- a/src/peerinfo/peerinfo_api_notify.c +++ b/src/peerinfo/peerinfo_api_notify.c @@ -133,7 +133,7 @@ process_notification (void *cls, const struct GNUNET_MessageHeader *msg) if (msg == NULL) { - GNUNET_CLIENT_disconnect (nc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (nc->client); reconnect (nc, NULL); return; } @@ -142,7 +142,7 @@ process_notification (void *cls, const struct GNUNET_MessageHeader *msg) (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO)) { GNUNET_break (0); - GNUNET_CLIENT_disconnect (nc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (nc->client); nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); request_notifications (nc); return; @@ -155,17 +155,15 @@ process_notification (void *cls, const struct GNUNET_MessageHeader *msg) if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello)) { GNUNET_break (0); - GNUNET_CLIENT_disconnect (nc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (nc->client); nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); request_notifications (nc); return; } } -#if DEBUG_PEERINFO LOG (GNUNET_ERROR_TYPE_DEBUG, "Received information about peer `%s' from peerinfo database\n", GNUNET_i2s (&im->peer)); -#endif nc->callback (nc->callback_cls, &im->peer, hello, NULL); receive_notifications (nc); } @@ -202,7 +200,7 @@ transmit_notify_request (void *cls, size_t size, void *buf) nc->init = NULL; if (buf == NULL) { - GNUNET_CLIENT_disconnect (nc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (nc->client); nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); request_notifications (nc); return 0; @@ -283,7 +281,7 @@ GNUNET_PEERINFO_notify_cancel (struct GNUNET_PEERINFO_NotifyContext *nc) nc->init = NULL; } if (NULL != nc->client) - GNUNET_CLIENT_disconnect (nc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (nc->client); if (GNUNET_SCHEDULER_NO_TASK != nc->task) GNUNET_SCHEDULER_cancel (nc->task); GNUNET_free (nc); diff --git a/src/peerinfo/perf_peerinfo_api.c b/src/peerinfo/perf_peerinfo_api.c old mode 100755 new mode 100644 index 3396930..34888fa --- a/src/peerinfo/perf_peerinfo_api.c +++ b/src/peerinfo/perf_peerinfo_api.c @@ -53,12 +53,6 @@ static int check_it (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { -#if DEBUG - if (addrlen > 0) - { - FPRINTF (stderr, "name: %s, addr: %s\n", tname, (const char *) addr); - } -#endif return GNUNET_OK; } @@ -98,7 +92,7 @@ add_peer (size_t i) memset (&pkey, i, sizeof (pkey)); GNUNET_CRYPTO_hash (&pkey, sizeof (pkey), &pid.hashPubKey); h2 = GNUNET_HELLO_create (&pkey, &address_generator, &i); - GNUNET_PEERINFO_add_peer (h, h2); + GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL); GNUNET_free (h2); } @@ -107,17 +101,8 @@ static void process (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg) { - if (peer == NULL) - { -#if DEBUG - FPRINTF (stderr, "Process received NULL response\n"); -#endif - } - else + if (NULL != peer) { -#if DEBUG - FPRINTF (stderr, "Processed a peer\n"); -#endif numpeers++; if (0 && (hello != NULL)) GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_it, NULL); @@ -153,11 +138,7 @@ check () char *const argv[] = { "perf-peerinfo-api", "-c", "test_peerinfo_api_data.conf", -#if DEBUG_PEERINFO - "-L", "DEBUG", -#else "-L", "ERROR", -#endif NULL }; #if START_SERVICE @@ -169,11 +150,7 @@ check () proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-peerinfo", "gnunet-service-peerinfo", -#if DEBUG_PEERINFO - "-L", "DEBUG", -#else "-L", "ERROR", -#endif "-c", "test_peerinfo_api_data.conf", NULL); #endif GNUNET_assert (NULL != proc); @@ -189,9 +166,8 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; - #endif return ok; } @@ -202,12 +178,9 @@ main (int argc, char *argv[]) { int ret = 0; + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-peerinfo"); GNUNET_log_setup ("perf_peerinfo_api", -#if DEBUG_PEERINFO - "DEBUG", -#else "ERROR", -#endif NULL); ret = check (); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-peerinfo"); diff --git a/src/peerinfo/test_peerinfo_api.c b/src/peerinfo/test_peerinfo_api.c index 71da46b..e66878e 100644 --- a/src/peerinfo/test_peerinfo_api.c +++ b/src/peerinfo/test_peerinfo_api.c @@ -96,7 +96,7 @@ add_peer () memset (&pkey, 32, sizeof (pkey)); GNUNET_CRYPTO_hash (&pkey, sizeof (pkey), &pid.hashPubKey); h2 = GNUNET_HELLO_create (&pkey, &address_generator, &agc); - GNUNET_PEERINFO_add_peer (h, h2); + GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL); GNUNET_free (h2); } @@ -170,9 +170,6 @@ check () char *const argv[] = { "test-peerinfo-api", "-c", "test_peerinfo_api_data.conf", -#if DEBUG_PEERINFO - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -181,9 +178,6 @@ check () proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-peerinfo", "gnunet-service-peerinfo", -#if DEBUG_PEERINFO - "-L", "DEBUG", -#endif "-c", "test_peerinfo_api_data.conf", NULL); GNUNET_assert (NULL != proc); GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, @@ -194,7 +188,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; return ok; } @@ -205,12 +199,9 @@ main (int argc, char *argv[]) { int ret = 0; + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-peerinfo"); GNUNET_log_setup ("test_peerinfo_api", -#if DEBUG_PEERINFO - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-peerinfo"); diff --git a/src/postgres/Makefile.am b/src/postgres/Makefile.am new file mode 100644 index 0000000..0b3be5e --- /dev/null +++ b/src/postgres/Makefile.am @@ -0,0 +1,20 @@ +INCLUDES = -I$(top_srcdir)/src/include + +if MINGW + WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +endif + +if USE_COVERAGE + AM_CFLAGS = --coverage +endif + +lib_LTLIBRARIES = libgnunetpostgres.la + +libgnunetpostgres_la_SOURCES = \ + postgres.c +libgnunetpostgres_la_LIBADD = -lpq \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunetpostgres_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + diff --git a/src/postgres/Makefile.in b/src/postgres/Makefile.in new file mode 100644 index 0000000..36d0f66 --- /dev/null +++ b/src/postgres/Makefile.in @@ -0,0 +1,654 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/postgres +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ + $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ + $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/gnunet_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libgnunetpostgres_la_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la +am_libgnunetpostgres_la_OBJECTS = postgres.lo +libgnunetpostgres_la_OBJECTS = $(am_libgnunetpostgres_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libgnunetpostgres_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libgnunetpostgres_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libgnunetpostgres_la_SOURCES) +DIST_SOURCES = $(libgnunetpostgres_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_INTERFACE = @DEFAULT_INTERFACE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLDIR = @DLLDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXT_LIBS = @EXT_LIBS@ +EXT_LIB_PATH = @EXT_LIB_PATH@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ +GN_DAEMON_CONFIG_DIR = @GN_DAEMON_CONFIG_DIR@ +GN_DAEMON_HOME_DIR = @GN_DAEMON_HOME_DIR@ +GN_INTLINCL = @GN_INTLINCL@ +GN_LIBINTL = @GN_LIBINTL@ +GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ +GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ +GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GREP = @GREP@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBPREFIX = @LIBPREFIX@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNISTRING = @LIBUNISTRING@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ +POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CPPFLAGS = @SQLITE_CPPFLAGS@ +SQLITE_LDFLAGS = @SQLITE_LDFLAGS@ +STRIP = @STRIP@ +SUDO_BINARY = @SUDO_BINARY@ +UNIXONLY = @UNIXONLY@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_OBJC = @ac_ct_OBJC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_target = @build_target@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/src/include +@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage +lib_LTLIBRARIES = libgnunetpostgres.la +libgnunetpostgres_la_SOURCES = \ + postgres.c + +libgnunetpostgres_la_LIBADD = -lpq \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunetpostgres_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/postgres/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/postgres/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgnunetpostgres.la: $(libgnunetpostgres_la_OBJECTS) $(libgnunetpostgres_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunetpostgres_la_LINK) -rpath $(libdir) $(libgnunetpostgres_la_OBJECTS) $(libgnunetpostgres_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/postgres.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/postgres/postgres.c b/src/postgres/postgres.c new file mode 100644 index 0000000..1001452 --- /dev/null +++ b/src/postgres/postgres.c @@ -0,0 +1,189 @@ +/* + This file is part of GNUnet + (C) 2009, 2010, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file postgres/postgres.c + * @brief library to help with access to a Postgres database + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_postgres_lib.h" + + +/** + * Check if the result obtained from Postgres has + * the desired status code. If not, log an error, clear the + * result and return GNUNET_SYSERR. + * + * @param dbh database handle + * @param ret return value from database operation to check + * @param expected_status desired status + * @param command description of the command that was run + * @param args arguments given to the command + * @param filename name of the source file where the command was run + * @param line line number in the source file + * @return GNUNET_OK if the result is acceptable + */ +int +GNUNET_POSTGRES_check_result_ (PGconn * dbh, PGresult * ret, + int expected_status, const char *command, + const char *args, const char *filename, int line) +{ + if (ret == NULL) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "postgres", + "Postgres failed to allocate result for `%s:%s' at %s:%d\n", + command, args, filename, line); + return GNUNET_SYSERR; + } + if (PQresultStatus (ret) != expected_status) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "postgres", _("`%s:%s' failed at %s:%d with error: %s"), + command, args, filename, line, PQerrorMessage (dbh)); + PQclear (ret); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Run simple SQL statement (without results). + * + * @param dbh database handle + * @param sql statement to run + * @param filename filename for error reporting + * @param line code line for error reporting + * @return GNUNET_OK on success + */ +int +GNUNET_POSTGRES_exec_ (PGconn * dbh, const char *sql, const char *filename, + int line) +{ + PGresult *ret; + + ret = PQexec (dbh, sql); + if (GNUNET_OK != + GNUNET_POSTGRES_check_result_ (dbh, ret, PGRES_COMMAND_OK, "PQexec", sql, + filename, line)) + return GNUNET_SYSERR; + PQclear (ret); + return GNUNET_OK; +} + + +/** + * Prepare SQL statement. + * + * @param dbh database handle + * @param name name for the prepared SQL statement + * @param sql SQL code to prepare + * @param nparms number of parameters in sql + * @param filename filename for error reporting + * @param line code line for error reporting + * @return GNUNET_OK on success + */ +int +GNUNET_POSTGRES_prepare_ (PGconn * dbh, const char *name, const char *sql, + int nparms, const char *filename, int line) +{ + PGresult *ret; + + ret = PQprepare (dbh, name, sql, nparms, NULL); + if (GNUNET_OK != + GNUNET_POSTGRES_check_result_ (dbh, ret, PGRES_COMMAND_OK, "PQprepare", + sql, filename, line)) + return GNUNET_SYSERR; + PQclear (ret); + return GNUNET_OK; +} + + +/** + * Connect to a postgres database + * + * @param cfg configuration + * @param section configuration section to use to get Postgres configuration options + * @return the postgres handle + */ +PGconn * +GNUNET_POSTGRES_connect (const struct GNUNET_CONFIGURATION_Handle * cfg, + const char *section) +{ + PGconn *dbh; + char *conninfo; + + /* Open database and precompile statements */ + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, section, "CONFIG", &conninfo)) + conninfo = NULL; + dbh = PQconnectdb (conninfo == NULL ? "" : conninfo); + GNUNET_free_non_null (conninfo); + if (NULL == dbh) + { + /* FIXME: warn about out-of-memory? */ + return NULL; + } + if (PQstatus (dbh) != CONNECTION_OK) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "postgres", + _("Unable to initialize Postgres: %s"), + PQerrorMessage (dbh)); + PQfinish (dbh); + return NULL; + } + return dbh; +} + + +/** + * Delete the row identified by the given rowid (qid + * in postgres). + * + * @param dbh database handle + * @param stmt name of the prepared statement + * @param rowid which row to delete + * @return GNUNET_OK on success + */ +int +GNUNET_POSTGRES_delete_by_rowid (PGconn * dbh, const char *stmt, uint32_t rowid) +{ + uint32_t brow = htonl (rowid); + const char *paramValues[] = { (const char *) &brow }; + int paramLengths[] = { sizeof (brow) }; + const int paramFormats[] = { 1 }; + PGresult *ret; + + ret = + PQexecPrepared (dbh, stmt, 1, paramValues, paramLengths, paramFormats, 1); + if (GNUNET_OK != + GNUNET_POSTGRES_check_result_ (dbh, ret, PGRES_COMMAND_OK, + "PQexecPrepared", "delrow", __FILE__, + __LINE__)) + { + return GNUNET_SYSERR; + } + PQclear (ret); + return GNUNET_OK; +} + + +/* end of postgres.c */ diff --git a/src/pt/Makefile.in b/src/pt/Makefile.in index ebdc995..ca3fee5 100644 --- a/src/pt/Makefile.in +++ b/src/pt/Makefile.in @@ -184,6 +184,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -217,6 +218,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/regex/Makefile.am b/src/regex/Makefile.am new file mode 100644 index 0000000..8c73c60 --- /dev/null +++ b/src/regex/Makefile.am @@ -0,0 +1,42 @@ +INCLUDES = -I$(top_srcdir)/src/include + +if MINGW + WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +endif + +if USE_COVERAGE + AM_CFLAGS = --coverage +endif + +lib_LTLIBRARIES = libgnunetregex.la + +libgnunetregex_la_SOURCES = \ + regex.c +libgnunetregex_la_LIBADD = -lm \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunetregex_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + +check_PROGRAMS = \ + test_regex_eval_api \ + test_regex_iterate_api + +if ENABLE_TEST_RUN +TESTS = $(check_PROGRAMS) +endif + +test_regex_eval_api_SOURCES = \ + test_regex_eval_api.c +test_regex_eval_api_LDADD = \ + $(top_builddir)/src/regex/libgnunetregex.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_regex_iterate_api_SOURCES = \ + test_regex_iterate_api.c +test_regex_iterate_api_LDADD = \ + $(top_builddir)/src/regex/libgnunetregex.la \ + $(top_builddir)/src/util/libgnunetutil.la + +EXTRA_DIST = +# test_regex_data.conf diff --git a/src/regex/Makefile.in b/src/regex/Makefile.in new file mode 100644 index 0000000..c0c0704 --- /dev/null +++ b/src/regex/Makefile.in @@ -0,0 +1,800 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +check_PROGRAMS = test_regex_eval_api$(EXEEXT) \ + test_regex_iterate_api$(EXEEXT) +subdir = src/regex +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ + $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ + $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/gnunet_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libgnunetregex_la_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la +am_libgnunetregex_la_OBJECTS = regex.lo +libgnunetregex_la_OBJECTS = $(am_libgnunetregex_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libgnunetregex_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libgnunetregex_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +am_test_regex_eval_api_OBJECTS = test_regex_eval_api.$(OBJEXT) +test_regex_eval_api_OBJECTS = $(am_test_regex_eval_api_OBJECTS) +test_regex_eval_api_DEPENDENCIES = \ + $(top_builddir)/src/regex/libgnunetregex.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_test_regex_iterate_api_OBJECTS = test_regex_iterate_api.$(OBJEXT) +test_regex_iterate_api_OBJECTS = $(am_test_regex_iterate_api_OBJECTS) +test_regex_iterate_api_DEPENDENCIES = \ + $(top_builddir)/src/regex/libgnunetregex.la \ + $(top_builddir)/src/util/libgnunetutil.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libgnunetregex_la_SOURCES) $(test_regex_eval_api_SOURCES) \ + $(test_regex_iterate_api_SOURCES) +DIST_SOURCES = $(libgnunetregex_la_SOURCES) \ + $(test_regex_eval_api_SOURCES) \ + $(test_regex_iterate_api_SOURCES) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_INTERFACE = @DEFAULT_INTERFACE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLDIR = @DLLDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXT_LIBS = @EXT_LIBS@ +EXT_LIB_PATH = @EXT_LIB_PATH@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ +GN_DAEMON_CONFIG_DIR = @GN_DAEMON_CONFIG_DIR@ +GN_DAEMON_HOME_DIR = @GN_DAEMON_HOME_DIR@ +GN_INTLINCL = @GN_INTLINCL@ +GN_LIBINTL = @GN_LIBINTL@ +GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ +GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ +GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GREP = @GREP@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBPREFIX = @LIBPREFIX@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNISTRING = @LIBUNISTRING@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ +POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CPPFLAGS = @SQLITE_CPPFLAGS@ +SQLITE_LDFLAGS = @SQLITE_LDFLAGS@ +STRIP = @STRIP@ +SUDO_BINARY = @SUDO_BINARY@ +UNIXONLY = @UNIXONLY@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_OBJC = @ac_ct_OBJC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_target = @build_target@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/src/include +@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage +lib_LTLIBRARIES = libgnunetregex.la +libgnunetregex_la_SOURCES = \ + regex.c + +libgnunetregex_la_LIBADD = -lm \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunetregex_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + +@ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) +test_regex_eval_api_SOURCES = \ + test_regex_eval_api.c + +test_regex_eval_api_LDADD = \ + $(top_builddir)/src/regex/libgnunetregex.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_regex_iterate_api_SOURCES = \ + test_regex_iterate_api.c + +test_regex_iterate_api_LDADD = \ + $(top_builddir)/src/regex/libgnunetregex.la \ + $(top_builddir)/src/util/libgnunetutil.la + +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/regex/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/regex/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgnunetregex.la: $(libgnunetregex_la_OBJECTS) $(libgnunetregex_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunetregex_la_LINK) -rpath $(libdir) $(libgnunetregex_la_OBJECTS) $(libgnunetregex_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +test_regex_eval_api$(EXEEXT): $(test_regex_eval_api_OBJECTS) $(test_regex_eval_api_DEPENDENCIES) + @rm -f test_regex_eval_api$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_regex_eval_api_OBJECTS) $(test_regex_eval_api_LDADD) $(LIBS) +test_regex_iterate_api$(EXEEXT): $(test_regex_iterate_api_OBJECTS) $(test_regex_iterate_api_DEPENDENCIES) + @rm -f test_regex_iterate_api$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_regex_iterate_api_OBJECTS) $(test_regex_iterate_api_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_regex_eval_api.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_regex_iterate_api.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-libLTLIBRARIES + +# test_regex_data.conf + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/regex/regex.c b/src/regex/regex.c new file mode 100644 index 0000000..5244c26 --- /dev/null +++ b/src/regex/regex.c @@ -0,0 +1,2252 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file src/regex/regex.c + * @brief library to create automatons from regular expressions + * @author Maximilian Szengel + */ +#include "platform.h" +#include "gnunet_container_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_regex_lib.h" +#include "regex.h" + +#define initial_bits 10 + +/** + * Context that contains an id counter for states and transitions as well as a + * DLL of automatons used as a stack for NFA construction. + */ +struct GNUNET_REGEX_Context +{ + /** + * Unique state id. + */ + unsigned int state_id; + + /** + * Unique transition id. + */ + unsigned int transition_id; + + /** + * Unique SCC (Strongly Connected Component) id. + */ + unsigned int scc_id; + + /** + * DLL of GNUNET_REGEX_Automaton's used as a stack. + */ + struct GNUNET_REGEX_Automaton *stack_head; + + /** + * DLL of GNUNET_REGEX_Automaton's used as a stack. + */ + struct GNUNET_REGEX_Automaton *stack_tail; +}; + +/** + * Type of an automaton. + */ +enum GNUNET_REGEX_automaton_type +{ + NFA, + DFA +}; + +/** + * Automaton representation. + */ +struct GNUNET_REGEX_Automaton +{ + /** + * This is a linked list. + */ + struct GNUNET_REGEX_Automaton *prev; + + /** + * This is a linked list. + */ + struct GNUNET_REGEX_Automaton *next; + + /** + * First state of the automaton. This is mainly used for constructing an NFA, + * where each NFA itself consists of one or more NFAs linked together. + */ + struct GNUNET_REGEX_State *start; + + /** + * End state of the automaton. + */ + struct GNUNET_REGEX_State *end; + + /** + * Number of states in the automaton. + */ + unsigned int state_count; + + /** + * DLL of states. + */ + struct GNUNET_REGEX_State *states_head; + + /** + * DLL of states + */ + struct GNUNET_REGEX_State *states_tail; + + /** + * Type of the automaton. + */ + enum GNUNET_REGEX_automaton_type type; +}; + +/** + * A state. Can be used in DFA and NFA automatons. + */ +struct GNUNET_REGEX_State +{ + /** + * This is a linked list. + */ + struct GNUNET_REGEX_State *prev; + + /** + * This is a linked list. + */ + struct GNUNET_REGEX_State *next; + + /** + * Unique state id. + */ + unsigned int id; + + /** + * If this is an accepting state or not. + */ + int accepting; + + /** + * Marking of the state. This is used for marking all visited states when + * traversing all states of an automaton and for cases where the state id + * cannot be used (dfa minimization). + */ + int marked; + + /** + * Marking the state as contained. This is used for checking, if the state is + * contained in a set in constant time + */ + int contained; + + /** + * Marking the state as part of an SCC (Strongly Connected Component). All + * states with the same scc_id are part of the same SCC. scc_id is 0, if state + * is not a part of any SCC. + */ + unsigned int scc_id; + + /** + * Used for SCC detection. + */ + int index; + + /** + * Used for SCC detection. + */ + int lowlink; + + /** + * Human readable name of the automaton. Used for debugging and graph + * creation. + */ + char *name; + + /** + * Hash of the state. + */ + GNUNET_HashCode hash; + + /** + * Proof for this state. + */ + char *proof; + + /** + * Number of transitions from this state to other states. + */ + unsigned int transition_count; + + /** + * DLL of transitions. + */ + struct Transition *transitions_head; + + /** + * DLL of transitions. + */ + struct Transition *transitions_tail; + + /** + * Set of states on which this state is based on. Used when creating a DFA out + * of several NFA states. + */ + struct GNUNET_REGEX_StateSet *nfa_set; +}; + +/** + * Transition between two states. Each state can have 0-n transitions. If label + * is 0, this is considered to be an epsilon transition. + */ +struct Transition +{ + /** + * This is a linked list. + */ + struct Transition *prev; + + /** + * This is a linked list. + */ + struct Transition *next; + + /** + * Unique id of this transition. + */ + unsigned int id; + + /** + * Label for this transition. This is basically the edge label for the graph. + */ + char label; + + /** + * State to which this transition leads. + */ + struct GNUNET_REGEX_State *to_state; + + /** + * State from which this transition origins. + */ + struct GNUNET_REGEX_State *from_state; + + /** + * Mark this transition. For example when reversing the automaton. + */ + int mark; +}; + +/** + * Set of states. + */ +struct GNUNET_REGEX_StateSet +{ + /** + * Array of states. + */ + struct GNUNET_REGEX_State **states; + + /** + * Length of the 'states' array. + */ + unsigned int len; +}; + +/* + * Debug helper functions + */ +void +debug_print_transitions (struct GNUNET_REGEX_State *); + +void +debug_print_state (struct GNUNET_REGEX_State *s) +{ + char *proof; + + if (NULL == s->proof) + proof = "NULL"; + else + proof = s->proof; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "State %i: %s marked: %i accepting: %i scc_id: %i transitions: %i proof: %s\n", + s->id, s->name, s->marked, s->accepting, s->scc_id, + s->transition_count, proof); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transitions:\n"); + debug_print_transitions (s); +} + +void +debug_print_states (struct GNUNET_REGEX_Automaton *a) +{ + struct GNUNET_REGEX_State *s; + + for (s = a->states_head; NULL != s; s = s->next) + debug_print_state (s); +} + +void +debug_print_transition (struct Transition *t) +{ + char *to_state; + char *from_state; + char label; + + if (NULL == t) + return; + + if (0 == t->label) + label = '0'; + else + label = t->label; + + if (NULL == t->to_state) + to_state = "NULL"; + else + to_state = t->to_state->name; + + if (NULL == t->from_state) + from_state = "NULL"; + else + from_state = t->from_state->name; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transition %i: From %s on %c to %s\n", + t->id, from_state, label, to_state); +} + +void +debug_print_transitions (struct GNUNET_REGEX_State *s) +{ + struct Transition *t; + + for (t = s->transitions_head; NULL != t; t = t->next) + debug_print_transition (t); +} + +/** + * Recursive function doing DFS with 'v' as a start, detecting all SCCs inside + * the subgraph reachable from 'v'. Used with scc_tarjan function to detect all + * SCCs inside an automaton. + * + * @param ctx context + * @param v start vertex + * @param index current index + * @param stack stack for saving all SCCs + * @param stack_size current size of the stack + */ +static void +scc_tarjan_strongconnect (struct GNUNET_REGEX_Context *ctx, + struct GNUNET_REGEX_State *v, int *index, + struct GNUNET_REGEX_State **stack, + unsigned int *stack_size) +{ + struct GNUNET_REGEX_State *w; + struct Transition *t; + + v->index = *index; + v->lowlink = *index; + (*index)++; + stack[(*stack_size)++] = v; + v->contained = 1; + + for (t = v->transitions_head; NULL != t; t = t->next) + { + w = t->to_state; + if (NULL != w && w->index < 0) + { + scc_tarjan_strongconnect (ctx, w, index, stack, stack_size); + v->lowlink = (v->lowlink > w->lowlink) ? w->lowlink : v->lowlink; + } + else if (0 != w->contained) + v->lowlink = (v->lowlink > w->index) ? w->index : v->lowlink; + } + + if (v->lowlink == v->index) + { + w = stack[--(*stack_size)]; + w->contained = 0; + + if (v != w) + { + ctx->scc_id++; + while (v != w) + { + w->scc_id = ctx->scc_id; + w = stack[--(*stack_size)]; + w->contained = 0; + } + w->scc_id = ctx->scc_id; + } + } +} + +/** + * Detect all SCCs (Strongly Connected Components) inside the given automaton. + * SCCs will be marked using the scc_id on each state. + * + * @param ctx context + * @param a automaton + */ +static void +scc_tarjan (struct GNUNET_REGEX_Context *ctx, struct GNUNET_REGEX_Automaton *a) +{ + int index; + struct GNUNET_REGEX_State *v; + struct GNUNET_REGEX_State *stack[a->state_count]; + unsigned int stack_size; + + for (v = a->states_head; NULL != v; v = v->next) + { + v->contained = 0; + v->index = -1; + v->lowlink = -1; + } + + stack_size = 0; + index = 0; + + for (v = a->states_head; NULL != v; v = v->next) + { + if (v->index < 0) + scc_tarjan_strongconnect (ctx, v, &index, stack, &stack_size); + } +} + +/** + * Adds a transition from one state to another on 'label'. Does not add + * duplicate states. + * + * @param ctx context + * @param from_state starting state for the transition + * @param label transition label + * @param to_state state to where the transition should point to + */ +static void +state_add_transition (struct GNUNET_REGEX_Context *ctx, + struct GNUNET_REGEX_State *from_state, const char label, + struct GNUNET_REGEX_State *to_state) +{ + int is_dup; + struct Transition *t; + + if (NULL == from_state) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not create Transition.\n"); + return; + } + + // Do not add duplicate state transitions + is_dup = GNUNET_NO; + for (t = from_state->transitions_head; NULL != t; t = t->next) + { + if (t->to_state == to_state && t->label == label && + t->from_state == from_state) + { + is_dup = GNUNET_YES; + break; + } + } + + if (is_dup) + return; + + t = GNUNET_malloc (sizeof (struct Transition)); + t->id = ctx->transition_id++; + t->label = label; + t->to_state = to_state; + t->from_state = from_state; + + // Add outgoing transition to 'from_state' + from_state->transition_count++; + GNUNET_CONTAINER_DLL_insert (from_state->transitions_head, + from_state->transitions_tail, t); +} + +/** + * Compare two states. Used for sorting. + * + * @param a first state + * @param b second state + * + * @return an integer less than, equal to, or greater than zero + * if the first argument is considered to be respectively + * less than, equal to, or greater than the second. + */ +static int +state_compare (const void *a, const void *b) +{ + struct GNUNET_REGEX_State **s1; + struct GNUNET_REGEX_State **s2; + + s1 = (struct GNUNET_REGEX_State **) a; + s2 = (struct GNUNET_REGEX_State **) b; + + return (*s1)->id - (*s2)->id; +} + +/** + * Get all edges leaving state 's'. + * + * @param s state. + * @param edges all edges leaving 's'. + * + * @return number of edges. + */ +static unsigned int +state_get_edges (struct GNUNET_REGEX_State *s, struct GNUNET_REGEX_Edge *edges) +{ + struct Transition *t; + unsigned int count; + + if (NULL == s) + return 0; + + count = 0; + + for (t = s->transitions_head; NULL != t; t = t->next) + { + if (NULL != t->to_state) + { + edges[count].label = &t->label; + edges[count].destination = t->to_state->hash; + count++; + } + } + return count; +} + +/** + * Compare to state sets by comparing the id's of the states that are contained + * in each set. Both sets are expected to be sorted by id! + * + * @param sset1 first state set + * @param sset2 second state set + * + * @return an integer less than, equal to, or greater than zero + * if the first argument is considered to be respectively + * less than, equal to, or greater than the second. + */ +static int +state_set_compare (struct GNUNET_REGEX_StateSet *sset1, + struct GNUNET_REGEX_StateSet *sset2) +{ + int result; + int i; + + if (NULL == sset1 || NULL == sset2) + return 1; + + result = sset1->len - sset2->len; + + for (i = 0; i < sset1->len; i++) + { + if (0 != result) + break; + + result = state_compare (&sset1->states[i], &sset2->states[i]); + } + return result; +} + +/** + * Clears the given StateSet 'set' + * + * @param set set to be cleared + */ +static void +state_set_clear (struct GNUNET_REGEX_StateSet *set) +{ + if (NULL != set) + { + if (NULL != set->states) + GNUNET_free (set->states); + GNUNET_free (set); + } +} + +/** + * Clears an automaton fragment. Does not destroy the states inside the + * automaton. + * + * @param a automaton to be cleared + */ +static void +automaton_fragment_clear (struct GNUNET_REGEX_Automaton *a) +{ + if (NULL == a) + return; + + a->start = NULL; + a->end = NULL; + a->states_head = NULL; + a->states_tail = NULL; + a->state_count = 0; + GNUNET_free (a); +} + +/** + * Frees the memory used by State 's' + * + * @param s state that should be destroyed + */ +static void +automaton_destroy_state (struct GNUNET_REGEX_State *s) +{ + struct Transition *t; + struct Transition *next_t; + + if (NULL == s) + return; + + if (NULL != s->name) + GNUNET_free (s->name); + + if (NULL != s->proof) + GNUNET_free (s->proof); + + for (t = s->transitions_head; NULL != t; t = next_t) + { + next_t = t->next; + GNUNET_CONTAINER_DLL_remove (s->transitions_head, s->transitions_tail, t); + GNUNET_free (t); + } + + state_set_clear (s->nfa_set); + + GNUNET_free (s); +} + +/** + * Remove a state from the given automaton 'a'. Always use this function when + * altering the states of an automaton. Will also remove all transitions leading + * to this state, before destroying it. + * + * @param a automaton + * @param s state to remove + */ +static void +automaton_remove_state (struct GNUNET_REGEX_Automaton *a, + struct GNUNET_REGEX_State *s) +{ + struct GNUNET_REGEX_State *ss; + struct GNUNET_REGEX_State *s_check; + struct Transition *t_check; + + if (NULL == a || NULL == s) + return; + + // remove state + ss = s; + GNUNET_CONTAINER_DLL_remove (a->states_head, a->states_tail, s); + a->state_count--; + + // remove all transitions leading to this state + for (s_check = a->states_head; NULL != s_check; s_check = s_check->next) + { + for (t_check = s_check->transitions_head; NULL != t_check; + t_check = t_check->next) + { + if (t_check->to_state == ss) + { + GNUNET_CONTAINER_DLL_remove (s_check->transitions_head, + s_check->transitions_tail, t_check); + s_check->transition_count--; + } + } + } + + automaton_destroy_state (ss); +} + +/** + * Merge two states into one. Will merge 's1' and 's2' into 's1' and destroy + * 's2'. + * + * @param ctx context + * @param a automaton + * @param s1 first state + * @param s2 second state, will be destroyed + */ +static void +automaton_merge_states (struct GNUNET_REGEX_Context *ctx, + struct GNUNET_REGEX_Automaton *a, + struct GNUNET_REGEX_State *s1, + struct GNUNET_REGEX_State *s2) +{ + struct GNUNET_REGEX_State *s_check; + struct Transition *t_check; + char *new_name; + + GNUNET_assert (NULL != ctx && NULL != a && NULL != s1 && NULL != s2); + + if (s1 == s2) + return; + + // 1. Make all transitions pointing to s2 point to s1 + for (s_check = a->states_head; NULL != s_check; s_check = s_check->next) + { + for (t_check = s_check->transitions_head; NULL != t_check; + t_check = t_check->next) + { + if (s2 == t_check->to_state) + t_check->to_state = s1; + } + } + + // 2. Add all transitions from s2 to sX to s1 + for (t_check = s2->transitions_head; NULL != t_check; t_check = t_check->next) + { + if (t_check->to_state != s1) + state_add_transition (ctx, s1, t_check->label, t_check->to_state); + } + + // 3. Rename s1 to {s1,s2} + new_name = GNUNET_strdup (s1->name); + if (NULL != s1->name) + { + GNUNET_free (s1->name); + s1->name = NULL; + } + GNUNET_asprintf (&s1->name, "{%s,%s}", new_name, s2->name); + GNUNET_free (new_name); + + // remove state + GNUNET_CONTAINER_DLL_remove (a->states_head, a->states_tail, s2); + a->state_count--; + automaton_destroy_state (s2); +} + +/** + * Add a state to the automaton 'a', always use this function to alter the + * states DLL of the automaton. + * + * @param a automaton to add the state to + * @param s state that should be added + */ +static void +automaton_add_state (struct GNUNET_REGEX_Automaton *a, + struct GNUNET_REGEX_State *s) +{ + GNUNET_CONTAINER_DLL_insert (a->states_head, a->states_tail, s); + a->state_count++; +} + +/** + * Function that is called with each state, when traversing an automaton. + * + * @param cls closure + * @param s state + */ +typedef void (*GNUNET_REGEX_traverse_action) (void *cls, + struct GNUNET_REGEX_State * s); + +/** + * Traverses all states that are reachable from state 's'. Expects the states to + * be unmarked (s->marked == GNUNET_NO). Performs 'action' on each visited + * state. + * + * @param cls closure. + * @param s start state. + * @param action action to be performed on each state. + */ +static void +automaton_state_traverse (void *cls, struct GNUNET_REGEX_State *s, + GNUNET_REGEX_traverse_action action) +{ + struct Transition *t; + + if (GNUNET_NO == s->marked) + { + s->marked = GNUNET_YES; + + if (action > 0) + action (cls, s); + + for (t = s->transitions_head; NULL != t; t = t->next) + automaton_state_traverse (cls, t->to_state, action); + } +} + +/** + * Traverses the given automaton from it's start state, visiting all reachable + * states and calling 'action' on each one of them. + * + * @param cls closure. + * @param a automaton. + * @param action action to be performed on each state. + */ +static void +automaton_traverse (void *cls, struct GNUNET_REGEX_Automaton *a, + GNUNET_REGEX_traverse_action action) +{ + struct GNUNET_REGEX_State *s; + + for (s = a->states_head; NULL != s; s = s->next) + s->marked = GNUNET_NO; + + automaton_state_traverse (cls, a->start, action); +} + +/** + * Reverses all transitions of the given automaton. + * + * @param a automaton. + */ +static void +automaton_reverse (struct GNUNET_REGEX_Automaton *a) +{ + struct GNUNET_REGEX_State *s; + struct Transition *t; + struct Transition *t_next; + struct GNUNET_REGEX_State *s_swp; + + for (s = a->states_head; NULL != s; s = s->next) + for (t = s->transitions_head; NULL != t; t = t->next) + t->mark = GNUNET_NO; + + for (s = a->states_head; NULL != s; s = s->next) + { + for (t = s->transitions_head; NULL != t; t = t_next) + { + t_next = t->next; + + if (GNUNET_YES == t->mark || t->from_state == t->to_state) + continue; + + t->mark = GNUNET_YES; + + GNUNET_CONTAINER_DLL_remove (t->from_state->transitions_head, + t->from_state->transitions_tail, t); + t->from_state->transition_count--; + GNUNET_CONTAINER_DLL_insert (t->to_state->transitions_head, + t->to_state->transitions_tail, t); + t->to_state->transition_count++; + + s_swp = t->from_state; + t->from_state = t->to_state; + t->to_state = s_swp; + } + } +} + +/** + * Create proof for the given state. + * + * @param cls closure. + * @param s state. + */ +static void +automaton_create_proofs_step (void *cls, struct GNUNET_REGEX_State *s) +{ + struct Transition *t; + int i; + char *tmp; + + for (i = 0, t = s->transitions_head; NULL != t; t = t->next, i++) + { + if (t->to_state == s) + GNUNET_asprintf (&tmp, "%c*", t->label); + else if (i != s->transition_count - 1) + GNUNET_asprintf (&tmp, "%c|", t->label); + else + GNUNET_asprintf (&tmp, "%c", t->label); + + if (NULL != s->proof) + s->proof = + GNUNET_realloc (s->proof, strlen (s->proof) + strlen (tmp) + 1); + else + s->proof = GNUNET_malloc (strlen (tmp) + 1); + strcat (s->proof, tmp); + GNUNET_free (tmp); + } +} + +/** + * Create proofs for all states in the given automaton. + * + * @param a automaton. + */ +static void +automaton_create_proofs (struct GNUNET_REGEX_Automaton *a) +{ + struct GNUNET_REGEX_State *s; + + automaton_reverse (a); + + for (s = a->states_head; NULL != s; s = s->next) + automaton_create_proofs_step (NULL, s); + + automaton_reverse (a); +} + +/** + * Creates a new DFA state based on a set of NFA states. Needs to be freed using + * automaton_destroy_state. + * + * @param ctx context + * @param nfa_states set of NFA states on which the DFA should be based on + * + * @return new DFA state + */ +static struct GNUNET_REGEX_State * +dfa_state_create (struct GNUNET_REGEX_Context *ctx, + struct GNUNET_REGEX_StateSet *nfa_states) +{ + struct GNUNET_REGEX_State *s; + char *name; + int len = 0; + struct GNUNET_REGEX_State *cstate; + struct Transition *ctran; + int insert = 1; + struct Transition *t; + int i; + + s = GNUNET_malloc (sizeof (struct GNUNET_REGEX_State)); + s->id = ctx->state_id++; + s->accepting = 0; + s->marked = 0; + s->name = NULL; + s->scc_id = 0; + s->index = -1; + s->lowlink = -1; + s->contained = 0; + s->proof = NULL; + + if (NULL == nfa_states) + { + GNUNET_asprintf (&s->name, "s%i", s->id); + return s; + } + + s->nfa_set = nfa_states; + + if (nfa_states->len < 1) + return s; + + // Create a name based on 'sset' + s->name = GNUNET_malloc (sizeof (char) * 2); + strcat (s->name, "{"); + name = NULL; + + for (i = 0; i < nfa_states->len; i++) + { + cstate = nfa_states->states[i]; + GNUNET_asprintf (&name, "%i,", cstate->id); + + if (NULL != name) + { + len = strlen (s->name) + strlen (name) + 1; + s->name = GNUNET_realloc (s->name, len); + strcat (s->name, name); + GNUNET_free (name); + name = NULL; + } + + // Add a transition for each distinct label to NULL state + for (ctran = cstate->transitions_head; NULL != ctran; ctran = ctran->next) + { + if (0 != ctran->label) + { + insert = 1; + + for (t = s->transitions_head; NULL != t; t = t->next) + { + if (t->label == ctran->label) + { + insert = 0; + break; + } + } + + if (insert) + state_add_transition (ctx, s, ctran->label, NULL); + } + } + + // If the nfa_states contain an accepting state, the new dfa state is also + // accepting + if (cstate->accepting) + s->accepting = 1; + } + + s->name[strlen (s->name) - 1] = '}'; + + return s; +} + +/** + * Move from the given state 's' to the next state on transition 'label' + * + * @param s starting state + * @param label edge label to follow + * + * @return new state or NULL, if transition on label not possible + */ +static struct GNUNET_REGEX_State * +dfa_move (struct GNUNET_REGEX_State *s, const char label) +{ + struct Transition *t; + struct GNUNET_REGEX_State *new_s; + + if (NULL == s) + return NULL; + + new_s = NULL; + + for (t = s->transitions_head; NULL != t; t = t->next) + { + if (label == t->label) + { + new_s = t->to_state; + break; + } + } + + return new_s; +} + +/** + * Remove all unreachable states from DFA 'a'. Unreachable states are those + * states that are not reachable from the starting state. + * + * @param a DFA automaton + */ +static void +dfa_remove_unreachable_states (struct GNUNET_REGEX_Automaton *a) +{ + struct GNUNET_REGEX_State *s; + struct GNUNET_REGEX_State *s_next; + + // 1. unmark all states + for (s = a->states_head; NULL != s; s = s->next) + s->marked = GNUNET_NO; + + // 2. traverse dfa from start state and mark all visited states + automaton_traverse (NULL, a, NULL); + + // 3. delete all states that were not visited + for (s = a->states_head; NULL != s; s = s_next) + { + s_next = s->next; + if (GNUNET_NO == s->marked) + automaton_remove_state (a, s); + } +} + +/** + * Remove all dead states from the DFA 'a'. Dead states are those states that do + * not transition to any other state but themselfes. + * + * @param a DFA automaton + */ +static void +dfa_remove_dead_states (struct GNUNET_REGEX_Automaton *a) +{ + struct GNUNET_REGEX_State *s; + struct Transition *t; + int dead; + + GNUNET_assert (DFA == a->type); + + for (s = a->states_head; NULL != s; s = s->next) + { + if (s->accepting) + continue; + + dead = 1; + for (t = s->transitions_head; NULL != t; t = t->next) + { + if (NULL != t->to_state && t->to_state != s) + { + dead = 0; + break; + } + } + + if (0 == dead) + continue; + + // state s is dead, remove it + automaton_remove_state (a, s); + } +} + +/** + * Merge all non distinguishable states in the DFA 'a' + * + * @param ctx context + * @param a DFA automaton + */ +static void +dfa_merge_nondistinguishable_states (struct GNUNET_REGEX_Context *ctx, + struct GNUNET_REGEX_Automaton *a) +{ + int i; + int table[a->state_count][a->state_count]; + struct GNUNET_REGEX_State *s1; + struct GNUNET_REGEX_State *s2; + struct Transition *t1; + struct Transition *t2; + struct GNUNET_REGEX_State *s1_next; + struct GNUNET_REGEX_State *s2_next; + int change; + int num_equal_edges; + + for (i = 0, s1 = a->states_head; i < a->state_count && NULL != s1; + i++, s1 = s1->next) + { + s1->marked = i; + } + + // Mark all pairs of accepting/!accepting states + for (s1 = a->states_head; NULL != s1; s1 = s1->next) + { + for (s2 = a->states_head; NULL != s2; s2 = s2->next) + { + table[s1->marked][s2->marked] = 0; + + if ((s1->accepting && !s2->accepting) || + (!s1->accepting && s2->accepting)) + { + table[s1->marked][s2->marked] = 1; + } + } + } + + // Find all equal states + change = 1; + while (0 != change) + { + change = 0; + for (s1 = a->states_head; NULL != s1; s1 = s1->next) + { + for (s2 = a->states_head; NULL != s2 && s1 != s2; s2 = s2->next) + { + if (0 != table[s1->marked][s2->marked]) + continue; + + num_equal_edges = 0; + for (t1 = s1->transitions_head; NULL != t1; t1 = t1->next) + { + for (t2 = s2->transitions_head; NULL != t2; t2 = t2->next) + { + if (t1->label == t2->label) + { + num_equal_edges++; + if (0 != table[t1->to_state->marked][t2->to_state->marked] || + 0 != table[t2->to_state->marked][t1->to_state->marked]) + { + table[s1->marked][s2->marked] = t1->label != 0 ? t1->label : 1; + change = 1; + } + } + } + } + if (num_equal_edges != s1->transition_count || + num_equal_edges != s2->transition_count) + { + // Make sure ALL edges of possible equal states are the same + table[s1->marked][s2->marked] = -2; + } + } + } + } + + // Merge states that are equal + for (s1 = a->states_head; NULL != s1; s1 = s1_next) + { + s1_next = s1->next; + for (s2 = a->states_head; NULL != s2 && s1 != s2; s2 = s2_next) + { + s2_next = s2->next; + if (table[s1->marked][s2->marked] == 0) + automaton_merge_states (ctx, a, s1, s2); + } + } +} + +/** + * Minimize the given DFA 'a' by removing all unreachable states, removing all + * dead states and merging all non distinguishable states + * + * @param ctx context + * @param a DFA automaton + */ +static void +dfa_minimize (struct GNUNET_REGEX_Context *ctx, + struct GNUNET_REGEX_Automaton *a) +{ + if (NULL == a) + return; + + GNUNET_assert (DFA == a->type); + + // 1. remove unreachable states + dfa_remove_unreachable_states (a); + + // 2. remove dead states + dfa_remove_dead_states (a); + + // 3. Merge nondistinguishable states + dfa_merge_nondistinguishable_states (ctx, a); +} + +/** + * Creates a new NFA fragment. Needs to be cleared using + * automaton_fragment_clear. + * + * @param start starting state + * @param end end state + * + * @return new NFA fragment + */ +static struct GNUNET_REGEX_Automaton * +nfa_fragment_create (struct GNUNET_REGEX_State *start, + struct GNUNET_REGEX_State *end) +{ + struct GNUNET_REGEX_Automaton *n; + + n = GNUNET_malloc (sizeof (struct GNUNET_REGEX_Automaton)); + + n->type = NFA; + n->start = NULL; + n->end = NULL; + + if (NULL == start && NULL == end) + return n; + + automaton_add_state (n, end); + automaton_add_state (n, start); + + n->start = start; + n->end = end; + + return n; +} + +/** + * Adds a list of states to the given automaton 'n'. + * + * @param n automaton to which the states should be added + * @param states_head head of the DLL of states + * @param states_tail tail of the DLL of states + */ +static void +nfa_add_states (struct GNUNET_REGEX_Automaton *n, + struct GNUNET_REGEX_State *states_head, + struct GNUNET_REGEX_State *states_tail) +{ + struct GNUNET_REGEX_State *s; + + if (NULL == n || NULL == states_head) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not add states\n"); + return; + } + + if (NULL == n->states_head) + { + n->states_head = states_head; + n->states_tail = states_tail; + return; + } + + if (NULL != states_head) + { + n->states_tail->next = states_head; + n->states_tail = states_tail; + } + + for (s = states_head; NULL != s; s = s->next) + n->state_count++; +} + +/** + * Creates a new NFA state. Needs to be freed using automaton_destroy_state. + * + * @param ctx context + * @param accepting is it an accepting state or not + * + * @return new NFA state + */ +static struct GNUNET_REGEX_State * +nfa_state_create (struct GNUNET_REGEX_Context *ctx, int accepting) +{ + struct GNUNET_REGEX_State *s; + + s = GNUNET_malloc (sizeof (struct GNUNET_REGEX_State)); + s->id = ctx->state_id++; + s->accepting = accepting; + s->marked = 0; + s->contained = 0; + s->index = -1; + s->lowlink = -1; + s->scc_id = 0; + s->name = NULL; + GNUNET_asprintf (&s->name, "s%i", s->id); + + return s; +} + +/** + * Calculates the NFA closure set for the given state. + * + * @param nfa the NFA containing 's' + * @param s starting point state + * @param label transitioning label on which to base the closure on, + * pass 0 for epsilon transition + * + * @return sorted nfa closure on 'label' (epsilon closure if 'label' is 0) + */ +static struct GNUNET_REGEX_StateSet * +nfa_closure_create (struct GNUNET_REGEX_Automaton *nfa, + struct GNUNET_REGEX_State *s, const char label) +{ + struct GNUNET_REGEX_StateSet *cls; + struct GNUNET_REGEX_StateSet *cls_check; + struct GNUNET_REGEX_State *clsstate; + struct GNUNET_REGEX_State *currentstate; + struct Transition *ctran; + + if (NULL == s) + return NULL; + + cls = GNUNET_malloc (sizeof (struct GNUNET_REGEX_StateSet)); + cls_check = GNUNET_malloc (sizeof (struct GNUNET_REGEX_StateSet)); + + for (clsstate = nfa->states_head; NULL != clsstate; clsstate = clsstate->next) + clsstate->contained = 0; + + // Add start state to closure only for epsilon closure + if (0 == label) + GNUNET_array_append (cls->states, cls->len, s); + + GNUNET_array_append (cls_check->states, cls_check->len, s); + while (cls_check->len > 0) + { + currentstate = cls_check->states[cls_check->len - 1]; + GNUNET_array_grow (cls_check->states, cls_check->len, cls_check->len - 1); + + for (ctran = currentstate->transitions_head; NULL != ctran; + ctran = ctran->next) + { + if (NULL != ctran->to_state && label == ctran->label) + { + clsstate = ctran->to_state; + + if (NULL != clsstate && 0 == clsstate->contained) + { + GNUNET_array_append (cls->states, cls->len, clsstate); + GNUNET_array_append (cls_check->states, cls_check->len, clsstate); + clsstate->contained = 1; + } + } + } + } + GNUNET_assert (0 == cls_check->len); + GNUNET_free (cls_check); + + if (cls->len > 1) + qsort (cls->states, cls->len, sizeof (struct GNUNET_REGEX_State *), + state_compare); + + return cls; +} + +/** + * Calculates the closure set for the given set of states. + * + * @param nfa the NFA containing 's' + * @param states list of states on which to base the closure on + * @param label transitioning label for which to base the closure on, + * pass 0 for epsilon transition + * + * @return sorted nfa closure on 'label' (epsilon closure if 'label' is 0) + */ +static struct GNUNET_REGEX_StateSet * +nfa_closure_set_create (struct GNUNET_REGEX_Automaton *nfa, + struct GNUNET_REGEX_StateSet *states, const char label) +{ + struct GNUNET_REGEX_State *s; + struct GNUNET_REGEX_StateSet *sset; + struct GNUNET_REGEX_StateSet *cls; + int i; + int j; + int k; + int contains; + + if (NULL == states) + return NULL; + + cls = GNUNET_malloc (sizeof (struct GNUNET_REGEX_StateSet)); + + for (i = 0; i < states->len; i++) + { + s = states->states[i]; + sset = nfa_closure_create (nfa, s, label); + + for (j = 0; j < sset->len; j++) + { + contains = 0; + for (k = 0; k < cls->len; k++) + { + if (sset->states[j]->id == cls->states[k]->id) + { + contains = 1; + break; + } + } + if (!contains) + GNUNET_array_append (cls->states, cls->len, sset->states[j]); + } + state_set_clear (sset); + } + + if (cls->len > 1) + qsort (cls->states, cls->len, sizeof (struct GNUNET_REGEX_State *), + state_compare); + + return cls; +} + +/** + * Pops two NFA fragments (a, b) from the stack and concatenates them (ab) + * + * @param ctx context + */ +static void +nfa_add_concatenation (struct GNUNET_REGEX_Context *ctx) +{ + struct GNUNET_REGEX_Automaton *a; + struct GNUNET_REGEX_Automaton *b; + struct GNUNET_REGEX_Automaton *new; + + b = ctx->stack_tail; + GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, b); + a = ctx->stack_tail; + GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a); + + state_add_transition (ctx, a->end, 0, b->start); + a->end->accepting = 0; + b->end->accepting = 1; + + new = nfa_fragment_create (NULL, NULL); + nfa_add_states (new, a->states_head, a->states_tail); + nfa_add_states (new, b->states_head, b->states_tail); + new->start = a->start; + new->end = b->end; + automaton_fragment_clear (a); + automaton_fragment_clear (b); + + GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, new); +} + +/** + * Pops a NFA fragment from the stack (a) and adds a new fragment (a*) + * + * @param ctx context + */ +static void +nfa_add_star_op (struct GNUNET_REGEX_Context *ctx) +{ + struct GNUNET_REGEX_Automaton *a; + struct GNUNET_REGEX_Automaton *new; + struct GNUNET_REGEX_State *start; + struct GNUNET_REGEX_State *end; + + a = ctx->stack_tail; + GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a); + + if (NULL == a) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "nfa_add_star_op failed, because there was no element on the stack"); + return; + } + + start = nfa_state_create (ctx, 0); + end = nfa_state_create (ctx, 1); + + state_add_transition (ctx, start, 0, a->start); + state_add_transition (ctx, start, 0, end); + state_add_transition (ctx, a->end, 0, a->start); + state_add_transition (ctx, a->end, 0, end); + + a->end->accepting = 0; + end->accepting = 1; + + new = nfa_fragment_create (start, end); + nfa_add_states (new, a->states_head, a->states_tail); + automaton_fragment_clear (a); + + GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, new); +} + +/** + * Pops an NFA fragment (a) from the stack and adds a new fragment (a+) + * + * @param ctx context + */ +static void +nfa_add_plus_op (struct GNUNET_REGEX_Context *ctx) +{ + struct GNUNET_REGEX_Automaton *a; + + a = ctx->stack_tail; + GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a); + + state_add_transition (ctx, a->end, 0, a->start); + + GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, a); +} + +/** + * Pops an NFA fragment (a) from the stack and adds a new fragment (a?) + * + * @param ctx context + */ +static void +nfa_add_question_op (struct GNUNET_REGEX_Context *ctx) +{ + struct GNUNET_REGEX_Automaton *a; + struct GNUNET_REGEX_Automaton *new; + struct GNUNET_REGEX_State *start; + struct GNUNET_REGEX_State *end; + + a = ctx->stack_tail; + GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a); + + if (NULL == a) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "nfa_add_question_op failed, because there was no element on the stack"); + return; + } + + start = nfa_state_create (ctx, 0); + end = nfa_state_create (ctx, 1); + + state_add_transition (ctx, start, 0, a->start); + state_add_transition (ctx, start, 0, end); + state_add_transition (ctx, a->end, 0, end); + + a->end->accepting = 0; + + new = nfa_fragment_create (start, end); + nfa_add_states (new, a->states_head, a->states_tail); + automaton_fragment_clear (a); + + GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, new); +} + +/** + * Pops two NFA fragments (a, b) from the stack and adds a new NFA fragment that + * alternates between a and b (a|b) + * + * @param ctx context + */ +static void +nfa_add_alternation (struct GNUNET_REGEX_Context *ctx) +{ + struct GNUNET_REGEX_Automaton *a; + struct GNUNET_REGEX_Automaton *b; + struct GNUNET_REGEX_Automaton *new; + struct GNUNET_REGEX_State *start; + struct GNUNET_REGEX_State *end; + + b = ctx->stack_tail; + GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, b); + a = ctx->stack_tail; + GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a); + + start = nfa_state_create (ctx, 0); + end = nfa_state_create (ctx, 1); + state_add_transition (ctx, start, 0, a->start); + state_add_transition (ctx, start, 0, b->start); + + state_add_transition (ctx, a->end, 0, end); + state_add_transition (ctx, b->end, 0, end); + + a->end->accepting = 0; + b->end->accepting = 0; + end->accepting = 1; + + new = nfa_fragment_create (start, end); + nfa_add_states (new, a->states_head, a->states_tail); + nfa_add_states (new, b->states_head, b->states_tail); + automaton_fragment_clear (a); + automaton_fragment_clear (b); + + GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, new); +} + +/** + * Adds a new nfa fragment to the stack + * + * @param ctx context + * @param lit label for nfa transition + */ +static void +nfa_add_label (struct GNUNET_REGEX_Context *ctx, const char lit) +{ + struct GNUNET_REGEX_Automaton *n; + struct GNUNET_REGEX_State *start; + struct GNUNET_REGEX_State *end; + + GNUNET_assert (NULL != ctx); + + start = nfa_state_create (ctx, 0); + end = nfa_state_create (ctx, 1); + state_add_transition (ctx, start, lit, end); + n = nfa_fragment_create (start, end); + GNUNET_assert (NULL != n); + GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, n); +} + +/** + * Initialize a new context + * + * @param ctx context + */ +static void +GNUNET_REGEX_context_init (struct GNUNET_REGEX_Context *ctx) +{ + if (NULL == ctx) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Context was NULL!"); + return; + } + ctx->state_id = 0; + ctx->transition_id = 0; + ctx->scc_id = 0; + ctx->stack_head = NULL; + ctx->stack_tail = NULL; +} + +/** + * Construct an NFA by parsing the regex string of length 'len'. + * + * @param regex regular expression string + * @param len length of the string + * + * @return NFA, needs to be freed using GNUNET_REGEX_destroy_automaton + */ +struct GNUNET_REGEX_Automaton * +GNUNET_REGEX_construct_nfa (const char *regex, const size_t len) +{ + struct GNUNET_REGEX_Context ctx; + struct GNUNET_REGEX_Automaton *nfa; + const char *regexp; + char *error_msg; + unsigned int count; + unsigned int altcount; + unsigned int atomcount; + unsigned int pcount; + struct + { + int altcount; + int atomcount; + } *p; + + GNUNET_REGEX_context_init (&ctx); + + regexp = regex; + p = NULL; + error_msg = NULL; + altcount = 0; + atomcount = 0; + pcount = 0; + + for (count = 0; count < len && *regexp; count++, regexp++) + { + switch (*regexp) + { + case '(': + if (atomcount > 1) + { + --atomcount; + nfa_add_concatenation (&ctx); + } + GNUNET_array_grow (p, pcount, pcount + 1); + p[pcount - 1].altcount = altcount; + p[pcount - 1].atomcount = atomcount; + altcount = 0; + atomcount = 0; + break; + case '|': + if (0 == atomcount) + { + error_msg = "Cannot append '|' to nothing"; + goto error; + } + while (--atomcount > 0) + nfa_add_concatenation (&ctx); + altcount++; + break; + case ')': + if (0 == pcount) + { + error_msg = "Missing opening '('"; + goto error; + } + if (0 == atomcount) + { + // Ignore this: "()" + pcount--; + altcount = p[pcount].altcount; + atomcount = p[pcount].atomcount; + break; + } + while (--atomcount > 0) + nfa_add_concatenation (&ctx); + for (; altcount > 0; altcount--) + nfa_add_alternation (&ctx); + pcount--; + altcount = p[pcount].altcount; + atomcount = p[pcount].atomcount; + atomcount++; + break; + case '*': + if (atomcount == 0) + { + error_msg = "Cannot append '*' to nothing"; + goto error; + } + nfa_add_star_op (&ctx); + break; + case '+': + if (atomcount == 0) + { + error_msg = "Cannot append '+' to nothing"; + goto error; + } + nfa_add_plus_op (&ctx); + break; + case '?': + if (atomcount == 0) + { + error_msg = "Cannot append '?' to nothing"; + goto error; + } + nfa_add_question_op (&ctx); + break; + case 92: /* escape: \ */ + regexp++; + count++; + default: + if (atomcount > 1) + { + --atomcount; + nfa_add_concatenation (&ctx); + } + nfa_add_label (&ctx, *regexp); + atomcount++; + break; + } + } + if (0 != pcount) + { + error_msg = "Unbalanced parenthesis"; + goto error; + } + while (--atomcount > 0) + nfa_add_concatenation (&ctx); + for (; altcount > 0; altcount--) + nfa_add_alternation (&ctx); + + if (NULL != p) + GNUNET_free (p); + + nfa = ctx.stack_tail; + GNUNET_CONTAINER_DLL_remove (ctx.stack_head, ctx.stack_tail, nfa); + + if (NULL != ctx.stack_head) + { + error_msg = "Creating the NFA failed. NFA stack was not empty!"; + goto error; + } + + return nfa; + +error: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not parse regex\n"); + if (NULL != error_msg) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", error_msg); + if (NULL != p) + GNUNET_free (p); + while (NULL != ctx.stack_tail) + { + GNUNET_REGEX_automaton_destroy (ctx.stack_tail); + GNUNET_CONTAINER_DLL_remove (ctx.stack_head, ctx.stack_tail, + ctx.stack_tail); + } + return NULL; +} + +/** + * Create DFA states based on given 'nfa' and starting with 'dfa_state'. + * + * @param ctx context. + * @param nfa NFA automaton. + * @param dfa DFA automaton. + * @param dfa_state current dfa state, pass epsilon closure of first nfa state + * for starting. + */ +static void +construct_dfa_states (struct GNUNET_REGEX_Context *ctx, + struct GNUNET_REGEX_Automaton *nfa, + struct GNUNET_REGEX_Automaton *dfa, + struct GNUNET_REGEX_State *dfa_state) +{ + struct Transition *ctran; + struct GNUNET_REGEX_State *state_iter; + struct GNUNET_REGEX_State *new_dfa_state; + struct GNUNET_REGEX_State *state_contains; + struct GNUNET_REGEX_StateSet *tmp; + struct GNUNET_REGEX_StateSet *nfa_set; + + for (ctran = dfa_state->transitions_head; NULL != ctran; ctran = ctran->next) + { + if (0 == ctran->label || NULL != ctran->to_state) + continue; + + tmp = nfa_closure_set_create (nfa, dfa_state->nfa_set, ctran->label); + nfa_set = nfa_closure_set_create (nfa, tmp, 0); + state_set_clear (tmp); + new_dfa_state = dfa_state_create (ctx, nfa_set); + state_contains = NULL; + for (state_iter = dfa->states_head; NULL != state_iter; + state_iter = state_iter->next) + { + if (0 == state_set_compare (state_iter->nfa_set, new_dfa_state->nfa_set)) + state_contains = state_iter; + } + + if (NULL == state_contains) + { + automaton_add_state (dfa, new_dfa_state); + ctran->to_state = new_dfa_state; + construct_dfa_states (ctx, nfa, dfa, new_dfa_state); + } + else + { + ctran->to_state = state_contains; + automaton_destroy_state (new_dfa_state); + } + } +} + +/** + * Construct DFA for the given 'regex' of length 'len' + * + * @param regex regular expression string + * @param len length of the regular expression + * + * @return DFA, needs to be freed using GNUNET_REGEX_destroy_automaton + */ +struct GNUNET_REGEX_Automaton * +GNUNET_REGEX_construct_dfa (const char *regex, const size_t len) +{ + struct GNUNET_REGEX_Context ctx; + struct GNUNET_REGEX_Automaton *dfa; + struct GNUNET_REGEX_Automaton *nfa; + struct GNUNET_REGEX_StateSet *nfa_set; + + GNUNET_REGEX_context_init (&ctx); + + // Create NFA + nfa = GNUNET_REGEX_construct_nfa (regex, len); + + if (NULL == nfa) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not create DFA, because NFA creation failed\n"); + return NULL; + } + + dfa = GNUNET_malloc (sizeof (struct GNUNET_REGEX_Automaton)); + dfa->type = DFA; + + // Create DFA start state from epsilon closure + nfa_set = nfa_closure_create (nfa, nfa->start, 0); + dfa->start = dfa_state_create (&ctx, nfa_set); + automaton_add_state (dfa, dfa->start); + + construct_dfa_states (&ctx, nfa, dfa, dfa->start); + + GNUNET_REGEX_automaton_destroy (nfa); + + // Minimize DFA + dfa_minimize (&ctx, dfa); + + // Calculate SCCs + scc_tarjan (&ctx, dfa); + + // Create proofs for all states + automaton_create_proofs (dfa); + + return dfa; +} + +/** + * Free the memory allocated by constructing the GNUNET_REGEX_Automaton data + * structure. + * + * @param a automaton to be destroyed + */ +void +GNUNET_REGEX_automaton_destroy (struct GNUNET_REGEX_Automaton *a) +{ + struct GNUNET_REGEX_State *s; + struct GNUNET_REGEX_State *next_state; + + if (NULL == a) + return; + + for (s = a->states_head; NULL != s;) + { + next_state = s->next; + automaton_destroy_state (s); + s = next_state; + } + + GNUNET_free (a); +} + +/** + * Save the given automaton as a GraphViz dot file + * + * @param a the automaton to be saved + * @param filename where to save the file + */ +void +GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a, + const char *filename) +{ + struct GNUNET_REGEX_State *s; + struct Transition *ctran; + char *s_acc = NULL; + char *s_tran = NULL; + char *start; + char *end; + FILE *p; + + if (NULL == a) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print NFA, was NULL!"); + return; + } + + if (NULL == filename || strlen (filename) < 1) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No Filename given!"); + return; + } + + p = fopen (filename, "w"); + + if (NULL == p) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not open file for writing: %s", + filename); + return; + } + + start = "digraph G {\nrankdir=LR\n"; + fwrite (start, strlen (start), 1, p); + + for (s = a->states_head; NULL != s; s = s->next) + { + if (s->accepting) + { + GNUNET_asprintf (&s_acc, + "\"%s\" [shape=doublecircle, color=\"0.%i 0.8 0.95\"];\n", + s->name, s->scc_id); + } + else + { + GNUNET_asprintf (&s_acc, "\"%s\" [color=\"0.%i 0.8 0.95\"];\n", s->name, + s->scc_id); + } + + if (NULL == s_acc) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print state %s\n", + s->name); + return; + } + fwrite (s_acc, strlen (s_acc), 1, p); + GNUNET_free (s_acc); + s_acc = NULL; + + for (ctran = s->transitions_head; NULL != ctran; ctran = ctran->next) + { + if (NULL == ctran->to_state) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Transition from State %i has has no state for transitioning\n", + s->id); + continue; + } + + if (ctran->label == 0) + { + GNUNET_asprintf (&s_tran, + "\"%s\" -> \"%s\" [label = \"epsilon\", color=\"0.%i 0.8 0.95\"];\n", + s->name, ctran->to_state->name, s->scc_id); + } + else + { + GNUNET_asprintf (&s_tran, + "\"%s\" -> \"%s\" [label = \"%c\", color=\"0.%i 0.8 0.95\"];\n", + s->name, ctran->to_state->name, ctran->label, + s->scc_id); + } + + if (NULL == s_tran) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print state %s\n", + s->name); + return; + } + + fwrite (s_tran, strlen (s_tran), 1, p); + GNUNET_free (s_tran); + s_tran = NULL; + } + } + + end = "\n}\n"; + fwrite (end, strlen (end), 1, p); + fclose (p); +} + +/** + * Evaluates the given string using the given DFA automaton + * + * @param a automaton, type must be DFA + * @param string string that should be evaluated + * + * @return 0 if string matches, non 0 otherwise + */ +static int +evaluate_dfa (struct GNUNET_REGEX_Automaton *a, const char *string) +{ + const char *strp; + struct GNUNET_REGEX_State *s; + + if (DFA != a->type) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Tried to evaluate DFA, but NFA automaton given"); + return -1; + } + + s = a->start; + + for (strp = string; NULL != strp && *strp; strp++) + { + s = dfa_move (s, *strp); + if (NULL == s) + break; + } + + if (NULL != s && s->accepting) + return 0; + + return 1; +} + +/** + * Evaluates the given string using the given NFA automaton + * + * @param a automaton, type must be NFA + * @param string string that should be evaluated + * + * @return 0 if string matches, non 0 otherwise + */ +static int +evaluate_nfa (struct GNUNET_REGEX_Automaton *a, const char *string) +{ + const char *strp; + struct GNUNET_REGEX_State *s; + struct GNUNET_REGEX_StateSet *sset; + struct GNUNET_REGEX_StateSet *new_sset; + int i; + int result; + + if (NFA != a->type) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Tried to evaluate NFA, but DFA automaton given"); + return -1; + } + + result = 1; + strp = string; + sset = nfa_closure_create (a, a->start, 0); + + for (strp = string; NULL != strp && *strp; strp++) + { + new_sset = nfa_closure_set_create (a, sset, *strp); + state_set_clear (sset); + sset = nfa_closure_set_create (a, new_sset, 0); + state_set_clear (new_sset); + } + + for (i = 0; i < sset->len; i++) + { + s = sset->states[i]; + if (NULL != s && s->accepting) + { + result = 0; + break; + } + } + + state_set_clear (sset); + return result; +} + +/** + * Evaluates the given 'string' against the given compiled regex + * + * @param a automaton + * @param string string to check + * + * @return 0 if string matches, non 0 otherwise + */ +int +GNUNET_REGEX_eval (struct GNUNET_REGEX_Automaton *a, const char *string) +{ + int result; + + switch (a->type) + { + case DFA: + result = evaluate_dfa (a, string); + break; + case NFA: + result = evaluate_nfa (a, string); + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Evaluating regex failed, automaton has no type!\n"); + result = GNUNET_SYSERR; + break; + } + + return result; +} + +/** + * Get the first key for the given 'input_string'. This hashes the first x bits + * of the 'input_strings'. + * + * @param input_string string. + * @param string_len length of the 'input_string'. + * @param key pointer to where to write the hash code. + * + * @return number of bits of 'input_string' that have been consumed + * to construct the key + */ +unsigned int +GNUNET_REGEX_get_first_key (const char *input_string, unsigned int string_len, + GNUNET_HashCode * key) +{ + unsigned int size; + + size = string_len < initial_bits ? string_len : initial_bits; + + if (NULL == input_string) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Given input string was NULL!\n"); + return 0; + } + + GNUNET_CRYPTO_hash (input_string, size, key); + + return size; +} + +/** + * Check if the given 'proof' matches the given 'key'. + * + * @param proof partial regex + * @param key hash + * + * @return GNUNET_OK if the proof is valid for the given key + */ +int +GNUNET_REGEX_check_proof (const char *proof, const GNUNET_HashCode * key) +{ + return GNUNET_OK; +} + +/** + * Iterate over all edges helper function starting from state 's', calling + * iterator on for each edge. + * + * @param s state. + * @param iterator iterator function called for each edge. + * @param iterator_cls closure. + */ +static void +iterate_edge (struct GNUNET_REGEX_State *s, GNUNET_REGEX_KeyIterator iterator, + void *iterator_cls) +{ + struct Transition *t; + struct GNUNET_REGEX_Edge edges[s->transition_count]; + unsigned int num_edges; + + if (GNUNET_YES != s->marked) + { + s->marked = GNUNET_YES; + + num_edges = state_get_edges (s, edges); + + iterator (iterator_cls, &s->hash, s->proof, s->accepting, num_edges, edges); + + for (t = s->transitions_head; NULL != t; t = t->next) + iterate_edge (t->to_state, iterator, iterator_cls); + } +} + +/** + * Iterate over all edges starting from start state of automaton 'a'. Calling + * iterator for each edge. + * + * @param a automaton. + * @param iterator iterator called for each edge. + * @param iterator_cls closure. + */ +void +GNUNET_REGEX_iterate_all_edges (struct GNUNET_REGEX_Automaton *a, + GNUNET_REGEX_KeyIterator iterator, + void *iterator_cls) +{ + struct GNUNET_REGEX_State *s; + + for (s = a->states_head; NULL != s; s = s->next) + s->marked = GNUNET_NO; + + iterate_edge (a->start, iterator, iterator_cls); +} diff --git a/src/regex/test_regex_eval_api.c b/src/regex/test_regex_eval_api.c new file mode 100644 index 0000000..c63e97c --- /dev/null +++ b/src/regex/test_regex_eval_api.c @@ -0,0 +1,311 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file regex/test_regex_eval_api.c + * @brief test for regex.c + * @author Maximilian Szengel + */ +#include +#include +#include "platform.h" +#include "gnunet_regex_lib.h" + +enum Match_Result +{ + match = 0, + nomatch = 1 +}; + +struct Regex_String_Pair +{ + char *regex; + int string_count; + char *strings[20]; + enum Match_Result expected_results[20]; +}; + +static const char allowed_literals[] = + "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; + +int +test_random (unsigned int rx_length, unsigned int max_str_len, + unsigned int str_count) +{ + int i; + int j; + int rx_exp; + char rand_rx[rx_length + 1]; + char matching_str[str_count][max_str_len + 1]; + char *rand_rxp; + char *matching_strp; + int char_op_switch; + int last_was_op; + char current_char; + int eval; + int eval_check; + struct GNUNET_REGEX_Automaton *dfa; + regex_t rx; + regmatch_t matchptr[1]; + char error[200]; + int result; + unsigned int str_len; + + // At least one string is needed for matching + GNUNET_assert (str_count > 0); + // The string should be at least as long as the regex itself + GNUNET_assert (max_str_len >= rx_length); + + rand_rxp = rand_rx; + matching_strp = matching_str[0]; + current_char = 0; + last_was_op = 1; + + // Generate random regex and a string that matches the regex + for (i = 0; i < rx_length; i++) + { + char_op_switch = 0 + (int) (1.0 * rand () / (RAND_MAX + 1.0)); + + if (0 == char_op_switch && !last_was_op) + { + last_was_op = 1; + rx_exp = rand () % 4; + + switch (rx_exp) + { + case 0: + current_char = '+'; + break; + case 1: + current_char = '*'; + break; + case 2: + current_char = '?'; + break; + case 3: + if (i < rx_length - 1) // '|' cannot be at the end + current_char = '|'; + else + current_char = + allowed_literals[rand () % (sizeof (allowed_literals) - 1)]; + break; + } + } + else + { + current_char = + allowed_literals[rand () % (sizeof (allowed_literals) - 1)]; + last_was_op = 0; + } + + if (current_char != '+' && current_char != '*' && current_char != '?' && + current_char != '|') + { + *matching_strp = current_char; + matching_strp++; + } + + *rand_rxp = current_char; + rand_rxp++; + } + *rand_rxp = '\0'; + *matching_strp = '\0'; + + // Generate some random strings for matching... + // Start at 1, because the first string is generated above during regex generation + for (i = 1; i < str_count; i++) + { + str_len = rand () % max_str_len; + for (j = 0; j < str_len; j++) + matching_str[i][j] = + allowed_literals[rand () % (sizeof (allowed_literals) - 1)]; + matching_str[i][str_len] = '\0'; + } + + // Now match + result = 0; + for (i = 0; i < str_count; i++) + { + // Match string using DFA + dfa = GNUNET_REGEX_construct_dfa (rand_rx, strlen (rand_rx)); + if (NULL == dfa) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Constructing DFA failed\n"); + return -1; + } + + eval = GNUNET_REGEX_eval (dfa, matching_str[i]); + GNUNET_REGEX_automaton_destroy (dfa); + + // Match string using glibc regex + if (0 != regcomp (&rx, rand_rx, REG_EXTENDED)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not compile regex using regcomp\n"); + return -1; + } + + eval_check = regexec (&rx, matching_str[i], 1, matchptr, 0); + regfree (&rx); + + // We only want to match the whole string, because that's what our DFA does, too. + if (eval_check == 0 && + (matchptr[0].rm_so != 0 || + matchptr[0].rm_eo != strlen (matching_str[i]))) + eval_check = 1; + + // compare result + if (eval_check != eval) + { + regerror (eval_check, &rx, error, sizeof error); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected result:\nregex: %s\nstring: %s\ngnunet regex: %i\nglibc regex: %i\nglibc error: %s\n\n", + rand_rx, matching_str, eval, eval_check, error); + result += 1; + } + } + return result; +} + +int +test_automaton (struct GNUNET_REGEX_Automaton *a, regex_t * rx, + struct Regex_String_Pair *rxstr) +{ + int result; + int eval; + int eval_check; + char error[200]; + regmatch_t matchptr[1]; + int i; + + if (NULL == a) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Automaton was NULL\n"); + return 1; + } + + result = 0; + + for (i = 0; i < rxstr->string_count; i++) + { + eval = GNUNET_REGEX_eval (a, rxstr->strings[i]); + eval_check = regexec (rx, rxstr->strings[i], 1, matchptr, 0); + + // We only want to match the whole string, because that's what our DFA does, too. + if (eval_check == 0 && + (matchptr[0].rm_so != 0 || + matchptr[0].rm_eo != strlen (rxstr->strings[i]))) + eval_check = 1; + + if ((rxstr->expected_results[i] == match && (0 != eval || 0 != eval_check)) + || (rxstr->expected_results[i] == nomatch && + (0 == eval || 0 == eval_check))) + { + result = 1; + regerror (eval_check, rx, error, sizeof error); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected result:\nregex: %s\nstring: %s\nexpected result: %i\n" + "gnunet regex: %i\nglibc regex: %i\nglibc error: %s\nrm_so: %i\nrm_eo: %i\n\n", + rxstr->regex, rxstr->strings[i], rxstr->expected_results[i], + eval, eval_check, error, matchptr[0].rm_so, + matchptr[0].rm_eo); + } + } + return result; +} + +int +main (int argc, char *argv[]) +{ + GNUNET_log_setup ("test-regex", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + + struct GNUNET_REGEX_Automaton *a; + regex_t rx; + int i; + int check_nfa; + int check_dfa; + int check_rand; + + struct Regex_String_Pair rxstr[8] = { + {"ab?(abcd)?", 5, + {"ababcd", "abab", "aabcd", "a", "abb"}, + {match, nomatch, match, match, nomatch}}, + {"ab(c|d)+c*(a(b|c)d)+", 5, + {"abcdcdcdcdddddabd", "abcd", "abcddddddccccccccccccccccccccccccabdacdabd", + "abccccca", "abcdcdcdccdabdabd"}, + {match, nomatch, match, nomatch, match}}, + {"ab+c*(a(bx|c)d)+", 5, + {"abcdcdcdcdddddabd", "abcd", "abcddddddccccccccccccccccccccccccabdacdabd", + "abccccca", "abcdcdcdccdabdabd"}, + {nomatch, nomatch, nomatch, nomatch, nomatch}}, + {"a+X*y+c|p|R|Z*K*y*R+w|Y*6+n+h*k*w+V*F|W*B*e*", 1, + {"kaXycQepRZKyRwY6nhkwVFWBegNVtLPj39XhJJ6bEifRSZRYZg"}, + {nomatch}}, + {"k|a+X*y+c|Q*e|p|R|Z*K*y*R+w|Y*6+n+h*k*w+V*F|W*B*e*g|N+V|t+L|P*j*3*9+X*h*J|J*6|b|E*i*f*R+S|Z|R|Y*Z|g*", 1, + {"kaXycQepRZKyRwY6nhkwVFWBegNVtLPj39XhJJ6bEifRSZRYZg"}, + {nomatch}}, + {"F?W+m+2*6*c*s|P?U?a|B|y*i+t+A|V|6*C*7*e?Z*n*i|J?5+g?W*V?7*j?p?1|r?B?C+E+3+6*i+W*P?K?0|D+7?y*m+3?g?K?", 1, + {"osfjsodfonONONOnosndfsdnfsd"}, + {nomatch}}, + {"V|M*o?x*p*d+h+b|E*m?h?Y*E*O?W*W*P+o?Z+H*M|I*q+C*a+5?5*9|b?z|G*y*k?R|p+u|8*h?B+l*H|e|L*O|1|F?v*0?5|C+", 1, + {"VMoxpdhbEmhYEOWWPoZHMIqCa559bzGykRpu8hBlHeLO1Fv05C"}, + {nomatch}}, + {"ab(c|d)+c*(a(b|c)d)+", 1, + {"abacd"}, + {nomatch}} + }; + + check_nfa = 0; + check_dfa = 0; + check_rand = 0; + + for (i = 0; i < 8; i++) + { + if (0 != regcomp (&rx, rxstr[i].regex, REG_EXTENDED)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not compile regex using regcomp()\n"); + return 1; + } + + // NFA test + a = GNUNET_REGEX_construct_nfa (rxstr[i].regex, strlen (rxstr[i].regex)); + check_nfa += test_automaton (a, &rx, &rxstr[i]); + GNUNET_REGEX_automaton_destroy (a); + + // DFA test + a = GNUNET_REGEX_construct_dfa (rxstr[i].regex, strlen (rxstr[i].regex)); + check_dfa += test_automaton (a, &rx, &rxstr[i]); + GNUNET_REGEX_automaton_destroy (a); + + regfree (&rx); + } + + srand (time (NULL)); + for (i = 0; i < 150; i++) + check_rand += test_random (150, 200, 25); + + return check_nfa + check_dfa + check_rand; +} diff --git a/src/regex/test_regex_iterate_api.c b/src/regex/test_regex_iterate_api.c new file mode 100644 index 0000000..b214d6a --- /dev/null +++ b/src/regex/test_regex_iterate_api.c @@ -0,0 +1,71 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file regex/test_regex_iterate_api.c + * @brief test for regex.c + * @author Maximilian Szengel + */ +#include +#include +#include "platform.h" +#include "gnunet_regex_lib.h" + +void +key_iterator (void *cls, const GNUNET_HashCode * key, const char *proof, + int accepting, unsigned int num_edges, + const struct GNUNET_REGEX_Edge *edges) +{ + int i; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iterating...\n"); + for (i = 0; i < num_edges; i++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Edge %i: %s\n", i, edges[i].label); + } + + if (NULL != proof) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Proof: %s\n", proof); +} + +int +main (int argc, char *argv[]) +{ + GNUNET_log_setup ("test-regex", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + + int error; + const char *regex; + struct GNUNET_REGEX_Automaton *dfa; + + error = 0; + regex = "ab(c|d)+c*(a(b|c)d)+"; + + dfa = GNUNET_REGEX_construct_dfa (regex, strlen (regex)); + GNUNET_REGEX_automaton_save_graph (dfa, "dfa.dot"); + GNUNET_REGEX_iterate_all_edges (dfa, key_iterator, NULL); + GNUNET_REGEX_automaton_destroy (dfa); + + return error; +} diff --git a/src/statistics/Makefile.am b/src/statistics/Makefile.am index 2d1daf8..ddf5fda 100644 --- a/src/statistics/Makefile.am +++ b/src/statistics/Makefile.am @@ -23,7 +23,7 @@ libgnunetstatistics_la_LIBADD = \ $(GN_LIBINTL) $(XLIB) libgnunetstatistics_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 1:0:1 + -version-info 1:1:1 bin_PROGRAMS = \ @@ -51,7 +51,8 @@ gnunet_service_statistics_DEPENDENCIES = \ check_PROGRAMS = \ test_statistics_api \ test_statistics_api_loop \ - test_statistics_api_watch + test_statistics_api_watch \ + test_statistics_api_watch_zero_value if ENABLE_TEST_RUN TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @@ -75,6 +76,12 @@ test_statistics_api_watch_LDADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la +test_statistics_api_watch_zero_value_SOURCES = \ + test_statistics_api_watch_zero_value.c +test_statistics_api_watch_zero_value_LDADD = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la + check_SCRIPTS = \ test_gnunet_statistics.sh diff --git a/src/statistics/Makefile.in b/src/statistics/Makefile.in index 1930c3a..a81ae4a 100644 --- a/src/statistics/Makefile.in +++ b/src/statistics/Makefile.in @@ -41,7 +41,8 @@ bin_PROGRAMS = gnunet-statistics$(EXEEXT) \ gnunet-service-statistics$(EXEEXT) check_PROGRAMS = test_statistics_api$(EXEEXT) \ test_statistics_api_loop$(EXEEXT) \ - test_statistics_api_watch$(EXEEXT) + test_statistics_api_watch$(EXEEXT) \ + test_statistics_api_watch_zero_value$(EXEEXT) subdir = src/statistics DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/statistics.conf.in @@ -127,6 +128,13 @@ test_statistics_api_watch_OBJECTS = \ test_statistics_api_watch_DEPENDENCIES = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la +am_test_statistics_api_watch_zero_value_OBJECTS = \ + test_statistics_api_watch_zero_value.$(OBJEXT) +test_statistics_api_watch_zero_value_OBJECTS = \ + $(am_test_statistics_api_watch_zero_value_OBJECTS) +test_statistics_api_watch_zero_value_DEPENDENCIES = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -157,12 +165,14 @@ SOURCES = $(libgnunetstatistics_la_SOURCES) \ $(gnunet_service_statistics_SOURCES) \ $(gnunet_statistics_SOURCES) $(test_statistics_api_SOURCES) \ $(test_statistics_api_loop_SOURCES) \ - $(test_statistics_api_watch_SOURCES) + $(test_statistics_api_watch_SOURCES) \ + $(test_statistics_api_watch_zero_value_SOURCES) DIST_SOURCES = $(libgnunetstatistics_la_SOURCES) \ $(gnunet_service_statistics_SOURCES) \ $(gnunet_statistics_SOURCES) $(test_statistics_api_SOURCES) \ $(test_statistics_api_loop_SOURCES) \ - $(test_statistics_api_watch_SOURCES) + $(test_statistics_api_watch_SOURCES) \ + $(test_statistics_api_watch_zero_value_SOURCES) DATA = $(pkgcfg_DATA) ETAGS = etags CTAGS = ctags @@ -224,6 +234,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -257,6 +268,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -391,7 +403,7 @@ libgnunetstatistics_la_LIBADD = \ libgnunetstatistics_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 1:0:1 + -version-info 1:1:1 gnunet_statistics_SOURCES = \ gnunet-statistics.c @@ -437,6 +449,13 @@ test_statistics_api_watch_LDADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la +test_statistics_api_watch_zero_value_SOURCES = \ + test_statistics_api_watch_zero_value.c + +test_statistics_api_watch_zero_value_LDADD = \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la + check_SCRIPTS = \ test_gnunet_statistics.sh @@ -580,6 +599,9 @@ test_statistics_api_loop$(EXEEXT): $(test_statistics_api_loop_OBJECTS) $(test_st test_statistics_api_watch$(EXEEXT): $(test_statistics_api_watch_OBJECTS) $(test_statistics_api_watch_DEPENDENCIES) @rm -f test_statistics_api_watch$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_statistics_api_watch_OBJECTS) $(test_statistics_api_watch_LDADD) $(LIBS) +test_statistics_api_watch_zero_value$(EXEEXT): $(test_statistics_api_watch_zero_value_OBJECTS) $(test_statistics_api_watch_zero_value_DEPENDENCIES) + @rm -f test_statistics_api_watch_zero_value$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_statistics_api_watch_zero_value_OBJECTS) $(test_statistics_api_watch_zero_value_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -593,6 +615,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_statistics_api.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_statistics_api_loop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_statistics_api_watch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_statistics_api_watch_zero_value.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/statistics/gnunet-service-statistics.c b/src/statistics/gnunet-service-statistics.c index a890d6d..efd8346 100644 --- a/src/statistics/gnunet-service-statistics.c +++ b/src/statistics/gnunet-service-statistics.c @@ -41,16 +41,37 @@ struct WatchEntry { + /** + * Watch entries are kept in a linked list. + */ struct WatchEntry *next; + /** + * Watch entries are kept in a linked list. + */ struct WatchEntry *prev; + /** + * For which client is this watch entry? + */ struct GNUNET_SERVER_Client *client; + /** + * Last value we communicated to the client for this watch entry. + */ uint64_t last_value; + /** + * Unique watch number for this client and this watched value. + */ uint32_t wid; + /** + * Is last_value valid + * GNUNET_NO : last_value is n/a, GNUNET_YES: last_value is valid + */ + int last_value_set; + }; @@ -59,13 +80,24 @@ struct WatchEntry */ struct ClientEntry { - + /** + * Clients are kept in a linked list. + */ struct ClientEntry *next; + /** + * Clients are kept in a linked list. + */ struct ClientEntry *prev; + /** + * Corresponding server handle. + */ struct GNUNET_SERVER_Client *client; + /** + * Maximum watch ID used by this client so far. + */ uint32_t max_wid; }; @@ -126,6 +158,12 @@ struct StatsEntry */ int persistent; + /** + * Is this value set? + * GNUNET_NO : value is n/a, GNUNET_YES: value is valid + */ + int set; + }; /** @@ -138,10 +176,21 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; */ static struct StatsEntry *start; +/** + * Head of linked list of connected clients. + */ static struct ClientEntry *client_head; +/** + * Tail of linked list of connected clients. + */ static struct ClientEntry *client_tail; +/** + * Handle to our server. + */ +static struct GNUNET_SERVER_Handle *srv; + /** * Our notification context. */ @@ -152,13 +201,26 @@ static struct GNUNET_SERVER_NotificationContext *nc; */ static uint32_t uidgen; +/** + * Set to YES if we are shutting down as soon as possible. + */ +static int in_shutdown; + -static void +/** + * Inject a message to our server with a client of 'NULL'. + * + * @param cls the 'struct GNUNET_SERVER_Handle' + * @param client unused + * @param msg message to inject + */ +static int inject_message (void *cls, void *client, const struct GNUNET_MessageHeader *msg) { struct GNUNET_SERVER_Handle *server = cls; GNUNET_break (GNUNET_OK == GNUNET_SERVER_inject (server, NULL, msg)); + return GNUNET_OK; } @@ -174,7 +236,7 @@ load (struct GNUNET_SERVER_Handle *server) { char *fn; struct GNUNET_BIO_ReadHandle *rh; - struct stat sb; + uint64_t fsize; char *buf; struct GNUNET_SERVER_MessageStreamTokenizer *mst; char *emsg; @@ -183,12 +245,12 @@ load (struct GNUNET_SERVER_Handle *server) NULL); if (fn == NULL) return; - if ((0 != stat (fn, &sb)) || (sb.st_size == 0)) + if ((GNUNET_OK != GNUNET_DISK_file_size (fn, &fsize, GNUNET_NO, GNUNET_YES)) || (fsize == 0)) { GNUNET_free (fn); return; } - buf = GNUNET_malloc (sb.st_size); + buf = GNUNET_malloc (fsize); rh = GNUNET_BIO_read_open (fn); if (!rh) { @@ -196,7 +258,7 @@ load (struct GNUNET_SERVER_Handle *server) GNUNET_free (fn); return; } - if (GNUNET_OK != GNUNET_BIO_read (rh, fn, buf, sb.st_size)) + if (GNUNET_OK != GNUNET_BIO_read (rh, fn, buf, fsize)) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "read", fn); GNUNET_break (GNUNET_OK == GNUNET_BIO_read_close (rh, &emsg)); @@ -207,10 +269,10 @@ load (struct GNUNET_SERVER_Handle *server) } GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading %llu bytes of statistics from `%s'\n"), - (unsigned long long) sb.st_size, fn); + fsize, fn); mst = GNUNET_SERVER_mst_create (&inject_message, server); GNUNET_break (GNUNET_OK == - GNUNET_SERVER_mst_receive (mst, NULL, buf, sb.st_size, + GNUNET_SERVER_mst_receive (mst, NULL, buf, fsize, GNUNET_YES, GNUNET_NO)); GNUNET_SERVER_mst_destroy (mst); GNUNET_free (buf); @@ -219,6 +281,7 @@ load (struct GNUNET_SERVER_Handle *server) GNUNET_free (fn); } + /** * Write persistent statistics to disk. */ @@ -272,6 +335,9 @@ save () /** * Transmit the given stats value. + * + * @param client receiver of the value + * @param e value to transmit */ static void transmit (struct GNUNET_SERVER_Client *client, const struct StatsEntry *e) @@ -294,11 +360,9 @@ transmit (struct GNUNET_SERVER_Client *client, const struct StatsEntry *e) GNUNET_assert (size == GNUNET_STRINGS_buffer_fill ((char *) &m[1], size, 2, e->service, e->name)); -#if DEBUG_STATISTICS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting value for `%s:%s' (%d): %llu\n", e->service, e->name, e->persistent, e->value); -#endif GNUNET_SERVER_notification_context_unicast (nc, client, &m->header, GNUNET_NO); GNUNET_free (m); @@ -307,6 +371,11 @@ transmit (struct GNUNET_SERVER_Client *client, const struct StatsEntry *e) /** * Does this entry match the request? + * + * @param e an entry + * @param service name of service to match + * @param name value to match + * @return 1 if they match, 0 if not */ static int matches (const struct StatsEntry *e, const char *service, const char *name) @@ -316,6 +385,12 @@ matches (const struct StatsEntry *e, const char *service, const char *name) } +/** + * Find a client entry for the given client handle, or create one. + * + * @param client handle to match + * @return corresponding client entry struct + */ static struct ClientEntry * make_client_entry (struct GNUNET_SERVER_Client *client) { @@ -329,6 +404,11 @@ make_client_entry (struct GNUNET_SERVER_Client *client) return ce; ce = ce->next; } + if (NULL == nc) + { + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return NULL; + } ce = GNUNET_malloc (sizeof (struct ClientEntry)); ce->client = client; GNUNET_SERVER_client_keep (client); @@ -357,8 +437,9 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, struct StatsEntry *pos; size_t size; - if (client != NULL) - make_client_entry (client); + if ( (NULL != client) && + (NULL == make_client_entry (client)) ) + return; /* new client during shutdown */ size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader); if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1], size, 2, @@ -368,18 +449,12 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_STATISTICS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received request for statistics on `%s:%s'\n", strlen (service) ? service : "*", strlen (name) ? name : "*"); -#endif - pos = start; - while (pos != NULL) - { + for (pos = start; NULL != pos; pos = pos->next) if (matches (pos, service, name)) transmit (client, pos); - pos = pos->next; - } end.size = htons (sizeof (struct GNUNET_MessageHeader)); end.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_END); GNUNET_SERVER_notification_context_unicast (nc, client, &end, GNUNET_NO); @@ -387,29 +462,38 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, } +/** + * Notify all clients listening about a change to a value. + * + * @param se value that changed + */ static void notify_change (struct StatsEntry *se) { struct GNUNET_STATISTICS_WatchValueMessage wvm; struct WatchEntry *pos; - pos = se->we_head; - while (pos != NULL) + for (pos = se->we_head; NULL != pos; pos = pos->next) { - if (pos->last_value != se->value) + if (GNUNET_YES == pos->last_value_set) { - wvm.header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE); - wvm.header.size = - htons (sizeof (struct GNUNET_STATISTICS_WatchValueMessage)); - wvm.flags = htonl (se->persistent ? GNUNET_STATISTICS_PERSIST_BIT : 0); - wvm.wid = htonl (pos->wid); - wvm.reserved = htonl (0); - wvm.value = GNUNET_htonll (se->value); - GNUNET_SERVER_notification_context_unicast (nc, pos->client, &wvm.header, - GNUNET_NO); - pos->last_value = se->value; + if (pos->last_value == se->value) + continue; } - pos = pos->next; + else + { + pos->last_value_set = GNUNET_YES; + } + wvm.header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE); + wvm.header.size = + htons (sizeof (struct GNUNET_STATISTICS_WatchValueMessage)); + wvm.flags = htonl (se->persistent ? GNUNET_STATISTICS_PERSIST_BIT : 0); + wvm.wid = htonl (pos->wid); + wvm.reserved = htonl (0); + wvm.value = GNUNET_htonll (se->value); + GNUNET_SERVER_notification_context_unicast (nc, pos->client, &wvm.header, + GNUNET_NO); + pos->last_value = se->value; } } @@ -435,9 +519,11 @@ handle_set (void *cls, struct GNUNET_SERVER_Client *client, uint64_t value; int64_t delta; int changed; + int initial_set; - if (client != NULL) - make_client_entry (client); + if ( (NULL != client) && + (NULL == make_client_entry (client)) ) + return; /* new client during shutdown */ msize = ntohs (message->size); if (msize < sizeof (struct GNUNET_STATISTICS_SetMessage)) { @@ -458,17 +544,16 @@ handle_set (void *cls, struct GNUNET_SERVER_Client *client, } flags = ntohl (msg->flags); value = GNUNET_ntohll (msg->value); -#if DEBUG_STATISTICS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received request to update statistic on `%s:%s' (%u) to/by %llu\n", service, name, (unsigned int) flags, (unsigned long long) value); -#endif pos = start; prev = NULL; while (pos != NULL) { if (matches (pos, service, name)) { + initial_set = 0; if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0) { changed = (pos->value != value); @@ -489,6 +574,11 @@ handle_set (void *cls, struct GNUNET_SERVER_Client *client, pos->value += delta; } } + if (GNUNET_NO == pos->set) + { + pos->set = GNUNET_YES; + initial_set = 1; + } pos->msg->value = GNUNET_htonll (pos->value); pos->msg->flags = msg->flags; pos->persistent = (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT)); @@ -499,12 +589,10 @@ handle_set (void *cls, struct GNUNET_SERVER_Client *client, pos->next = start; start = pos; } -#if DEBUG_STATISTICS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Statistic `%s:%s' updated to value %llu.\n", service, name, pos->value); -#endif - if (changed) + if ((changed) || (1 == initial_set)) notify_change (pos); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; @@ -516,7 +604,14 @@ handle_set (void *cls, struct GNUNET_SERVER_Client *client, pos->next = start; if (((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0) || (0 < (int64_t) GNUNET_ntohll (msg->value))) + { pos->value = GNUNET_ntohll (msg->value); + pos->set = GNUNET_YES; + } + else + { + pos->set = GNUNET_NO; + } pos->uid = uidgen++; pos->persistent = (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT)); pos->msg = (void *) &pos[1]; @@ -525,11 +620,9 @@ handle_set (void *cls, struct GNUNET_SERVER_Client *client, pos->name = &pos->service[strlen (pos->service) + 1]; start = pos; -#if DEBUG_STATISTICS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New statistic on `%s:%s' with value %llu created.\n", service, name, pos->value); -#endif GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -554,6 +647,12 @@ handle_watch (void *cls, struct GNUNET_SERVER_Client *client, struct WatchEntry *we; size_t slen; + if (NULL == nc) + { + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + GNUNET_SERVER_client_mark_monitor (client); ce = make_client_entry (client); msize = ntohs (message->size); if (msize < sizeof (struct GNUNET_MessageHeader)) @@ -571,11 +670,9 @@ handle_watch (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_STATISTICS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received request to watch statistic on `%s:%s'\n", service, name); -#endif pos = start; while (pos != NULL) { @@ -590,6 +687,7 @@ handle_watch (void *cls, struct GNUNET_SERVER_Client *client, sizeof (struct GNUNET_STATISTICS_SetMessage) + size); pos->next = start; pos->uid = uidgen++; + pos->set = GNUNET_NO; pos->msg = (void *) &pos[1]; pos->msg->header.size = htons (sizeof (struct GNUNET_STATISTICS_SetMessage) + size); @@ -600,9 +698,13 @@ handle_watch (void *cls, struct GNUNET_SERVER_Client *client, pos->name = &pos->service[slen]; memcpy ((void *) pos->name, name, strlen (name) + 1); start = pos; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "New statistic on `%s:%s' with value %llu created.\n", service, + name, pos->value); } we = GNUNET_malloc (sizeof (struct WatchEntry)); we->client = client; + we->last_value_set = GNUNET_NO; GNUNET_SERVER_client_keep (client); we->wid = ce->max_wid++; GNUNET_CONTAINER_DLL_insert (pos->we_head, pos->we_tail, we); @@ -613,27 +715,20 @@ handle_watch (void *cls, struct GNUNET_SERVER_Client *client, /** - * Task run during shutdown. - * - * @param cls unused - * @param tc unused + * Actually perform the shutdown. */ -static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +static void +do_shutdown () { - struct ClientEntry *ce; struct WatchEntry *we; struct StatsEntry *se; + if (NULL == nc) + return; save (); GNUNET_SERVER_notification_context_destroy (nc); - nc = NULL; - while (NULL != (ce = client_head)) - { - GNUNET_SERVER_client_drop (ce->client); - GNUNET_CONTAINER_DLL_remove (client_head, client_tail, ce); - GNUNET_free (ce); - } + nc = NULL; + GNUNET_assert (NULL == client_head); while (NULL != (se = start)) { start = se->next; @@ -648,6 +743,22 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } +/** + * Task run during shutdown. + * + * @param cls unused + * @param tc unused + */ +static void +shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + in_shutdown = GNUNET_YES; + if (NULL != client_head) + return; + do_shutdown (); +} + + /** * A client disconnected. Remove all of its data structure entries. * @@ -689,6 +800,9 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) } se = se->next; } + if ( (NULL == client_head) && + (GNUNET_YES == in_shutdown) ) + do_shutdown (); } @@ -710,6 +824,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, {NULL, NULL, 0, 0} }; cfg = c; + srv = server; GNUNET_SERVER_add_handlers (server, handlers); nc = GNUNET_SERVER_notification_context_create (server, 16); GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); @@ -731,7 +846,7 @@ main (int argc, char *const *argv) { return (GNUNET_OK == GNUNET_SERVICE_run (argc, argv, "statistics", - GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; + GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN, &run, NULL)) ? 0 : 1; } /* end of gnunet-service-statistics.c */ diff --git a/src/statistics/gnunet-statistics.c b/src/statistics/gnunet-statistics.c index ce91572..3eef887 100644 --- a/src/statistics/gnunet-statistics.c +++ b/src/statistics/gnunet-statistics.c @@ -27,6 +27,7 @@ #include "platform.h" #include "gnunet_getopt_lib.h" #include "gnunet_program_lib.h" +#include "gnunet_util_lib.h" #include "gnunet_statistics_service.h" #include "statistics.h" @@ -52,11 +53,17 @@ static char *name; */ static int persistent; +/** + * Watch value continuously + */ +static int watch; + /** * Quiet mode */ static int quiet; + /** * Callback function to process statistic values. * @@ -71,9 +78,26 @@ static int printer (void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent) { + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); + char * now_str; if (quiet == GNUNET_NO) - FPRINTF (stdout, "%s%-12s %-50s: %16llu\n", is_persistent ? "!" : " ", - subsystem, _(name), (unsigned long long) value); + { + if (GNUNET_YES == watch) + { + now_str = GNUNET_STRINGS_absolute_time_to_string(now); + FPRINTF (stdout, "%24s %s%12s %50s: %16llu \n", + now_str, + is_persistent ? "!" : " ", + subsystem, _(name), (unsigned long long) value); + GNUNET_free (now_str); + } + else + { + FPRINTF (stdout, "%s%12s %50s: %16llu \n", + is_persistent ? "!" : " ", + subsystem, _(name), (unsigned long long) value); + } + } else FPRINTF (stdout, "%llu\n", (unsigned long long) value); @@ -98,8 +122,25 @@ cleanup (void *cls, int success) FPRINTF (stderr, "%s", _("Failed to obtain statistics.\n")); ret = 1; } - if (h != NULL) + if (NULL != h) + { + GNUNET_STATISTICS_destroy (h, GNUNET_NO); + h = NULL; + } +} + + +static void +shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_STATISTICS_Handle *h = cls; + + GNUNET_STATISTICS_watch_cancel (h, subsystem, name, &printer, h); + if (NULL != h) + { GNUNET_STATISTICS_destroy (h, GNUNET_NO); + h = NULL; + } } @@ -128,25 +169,47 @@ run (void *cls, char *const *args, const char *cfgfile, return; } h = GNUNET_STATISTICS_create (subsystem, cfg); - if (h == NULL) + if (NULL == h) { ret = 1; return; } GNUNET_STATISTICS_set (h, name, (uint64_t) val, persistent); GNUNET_STATISTICS_destroy (h, GNUNET_YES); + h = NULL; return; } h = GNUNET_STATISTICS_create ("gnunet-statistics", cfg); - if (h == NULL) + if (NULL == h) { ret = 1; return; } - if (NULL == + if (GNUNET_NO == watch) + { + if (NULL == GNUNET_STATISTICS_get (h, subsystem, name, GET_TIMEOUT, &cleanup, &printer, h)) cleanup (h, GNUNET_SYSERR); + } + else + { + if ((NULL == subsystem) || (NULL == name)) + { + printf (_("No subsystem or name given\n")); + if (h != NULL) + GNUNET_STATISTICS_destroy (h, GNUNET_NO); + ret = 1; + return; + } + if (GNUNET_OK != GNUNET_STATISTICS_watch (h, subsystem, name, &printer, h)) + { + fprintf (stderr, _("Failed to initialize watch routine\n")); + GNUNET_SCHEDULER_add_now (&shutdown_task, h); + return; + } + GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, h); + } } /** @@ -172,6 +235,9 @@ main (int argc, char *const *argv) {'q', "quiet", NULL, gettext_noop ("just print the statistics value"), 0, &GNUNET_GETOPT_set_one, &quiet}, + {'w', "watch", NULL, + gettext_noop ("watch value continously"), 0, + &GNUNET_GETOPT_set_one, &watch}, GNUNET_GETOPT_OPTION_END }; return (GNUNET_OK == diff --git a/src/statistics/statistics.conf.in b/src/statistics/statistics.conf.in index 4482b0f..5de9ded 100644 --- a/src/statistics/statistics.conf.in +++ b/src/statistics/statistics.conf.in @@ -1,6 +1,6 @@ [statistics] AUTOSTART = YES -@UNIXONLY@ PORT = 2088 +@JAVAPORT@PORT = 2088 HOSTNAME = localhost HOME = $SERVICEHOME CONFIG = $DEFAULTCONFIG diff --git a/src/statistics/statistics.h b/src/statistics/statistics.h index 3fcac27..d5f662c 100644 --- a/src/statistics/statistics.h +++ b/src/statistics/statistics.h @@ -27,7 +27,6 @@ #include "gnunet_common.h" -#define DEBUG_STATISTICS GNUNET_EXTRA_LOGGING GNUNET_NETWORK_STRUCT_BEGIN diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c index 2838b70..e1b3698 100644 --- a/src/statistics/statistics_api.c +++ b/src/statistics/statistics_api.c @@ -280,7 +280,9 @@ schedule_watch_request (struct GNUNET_STATISTICS_Handle *h, size_t nlen; size_t nsize; - GNUNET_assert (h != NULL); + GNUNET_assert (NULL != h); + GNUNET_assert (NULL != watch); + slen = strlen (watch->subsystem) + 1; nlen = strlen (watch->name) + 1; nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen; @@ -335,14 +337,14 @@ do_disconnect (struct GNUNET_STATISTICS_Handle *h) } if (NULL != h->client) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } h->receiving = GNUNET_NO; if (NULL != (c = h->current)) { h->current = NULL; - if (c->cont != NULL) + if (NULL != c->cont) c->cont (c->cls, GNUNET_SYSERR); free_action_item (c); } @@ -362,12 +364,12 @@ try_connect (struct GNUNET_STATISTICS_Handle *h) struct GNUNET_STATISTICS_GetHandle *gn; unsigned int i; - if (h->backoff_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != h->backoff_task) return GNUNET_NO; - if (h->client != NULL) + if (NULL != h->client) return GNUNET_YES; h->client = GNUNET_CLIENT_connect ("statistics", h->cfg); - if (h->client != NULL) + if (NULL != h->client) { gn = h->action_head; while (NULL != (gh = gn)) @@ -382,13 +384,14 @@ try_connect (struct GNUNET_STATISTICS_Handle *h) } } for (i = 0; i < h->watches_size; i++) - schedule_watch_request (h, h->watches[i]); + { + if (NULL != h->watches[i]) + schedule_watch_request (h, h->watches[i]); + } return GNUNET_YES; } -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, - _("Failed to connect to statistics service!\n")); -#endif + "Failed to connect to statistics service!\n"); return GNUNET_NO; } @@ -409,6 +412,22 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } +/** + * Task used by 'reconnect_later' to shutdown the handle + * + * @param cls the statistics handle + * @param tc scheduler context + */ +static void +do_destroy (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_STATISTICS_Handle *h = cls; + + GNUNET_STATISTICS_destroy (h, GNUNET_NO); +} + + /** * Reconnect at a later time, respecting back-off. * @@ -417,7 +436,29 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void reconnect_later (struct GNUNET_STATISTICS_Handle *h) { + int loss; + struct GNUNET_STATISTICS_GetHandle *gh; + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->backoff_task); + if (GNUNET_YES == h->do_destroy) + { + /* So we are shutting down and the service is not reachable. + * Chances are that it's down for good and we are not going to connect to + * it anymore. + * Give up and don't sync the rest of the data. + */ + loss = GNUNET_NO; + for (gh = h->action_head; NULL != gh; gh = gh->next) + if ( (gh->make_persistent) && (ACTION_SET == gh->type) ) + loss = GNUNET_YES; + if (GNUNET_YES == loss) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Could not save some persistent statistics\n")); + h->do_destroy = GNUNET_NO; + GNUNET_SCHEDULER_add_continuation (&do_destroy, h, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + return; + } h->backoff_task = GNUNET_SCHEDULER_add_delayed (h->backoff, &reconnect_task, h); h->backoff = GNUNET_TIME_relative_multiply (h->backoff, 2); @@ -444,9 +485,7 @@ process_statistics_value_message (struct GNUNET_STATISTICS_Handle *h, if (h->current->aborted) { -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Iteration was aborted, ignoring VALUE\n"); -#endif return GNUNET_OK; /* don't bother */ } size = ntohs (msg->size); @@ -464,25 +503,19 @@ process_statistics_value_message (struct GNUNET_STATISTICS_Handle *h, GNUNET_break (0); return GNUNET_SYSERR; } -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Received valid statistic on `%s:%s': %llu\n", service, name, GNUNET_ntohll (smsg->value)); -#endif if (GNUNET_OK != h->current->proc (h->current->cls, service, name, GNUNET_ntohll (smsg->value), 0 != (ntohl (smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT))) { -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing of remaining statistics aborted by client.\n"); -#endif h->current->aborted = GNUNET_YES; } -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "VALUE processed successfully\n"); -#endif return GNUNET_OK; } @@ -526,6 +559,16 @@ process_watch_value (struct GNUNET_STATISTICS_Handle *h, } +static void +destroy_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_STATISTICS_Handle *h = cls; + + GNUNET_STATISTICS_destroy (h, GNUNET_NO); +} + + /** * Function called with messages from stats service. * @@ -539,22 +582,31 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg) struct GNUNET_STATISTICS_GetHandle *c; int ret; - if (msg == NULL) + if (NULL == msg) { -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Error receiving statistics from service, is the service running?\n"); -#endif do_disconnect (h); reconnect_later (h); return; } switch (ntohs (msg->type)) { + case GNUNET_MESSAGE_TYPE_TEST: + if (GNUNET_SYSERR != h->do_destroy) + { + /* not in shutdown, why do we get 'TEST'? */ + GNUNET_break (0); + do_disconnect (h); + reconnect_later (h); + return; + } + h->do_destroy = GNUNET_NO; + GNUNET_SCHEDULER_add_continuation (&destroy_task, h, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + break; case GNUNET_MESSAGE_TYPE_STATISTICS_END: -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Received end of statistics marker\n"); -#endif if (NULL == (c = h->current)) { GNUNET_break (0); @@ -574,7 +626,7 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg) } h->current = NULL; schedule_action (h); - if (c->cont != NULL) + if (NULL != c->cont) c->cont (c->cls, GNUNET_OK); free_action_item (c); return; @@ -586,10 +638,8 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg) return; } /* finally, look for more! */ -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing VALUE done, now reading more\n"); -#endif GNUNET_CLIENT_receive (h->client, &receive_stats, h, GNUNET_TIME_absolute_get_remaining (h-> current->timeout)); @@ -638,13 +688,11 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf) uint16_t msize; GNUNET_assert (NULL != (c = handle->current)); - if (buf == NULL) + if (NULL == buf) { /* timeout / error */ -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission of request for statistics failed!\n"); -#endif do_disconnect (handle); reconnect_later (handle); return 0; @@ -662,10 +710,8 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf) c->name)); if (GNUNET_YES != handle->receiving) { -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission of GET done, now reading response\n"); -#endif handle->receiving = GNUNET_YES; GNUNET_CLIENT_receive (handle->client, &receive_stats, handle, GNUNET_TIME_absolute_get_remaining (c->timeout)); @@ -691,21 +737,17 @@ transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf) size_t slen2; uint16_t msize; - if (buf == NULL) + if (NULL == buf) { /* timeout / error */ -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission of request for statistics failed!\n"); -#endif do_disconnect (handle); reconnect_later (handle); return 0; } -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting watch request for `%s'\n", handle->current->name); -#endif slen1 = strlen (handle->current->subsystem) + 1; slen2 = strlen (handle->current->name) + 1; msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader); @@ -833,8 +875,8 @@ GNUNET_STATISTICS_create (const char *subsystem, { struct GNUNET_STATISTICS_Handle *ret; - GNUNET_assert (subsystem != NULL); - GNUNET_assert (cfg != NULL); + GNUNET_assert (NULL != subsystem); + GNUNET_assert (NULL != cfg); ret = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_Handle)); ret->cfg = cfg; ret->subsystem = GNUNET_strdup (subsystem); @@ -859,8 +901,9 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first) struct GNUNET_TIME_Relative timeout; int i; - if (h == NULL) + if (NULL == h) return; + GNUNET_assert (GNUNET_NO == h->do_destroy); // Don't call twice. if (GNUNET_SCHEDULER_NO_TASK != h->backoff_task) { GNUNET_SCHEDULER_cancel (h->backoff_task); @@ -868,9 +911,9 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first) } if (sync_first) { - if (h->current != NULL) + if (NULL != h->current) { - if (h->current->type == ACTION_GET) + if (ACTION_GET == h->current->type) { GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); h->th = NULL; @@ -882,7 +925,7 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first) while (NULL != (pos = next)) { next = pos->next; - if (pos->type == ACTION_GET) + if (ACTION_GET == pos->type) { GNUNET_CONTAINER_DLL_remove (h->action_head, h->action_tail, @@ -896,24 +939,17 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first) h->action_tail, h->current); h->do_destroy = GNUNET_YES; - if ((h->current != NULL) && (h->th == NULL)) + if ((NULL != h->current) && (NULL == h->th) && + (NULL != h->client)) { - if (NULL == h->client) - { - /* instant-connect (regardless of back-off) to submit final value */ - h->client = GNUNET_CLIENT_connect ("statistics", h->cfg); - } - if (NULL != h->client) - { - timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout); - h->th = - GNUNET_CLIENT_notify_transmit_ready (h->client, h->current->msize, - timeout, GNUNET_YES, - &transmit_action, h); - GNUNET_assert (NULL != h->th); - } + timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout); + h->th = + GNUNET_CLIENT_notify_transmit_ready (h->client, h->current->msize, + timeout, GNUNET_YES, + &transmit_action, h); + GNUNET_assert (NULL != h->th); } - if (h->th != NULL) + if (NULL != h->th) return; /* do not finish destruction just yet */ } while (NULL != (pos = h->action_head)) @@ -938,6 +974,47 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first) } +/** + * Function called to transmit TEST message to service to + * confirm that the service has received all of our 'SET' + * messages (during statistics disconnect/shutdown). + * + * @param cls the 'struct GNUNET_STATISTICS_Handle' + * @param size how many bytes can we write to buf + * @param buf where to write requests to the service + * @return number of bytes written to buf + */ +static size_t +transmit_test_on_shutdown (void *cls, + size_t size, + void *buf) +{ + struct GNUNET_STATISTICS_Handle *h = cls; + struct GNUNET_MessageHeader hdr; + + h->th = NULL; + if (NULL == buf) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to receive acknowledgement from statistics service, some statistics might have been lost!\n")); + h->do_destroy = GNUNET_NO; + GNUNET_SCHEDULER_add_continuation (&destroy_task, h, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + return 0; + } + hdr.type = htons (GNUNET_MESSAGE_TYPE_TEST); + hdr.size = htons (sizeof (struct GNUNET_MessageHeader)); + memcpy (buf, &hdr, sizeof (hdr)); + if (GNUNET_YES != h->receiving) + { + h->receiving = GNUNET_YES; + GNUNET_CLIENT_receive (h->client, &receive_stats, h, + GNUNET_TIME_UNIT_FOREVER_REL); + } + return sizeof (struct GNUNET_MessageHeader); +} + + /** * Schedule the next action to be performed. * @@ -948,8 +1025,8 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h) { struct GNUNET_TIME_Relative timeout; - if ( (h->th != NULL) || - (h->backoff_task != GNUNET_SCHEDULER_NO_TASK) ) + if ( (NULL != h->th) || + (GNUNET_SCHEDULER_NO_TASK != h->backoff_task) ) return; /* action already pending */ if (GNUNET_YES != try_connect (h)) { @@ -962,10 +1039,14 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h) h->current = h->action_head; if (NULL == h->current) { - if (h->do_destroy) + if (GNUNET_YES == h->do_destroy) { - h->do_destroy = GNUNET_NO; - GNUNET_STATISTICS_destroy (h, GNUNET_YES); + h->do_destroy = GNUNET_SYSERR; /* in 'TEST' mode */ + h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, + sizeof (struct GNUNET_MessageHeader), + SET_TRANSMIT_TIMEOUT, + GNUNET_NO, + &transmit_test_on_shutdown, h); } return; } @@ -977,10 +1058,8 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h) timeout, GNUNET_YES, &transmit_action, h))) { -#if DEBUG_STATISTICS LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to transmit request to statistics service.\n"); -#endif do_disconnect (h); reconnect_later (h); } @@ -996,6 +1075,7 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h) * @param timeout after how long should we give up (and call * cont with an error code)? * @param cont continuation to call when done (can be NULL) + * This callback CANNOT destroy the statistics handle in the same call. * @param proc function to call on each value * @param cls closure for cont and proc * @return NULL on error @@ -1013,11 +1093,11 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle, if (NULL == handle) return NULL; - GNUNET_assert (proc != NULL); + GNUNET_assert (NULL != proc); GNUNET_assert (GNUNET_NO == handle->do_destroy); - if (subsystem == NULL) + if (NULL == subsystem) subsystem = ""; - if (name == NULL) + if (NULL == name) name = ""; slen1 = strlen (subsystem) + 1; slen2 = strlen (name) + 1; @@ -1082,7 +1162,7 @@ GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle, { struct GNUNET_STATISTICS_WatchEntry *w; - if (handle == NULL) + if (NULL == handle) return GNUNET_SYSERR; w = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_WatchEntry)); w->subsystem = GNUNET_strdup (subsystem); @@ -1113,11 +1193,13 @@ GNUNET_STATISTICS_watch_cancel (struct GNUNET_STATISTICS_Handle *handle, struct GNUNET_STATISTICS_WatchEntry *w; unsigned int i; - if (handle == NULL) + if (NULL == handle) return GNUNET_SYSERR; for (i=0;iwatches_size;i++) { w = handle->watches[i]; + if (NULL == w) + continue; if ( (w->proc == proc) && (w->proc_cls == proc_cls) && (0 == strcmp (w->name, name)) && @@ -1154,8 +1236,8 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h, const char *name, size_t nsize; int64_t delta; - GNUNET_assert (h != NULL); - GNUNET_assert (name != NULL); + GNUNET_assert (NULL != h); + GNUNET_assert (NULL != name); slen = strlen (h->subsystem) + 1; nlen = strlen (name) + 1; nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen; @@ -1164,16 +1246,16 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h, const char *name, GNUNET_break (0); return; } - for (ai = h->action_head; ai != NULL; ai = ai->next) + for (ai = h->action_head; NULL != ai; ai = ai->next) { if (! ( (0 == strcmp (ai->subsystem, h->subsystem)) && (0 == strcmp (ai->name, name)) && - ( (ai->type == ACTION_UPDATE) || - (ai->type == ACTION_SET) ) ) ) + ( (ACTION_UPDATE == ai->type) || + (ACTION_SET == ai->type) ) ) ) continue; - if (ai->type == ACTION_SET) + if (ACTION_SET == ai->type) { - if (type == ACTION_UPDATE) + if (ACTION_UPDATE == type) { delta = (int64_t) value; if (delta > 0) @@ -1198,7 +1280,7 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h, const char *name, } else { - if (type == ACTION_UPDATE) + if (ACTION_UPDATE == type) { /* make delta cummulative */ delta = (int64_t) value; @@ -1244,7 +1326,7 @@ void GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent) { - if (handle == NULL) + if (NULL == handle) return; GNUNET_assert (GNUNET_NO == handle->do_destroy); add_setter_action (handle, name, make_persistent, value, ACTION_SET); @@ -1264,9 +1346,9 @@ void GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent) { - if (handle == NULL) + if (NULL == handle) return; - if (delta == 0) + if (0 == delta) return; GNUNET_assert (GNUNET_NO == handle->do_destroy); add_setter_action (handle, name, make_persistent, (uint64_t) delta, diff --git a/src/statistics/test_statistics_api.c b/src/statistics/test_statistics_api.c index 0647a49..11f02b8 100644 --- a/src/statistics/test_statistics_api.c +++ b/src/statistics/test_statistics_api.c @@ -29,7 +29,6 @@ #include "gnunet_scheduler_lib.h" #include "gnunet_statistics_service.h" -#define DEBUG_STATISTICS GNUNET_EXTRA_LOGGING #define START_SERVICE GNUNET_YES @@ -130,11 +129,7 @@ check () char *const argv[] = { "test-statistics-api", "-c", "test_statistics_api_data.conf", -#if DEBUG_STATISTICS - "-L", "DEBUG", -#else "-L", "WARNING", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -146,9 +141,6 @@ check () proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-statistics", "gnunet-service-statistics", -#if DEBUG_STATISTICS - "-L", "DEBUG", -#endif "-c", "test_statistics_api_data.conf", NULL); #endif GNUNET_assert (NULL != proc); @@ -161,7 +153,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; #endif if (ok != 0) @@ -172,9 +164,6 @@ check () proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-statistics", "gnunet-service-statistics", -#if DEBUG_STATISTICS - "-L", "DEBUG", -#endif "-c", "test_statistics_api_data.conf", NULL); #endif GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp", options, @@ -186,7 +175,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; #endif return ok; @@ -198,11 +187,7 @@ main (int argc, char *argv[]) int ret; GNUNET_log_setup ("test_statistics_api", -#if DEBUG_STATISTICS - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); diff --git a/src/statistics/test_statistics_api_data.conf b/src/statistics/test_statistics_api_data.conf index 9ccb770..4e229e9 100644 --- a/src/statistics/test_statistics_api_data.conf +++ b/src/statistics/test_statistics_api_data.conf @@ -31,13 +31,24 @@ AUTOSTART = NO [peerinfo] AUTOSTART = NO - [dns] AUTOSTART = NO +[nse] +AUTOSTART = NO +[lockmanager] +AUTOSTART = NO -[nse] +[ats] AUTOSTART = NO +[namestore] +AUTOSTART = NO + +[gns] +AUTOSTART = NO + +[vpn] +AUTOSTART = NO diff --git a/src/statistics/test_statistics_api_loop.c b/src/statistics/test_statistics_api_loop.c index 32b176c..58114f2 100644 --- a/src/statistics/test_statistics_api_loop.c +++ b/src/statistics/test_statistics_api_loop.c @@ -114,7 +114,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; #endif return ok; diff --git a/src/statistics/test_statistics_api_watch.c b/src/statistics/test_statistics_api_watch.c index 979b561..e976bd4 100644 --- a/src/statistics/test_statistics_api_watch.c +++ b/src/statistics/test_statistics_api_watch.c @@ -145,7 +145,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; #endif return ok; diff --git a/src/statistics/test_statistics_api_watch_zero_value.c b/src/statistics/test_statistics_api_watch_zero_value.c new file mode 100644 index 0000000..9fadf6a --- /dev/null +++ b/src/statistics/test_statistics_api_watch_zero_value.c @@ -0,0 +1,201 @@ +/* + This file is part of GNUnet. + (C) 2009, 2011 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file statistics/test_statistics_api_watch_zero_value.c + * @brief testcase for statistics_api.c watch functions with initial 0 value + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_getopt_lib.h" +#include "gnunet_os_lib.h" +#include "gnunet_program_lib.h" +#include "gnunet_scheduler_lib.h" +#include "gnunet_statistics_service.h" + +#define VERBOSE GNUNET_NO + +#define START_SERVICE GNUNET_YES + +static int ok; +static int ok2; + +static struct GNUNET_STATISTICS_Handle *h; +static struct GNUNET_STATISTICS_Handle *h2; + +static GNUNET_SCHEDULER_TaskIdentifier shutdown_task; + + +static void +force_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + fprintf (stderr, "Timeout, failed to receive notifications: %d\n", ok); + GNUNET_STATISTICS_destroy (h, GNUNET_NO); + GNUNET_STATISTICS_destroy (h2, GNUNET_NO); + ok = 7; +} + + +static void +normal_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_STATISTICS_destroy (h, GNUNET_NO); + GNUNET_STATISTICS_destroy (h2, GNUNET_NO); +} + + +static int +watch_1 (void *cls, const char *subsystem, const char *name, uint64_t value, + int is_persistent) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received value `%s' `%s' %llu\n", + subsystem, name, value); + GNUNET_assert (0 == strcmp (name, "test-1")); + if ((0 == value) && (3 == ok)) + { + ok--; + GNUNET_STATISTICS_set (h, "test-1", 42, GNUNET_NO); + } + + if ((42 == value) && (2 == ok)) + { + ok--; + GNUNET_STATISTICS_set (h, "test-1", 0, GNUNET_NO); + } + + if ((0 == value) && (1 == ok)) + { + ok--; + } + if ((0 == ok) && (0 == ok2)) + { + GNUNET_SCHEDULER_cancel (shutdown_task); + GNUNET_SCHEDULER_add_now (&normal_shutdown, NULL); + } + + return GNUNET_OK; +} + +static int +watch_2 (void *cls, const char *subsystem, const char *name, uint64_t value, + int is_persistent) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received value `%s' `%s' %llu\n", + subsystem, name, value); + + GNUNET_assert (0 == strcmp (name, "test-2")); + if ((42 == value) && (1 == ok2)) + { + ok2 = 0; + if (0 == ok) + { + GNUNET_SCHEDULER_cancel (shutdown_task); + GNUNET_SCHEDULER_add_now (&normal_shutdown, NULL); + } + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received unexpected value %llu\n", value); + + GNUNET_break (0); + GNUNET_SCHEDULER_cancel (shutdown_task); + GNUNET_SCHEDULER_add_now (&normal_shutdown, NULL); + } + + return GNUNET_OK; +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + h = GNUNET_STATISTICS_create ("dummy", cfg); + h2 = GNUNET_STATISTICS_create ("dummy-2", cfg); + GNUNET_assert (GNUNET_OK == + GNUNET_STATISTICS_watch (h, "dummy", + "test-1", &watch_1, NULL)); + + GNUNET_assert (GNUNET_OK == + GNUNET_STATISTICS_watch (h2, "dummy-2", + "test-2", &watch_2, NULL)); + + /* Set initial value to 0 */ + GNUNET_STATISTICS_set (h, "test-1", 0, GNUNET_NO); + GNUNET_STATISTICS_set (h2, "test-2", 42, GNUNET_NO); + + shutdown_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &force_shutdown, + NULL); +} + + +static int +check () +{ + char *const argv[] = { "test-statistics-api", + "-c", + "test_statistics_api_data.conf", + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; +#if START_SERVICE + struct GNUNET_OS_Process *proc; + + proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-statistics", + "gnunet-service-statistics", +#if VERBOSE + "-L", "DEBUG", +#endif + "-c", "test_statistics_api_data.conf", NULL); +#endif + GNUNET_assert (NULL != proc); + ok = 3; + ok2 = 1; + GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp", options, &run, + NULL); +#if START_SERVICE + if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + ok = 1; + } + GNUNET_OS_process_wait (proc); + GNUNET_OS_process_destroy (proc); + proc = NULL; +#endif + if ((0 == ok) && (0 == ok2)) + return 0; + else + return 1; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_statistics_api_watch_zero_value.c */ diff --git a/src/stream/Makefile.am b/src/stream/Makefile.am index 385c0cf..8d74417 100644 --- a/src/stream/Makefile.am +++ b/src/stream/Makefile.am @@ -20,8 +20,9 @@ libgnunetstream_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) check_PROGRAMS = \ - test_stream_local -# test_stream_halfclose + test-stream-2peers \ + test-stream-2peers_halfclose \ + test-stream-local EXTRA_DIST = test_stream_local.conf @@ -29,15 +30,23 @@ if ENABLE_TEST_RUN TESTS = $(check_PROGRAMS) endif +test_stream_2peers_SOURCES = \ + test_stream_2peers.c +test_stream_2peers_LDADD = \ + $(top_builddir)/src/stream/libgnunetstream.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_stream_2peers_halfclose_SOURCES = \ + test_stream_2peers_halfclose.c +test_stream_2peers_halfclose_LDADD = \ + $(top_builddir)/src/stream/libgnunetstream.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la + test_stream_local_SOURCES = \ test_stream_local.c test_stream_local_LDADD = \ $(top_builddir)/src/stream/libgnunetstream.la \ - $(top_builddir)/src/util/libgnunetutil.la - -#test_stream_halfclose_SOURCES = \ -# test_stream_halfclose.c -#test_stream_halfclose_LDADD = \ -# $(top_builddir)/src/stream/libgnunetstream.la \ -# $(top_builddir)/src/util/libgnunetutil.la - + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ No newline at end of file diff --git a/src/stream/Makefile.in b/src/stream/Makefile.in index 44b63f7..9f1c278 100644 --- a/src/stream/Makefile.in +++ b/src/stream/Makefile.in @@ -35,7 +35,9 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -check_PROGRAMS = test_stream_local$(EXEEXT) +check_PROGRAMS = test-stream-2peers$(EXEEXT) \ + test-stream-2peers_halfclose$(EXEEXT) \ + test-stream-local$(EXEEXT) subdir = src/stream DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -94,11 +96,26 @@ libgnunetstream_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunetstream_la_LDFLAGS) \ $(LDFLAGS) -o $@ +am_test_stream_2peers_OBJECTS = test_stream_2peers.$(OBJEXT) +test_stream_2peers_OBJECTS = $(am_test_stream_2peers_OBJECTS) +test_stream_2peers_DEPENDENCIES = \ + $(top_builddir)/src/stream/libgnunetstream.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la +am_test_stream_2peers_halfclose_OBJECTS = \ + test_stream_2peers_halfclose.$(OBJEXT) +test_stream_2peers_halfclose_OBJECTS = \ + $(am_test_stream_2peers_halfclose_OBJECTS) +test_stream_2peers_halfclose_DEPENDENCIES = \ + $(top_builddir)/src/stream/libgnunetstream.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la am_test_stream_local_OBJECTS = test_stream_local.$(OBJEXT) test_stream_local_OBJECTS = $(am_test_stream_local_OBJECTS) test_stream_local_DEPENDENCIES = \ $(top_builddir)/src/stream/libgnunetstream.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -125,8 +142,12 @@ am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libgnunetstream_la_SOURCES) $(test_stream_local_SOURCES) +SOURCES = $(libgnunetstream_la_SOURCES) $(test_stream_2peers_SOURCES) \ + $(test_stream_2peers_halfclose_SOURCES) \ + $(test_stream_local_SOURCES) DIST_SOURCES = $(libgnunetstream_la_SOURCES) \ + $(test_stream_2peers_SOURCES) \ + $(test_stream_2peers_halfclose_SOURCES) \ $(test_stream_local_SOURCES) ETAGS = etags CTAGS = ctags @@ -188,6 +209,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -221,6 +243,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -352,15 +375,31 @@ libgnunetstream_la_LIBADD = \ libgnunetstream_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) -# test_stream_halfclose EXTRA_DIST = test_stream_local.conf @ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) +test_stream_2peers_SOURCES = \ + test_stream_2peers.c + +test_stream_2peers_LDADD = \ + $(top_builddir)/src/stream/libgnunetstream.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la + +test_stream_2peers_halfclose_SOURCES = \ + test_stream_2peers_halfclose.c + +test_stream_2peers_halfclose_LDADD = \ + $(top_builddir)/src/stream/libgnunetstream.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la + test_stream_local_SOURCES = \ test_stream_local.c test_stream_local_LDADD = \ $(top_builddir)/src/stream/libgnunetstream.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la all: all-am @@ -438,8 +477,14 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -test_stream_local$(EXEEXT): $(test_stream_local_OBJECTS) $(test_stream_local_DEPENDENCIES) - @rm -f test_stream_local$(EXEEXT) +test-stream-2peers$(EXEEXT): $(test_stream_2peers_OBJECTS) $(test_stream_2peers_DEPENDENCIES) + @rm -f test-stream-2peers$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_stream_2peers_OBJECTS) $(test_stream_2peers_LDADD) $(LIBS) +test-stream-2peers_halfclose$(EXEEXT): $(test_stream_2peers_halfclose_OBJECTS) $(test_stream_2peers_halfclose_DEPENDENCIES) + @rm -f test-stream-2peers_halfclose$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_stream_2peers_halfclose_OBJECTS) $(test_stream_2peers_halfclose_LDADD) $(LIBS) +test-stream-local$(EXEEXT): $(test_stream_local_OBJECTS) $(test_stream_local_DEPENDENCIES) + @rm -f test-stream-local$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_stream_local_OBJECTS) $(test_stream_local_LDADD) $(LIBS) mostlyclean-compile: @@ -449,6 +494,8 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_stream_2peers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_stream_2peers_halfclose.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_stream_local.Po@am__quote@ .c.o: @@ -778,12 +825,6 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-am uninstall-libLTLIBRARIES -#test_stream_halfclose_SOURCES = \ -# test_stream_halfclose.c -#test_stream_halfclose_LDADD = \ -# $(top_builddir)/src/stream/libgnunetstream.la \ -# $(top_builddir)/src/util/libgnunetutil.la - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/stream/README b/src/stream/README index 9b550b0..977ca2d 100644 --- a/src/stream/README +++ b/src/stream/README @@ -1,11 +1,11 @@ -The aim of the stream library is to provide stream connections between peers in -GNUnet. This is a convenience library which hides the complexity of dividing -data stream into packets, transmitting them and retransmitting them in case of +Stream library provides stream connections between peers in GNUnet. This is a +convenience library which hides the complexity of dividing data stream into +packets, transmitting them and retransmitting them in case of communication errors. This library's API are similar to unix PIPE API. The user is expected to open a stream to a listening target peer. Once the stream is established, the user can -use it as a pipe. Any data written into the stream will be readable by the -target peer. +use it as a pipe. Any data written into the stream at one peer will be readable +by the other peer and vice versa. -This library uses mesh API for establishing streams between peers. \ No newline at end of file +This library uses mesh API for establishing tunnels between peers. \ No newline at end of file diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c index 84fcdfd..dadba33 100644 --- a/src/stream/stream_api.c +++ b/src/stream/stream_api.c @@ -18,17 +18,31 @@ Boston, MA 02111-1307, USA. */ +/* TODO: + * + * Checks for matching the sender and socket->other_peer in server + * message handlers + * + * Add code for write io timeout + * + * Include retransmission for control messages + **/ + /** * @file stream/stream_api.c * @brief Implementation of the stream library * @author Sree Harsha Totakura */ + + #include "platform.h" #include "gnunet_common.h" #include "gnunet_crypto_lib.h" #include "gnunet_stream_lib.h" #include "stream_protocol.h" +#define LOG(kind,...) \ + GNUNET_log_from (kind, "stream-api", __VA_ARGS__) /** * The maximum packet size of a stream packet @@ -36,15 +50,15 @@ #define MAX_PACKET_SIZE 64000 /** - * The maximum payload a data message packet can carry + * Receive buffer */ -static size_t max_payload_size = - MAX_PACKET_SIZE - sizeof (struct GNUNET_STREAM_DataMessage); +#define RECEIVE_BUFFER_SIZE 4096000 /** - * Receive buffer + * The maximum payload a data message packet can carry */ -#define RECEIVE_BUFFER_SIZE 4096000 +static size_t max_payload_size = + MAX_PACKET_SIZE - sizeof (struct GNUNET_STREAM_DataMessage); /** * states in the Protocol @@ -150,12 +164,6 @@ struct MessageQueue */ struct GNUNET_STREAM_Socket { - - /** - * The peer identity of the peer at the other end of the stream - */ - struct GNUNET_PeerIdentity other_peer; - /** * Retransmission timeout */ @@ -176,16 +184,6 @@ struct GNUNET_STREAM_Socket */ struct GNUNET_TIME_Relative ack_time_deadline; - /** - * The task for sending timely Acks - */ - GNUNET_SCHEDULER_TaskIdentifier ack_task_id; - - /** - * Task scheduled to continue a read operation. - */ - GNUNET_SCHEDULER_TaskIdentifier read_task; - /** * The mesh handle */ @@ -211,6 +209,16 @@ struct GNUNET_STREAM_Socket */ struct GNUNET_MESH_TransmitHandle *transmit_handle; + /** + * The current act transmit handle (if a pending ack transmit request exists) + */ + struct GNUNET_MESH_TransmitHandle *ack_transmit_handle; + + /** + * Pointer to the current ack message using in ack_task + */ + struct GNUNET_STREAM_AckMessage *ack_msg; + /** * The current message associated with the transmit handle */ @@ -231,15 +239,46 @@ struct GNUNET_STREAM_Socket */ struct GNUNET_STREAM_IOReadHandle *read_handle; + /** + * The shutdown handle associated with this socket + */ + struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; + /** * Buffer for storing received messages */ void *receive_buffer; + /** + * The listen socket from which this socket is derived. Should be NULL if it + * is not a derived socket + */ + struct GNUNET_STREAM_ListenSocket *lsocket; + + /** + * The peer identity of the peer at the other end of the stream + */ + struct GNUNET_PeerIdentity other_peer; + /** * Task identifier for the read io timeout task */ - GNUNET_SCHEDULER_TaskIdentifier read_io_timeout_task; + GNUNET_SCHEDULER_TaskIdentifier read_io_timeout_task_id; + + /** + * Task identifier for retransmission task after timeout + */ + GNUNET_SCHEDULER_TaskIdentifier retransmission_timeout_task_id; + + /** + * The task for sending timely Acks + */ + GNUNET_SCHEDULER_TaskIdentifier ack_task_id; + + /** + * Task scheduled to continue a read operation. + */ + GNUNET_SCHEDULER_TaskIdentifier read_task_id; /** * The state of the protocol associated with this socket @@ -256,6 +295,11 @@ struct GNUNET_STREAM_Socket */ unsigned int retries; + /** + * The application port number (type: uint32_t) + */ + GNUNET_MESH_ApplicationType app_port; + /** * The session id associated with this stream connection * FIXME: Not used currently, may be removed @@ -286,7 +330,7 @@ struct GNUNET_STREAM_Socket /** * receiver's available buffer after the last acknowledged packet */ - uint32_t receive_window_available; + uint32_t receiver_window_available; /** * The offset pointer used during write operation @@ -310,7 +354,6 @@ struct GNUNET_STREAM_Socket */ struct GNUNET_STREAM_ListenSocket { - /** * The mesh handle */ @@ -328,6 +371,7 @@ struct GNUNET_STREAM_ListenSocket /** * The service port + * FIXME: Remove if not required! */ GNUNET_MESH_ApplicationType port; }; @@ -338,10 +382,25 @@ struct GNUNET_STREAM_ListenSocket */ struct GNUNET_STREAM_IOWriteHandle { + /** + * The socket to which this write handle is associated + */ + struct GNUNET_STREAM_Socket *socket; + /** * The packet_buffers associated with this Handle */ - struct GNUNET_STREAM_DataMessage *messages[64]; + struct GNUNET_STREAM_DataMessage *messages[GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH]; + + /** + * The write continuation callback + */ + GNUNET_STREAM_CompletionContinuation write_cont; + + /** + * Write continuation closure + */ + void *write_cont_cls; /** * The bitmap of this IOHandle; Corresponding bit for a message is set when @@ -350,11 +409,9 @@ struct GNUNET_STREAM_IOWriteHandle GNUNET_STREAM_AckBitmap ack_bitmap; /** - * Number of packets sent before waiting for an ack - * - * FIXME: Do we need this? + * Number of bytes in this write handle */ - unsigned int sent_packets; + size_t size; }; @@ -375,14 +432,46 @@ struct GNUNET_STREAM_IOReadHandle }; +/** + * Handle for Shutdown + */ +struct GNUNET_STREAM_ShutdownHandle +{ + /** + * The socket associated with this shutdown handle + */ + struct GNUNET_STREAM_Socket *socket; + + /** + * Shutdown completion callback + */ + GNUNET_STREAM_ShutdownCompletion completion_cb; + + /** + * Closure for completion callback + */ + void *completion_cls; + + /** + * Close message retransmission task id + */ + GNUNET_SCHEDULER_TaskIdentifier close_msg_retransmission_task_id; + + /** + * Which operation to shutdown? SHUT_RD, SHUT_WR or SHUT_RDWR + */ + int operation; +}; + + /** * Default value in seconds for various timeouts */ -static unsigned int default_timeout = 300; +static unsigned int default_timeout = 10; /** - * Callback function for sending hello message + * Callback function for sending queued message * * @param cls closure the socket * @param size number of bytes available in buf @@ -401,31 +490,32 @@ send_message_notify (void *cls, size_t size, void *buf) if (NULL == head) return 0; /* just to be safe */ if (0 == size) /* request timed out */ - { - socket->retries++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Message sending timed out. Retry %d \n", - socket->retries); - socket->transmit_handle = - GNUNET_MESH_notify_transmit_ready (socket->tunnel, - 0, /* Corking */ - 1, /* Priority */ - /* FIXME: exponential backoff */ - socket->retransmit_timeout, - &socket->other_peer, - ntohs (head->message->header.size), - &send_message_notify, - socket); - return 0; - } + { + socket->retries++; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Message sending timed out. Retry %d \n", + GNUNET_i2s (&socket->other_peer), + socket->retries); + socket->transmit_handle = + GNUNET_MESH_notify_transmit_ready (socket->tunnel, + 0, /* Corking */ + 1, /* Priority */ + /* FIXME: exponential backoff */ + socket->retransmit_timeout, + &socket->other_peer, + ntohs (head->message->header.size), + &send_message_notify, + socket); + return 0; + } ret = ntohs (head->message->header.size); GNUNET_assert (size >= ret); memcpy (buf, head->message, ret); if (NULL != head->finish_cb) - { - head->finish_cb (socket, head->finish_cb_cls); - } + { + head->finish_cb (head->finish_cb_cls, socket); + } GNUNET_CONTAINER_DLL_remove (socket->queue_head, socket->queue_tail, head); @@ -433,19 +523,19 @@ send_message_notify (void *cls, size_t size, void *buf) GNUNET_free (head); head = socket->queue_head; if (NULL != head) /* more pending messages to send */ - { - socket->retries = 0; - socket->transmit_handle = - GNUNET_MESH_notify_transmit_ready (socket->tunnel, - 0, /* Corking */ - 1, /* Priority */ - /* FIXME: exponential backoff */ - socket->retransmit_timeout, - &socket->other_peer, - ntohs (head->message->header.size), - &send_message_notify, - socket); - } + { + socket->retries = 0; + socket->transmit_handle = + GNUNET_MESH_notify_transmit_ready (socket->tunnel, + 0, /* Corking */ + 1, /* Priority */ + /* FIXME: exponential backoff */ + socket->retransmit_timeout, + &socket->other_peer, + ntohs (head->message->header.size), + &send_message_notify, + socket); + } return ret; } @@ -466,6 +556,16 @@ queue_message (struct GNUNET_STREAM_Socket *socket, { struct MessageQueue *queue_entity; + GNUNET_assert + ((ntohs (message->header.type) >= GNUNET_MESSAGE_TYPE_STREAM_DATA) + && (ntohs (message->header.type) <= GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK)); + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Queueing message of type %d and size %d\n", + GNUNET_i2s (&socket->other_peer), + ntohs (message->header.type), + ntohs (message->header.size)); + GNUNET_assert (NULL != message); queue_entity = GNUNET_malloc (sizeof (struct MessageQueue)); queue_entity->message = message; queue_entity->finish_cb = finish_cb; @@ -489,6 +589,31 @@ queue_message (struct GNUNET_STREAM_Socket *socket, } +/** + * Copies a message and queues it for sending using the mesh connection of + * given socket + * + * @param socket the socket whose mesh connection is used + * @param message the message to be sent + * @param finish_cb the callback to be called when the message is sent + * @param finish_cb_cls the closure for the callback + */ +static void +copy_and_queue_message (struct GNUNET_STREAM_Socket *socket, + const struct GNUNET_STREAM_MessageHeader *message, + SendFinishCallback finish_cb, + void *finish_cb_cls) +{ + struct GNUNET_STREAM_MessageHeader *msg_copy; + uint16_t size; + + size = ntohs (message->header.size); + msg_copy = GNUNET_malloc (size); + memcpy (msg_copy, message, size); + queue_message (socket, msg_copy, finish_cb, finish_cb_cls); +} + + /** * Callback function for sending ack message * @@ -500,21 +625,56 @@ queue_message (struct GNUNET_STREAM_Socket *socket, static size_t send_ack_notify (void *cls, size_t size, void *buf) { - struct GNUNET_STREAM_AckMessage *ack_msg = cls; + struct GNUNET_STREAM_Socket *socket = cls; if (0 == size) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "%s called with size 0\n", __func__); - return 0; - } - GNUNET_assert (ack_msg->header.header.size <= size); + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s called with size 0\n", __func__); + return 0; + } + GNUNET_assert (ntohs (socket->ack_msg->header.header.size) <= size); - size = ack_msg->header.header.size; - memcpy (buf, ack_msg, size); + size = ntohs (socket->ack_msg->header.header.size); + memcpy (buf, socket->ack_msg, size); + + GNUNET_free (socket->ack_msg); + socket->ack_msg = NULL; + socket->ack_transmit_handle = NULL; return size; } +/** + * Writes data using the given socket. The amount of data written is limited by + * the receiver_window_size + * + * @param socket the socket to use + */ +static void +write_data (struct GNUNET_STREAM_Socket *socket); + +/** + * Task for retransmitting data messages if they aren't ACK before their ack + * deadline + * + * @param cls the socket + * @param tc the Task context + */ +static void +retransmission_timeout_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_STREAM_Socket *socket = cls; + + if (GNUNET_SCHEDULER_REASON_SHUTDOWN == tc->reason) + return; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Retransmitting DATA...\n", GNUNET_i2s (&socket->other_peer)); + socket->retransmission_timeout_task_id = GNUNET_SCHEDULER_NO_TASK; + write_data (socket); +} + /** * Task for sending ACK message @@ -530,12 +690,10 @@ ack_task (void *cls, struct GNUNET_STREAM_AckMessage *ack_msg; if (GNUNET_SCHEDULER_REASON_SHUTDOWN == tc->reason) - { - return; - } - - socket->ack_task_id = 0; - + { + return; + } + socket->ack_task_id = GNUNET_SCHEDULER_NO_TASK; /* Create the ACK Message */ ack_msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_AckMessage)); ack_msg->header.header.size = htons (sizeof (struct @@ -545,18 +703,61 @@ ack_task (void *cls, ack_msg->base_sequence_number = htonl (socket->read_sequence_number); ack_msg->receive_window_remaining = htonl (RECEIVE_BUFFER_SIZE - socket->receive_buffer_size); - + socket->ack_msg = ack_msg; /* Request MESH for sending ACK */ - GNUNET_MESH_notify_transmit_ready (socket->tunnel, - 0, /* Corking */ - 1, /* Priority */ - socket->retransmit_timeout, - &socket->other_peer, - ntohs (ack_msg->header.header.size), - &send_ack_notify, - ack_msg); + socket->ack_transmit_handle = + GNUNET_MESH_notify_transmit_ready (socket->tunnel, + 0, /* Corking */ + 1, /* Priority */ + socket->retransmit_timeout, + &socket->other_peer, + ntohs (ack_msg->header.header.size), + &send_ack_notify, + socket); +} - + +/** + * Retransmission task for shutdown messages + * + * @param cls the shutdown handle + * @param tc the Task Context + */ +static void +close_msg_retransmission_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_STREAM_ShutdownHandle *shutdown_handle = cls; + struct GNUNET_STREAM_MessageHeader *msg; + struct GNUNET_STREAM_Socket *socket; + + GNUNET_assert (NULL != shutdown_handle); + socket = shutdown_handle->socket; + + msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); + msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); + switch (shutdown_handle->operation) + { + case SHUT_RDWR: + msg->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE); + break; + case SHUT_RD: + msg->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE); + break; + case SHUT_WR: + msg->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE); + break; + default: + GNUNET_free (msg); + shutdown_handle->close_msg_retransmission_task_id = + GNUNET_SCHEDULER_NO_TASK; + return; + } + queue_message (socket, msg, NULL, NULL); + shutdown_handle->close_msg_retransmission_task_id = + GNUNET_SCHEDULER_add_delayed (socket->retransmit_timeout, + &close_msg_retransmission_task, + shutdown_handle); } @@ -572,7 +773,7 @@ ackbitmap_modify_bit (GNUNET_STREAM_AckBitmap *bitmap, unsigned int bit, int value) { - GNUNET_assert (bit < 64); + GNUNET_assert (bit < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH); if (GNUNET_YES == value) *bitmap |= (1LL << bit); else @@ -591,31 +792,14 @@ static uint8_t ackbitmap_is_bit_set (const GNUNET_STREAM_AckBitmap *bitmap, unsigned int bit) { - GNUNET_assert (bit < 64); + GNUNET_assert (bit < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH); return 0 != (*bitmap & (1LL << bit)); } - -/** - * Function called when Data Message is sent - * - * @param cls the io_handle corresponding to the Data Message - * @param socket the socket which was used - */ -static void -write_data_finish_cb (void *cls, - struct GNUNET_STREAM_Socket *socket) -{ - struct GNUNET_STREAM_IOWriteHandle *io_handle = cls; - - io_handle->sent_packets++; -} - - /** * Writes data using the given socket. The amount of data written is limited by - * the receive_window_size + * the receiver_window_size * * @param socket the socket to use */ @@ -623,43 +807,59 @@ static void write_data (struct GNUNET_STREAM_Socket *socket) { struct GNUNET_STREAM_IOWriteHandle *io_handle = socket->write_handle; - unsigned int packet; + int packet; /* Although an int, should never be negative */ int ack_packet; ack_packet = -1; /* Find the last acknowledged packet */ - for (packet=0; packet < 64; packet++) - { - if (GNUNET_YES == ackbitmap_is_bit_set (&io_handle->ack_bitmap, - packet)) - ack_packet = packet; - else if (NULL == io_handle->messages[packet]) - break; - } + for (packet=0; packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH; packet++) + { + if (GNUNET_YES == ackbitmap_is_bit_set (&io_handle->ack_bitmap, + packet)) + ack_packet = packet; + else if (NULL == io_handle->messages[packet]) + break; + } /* Resend packets which weren't ack'ed */ for (packet=0; packet < ack_packet; packet++) + { + if (GNUNET_NO == ackbitmap_is_bit_set (&io_handle->ack_bitmap, + packet)) { - if (GNUNET_NO == ackbitmap_is_bit_set (&io_handle->ack_bitmap, - packet)) - { - queue_message (socket, - &io_handle->messages[packet]->header, - NULL, - NULL); - } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Placing DATA message with sequence %u in send queue\n", + GNUNET_i2s (&socket->other_peer), + ntohl (io_handle->messages[packet]->sequence_number)); + copy_and_queue_message (socket, + &io_handle->messages[packet]->header, + NULL, + NULL); } + } packet = ack_packet + 1; /* Now send new packets if there is enough buffer space */ while ( (NULL != io_handle->messages[packet]) && - (socket->receive_window_available >= ntohs (io_handle->messages[packet]->header.header.size)) ) - { - socket->receive_window_available -= ntohs (io_handle->messages[packet]->header.header.size); - queue_message (socket, - &io_handle->messages[packet]->header, - &write_data_finish_cb, - io_handle); - packet++; - } + (socket->receiver_window_available + >= ntohs (io_handle->messages[packet]->header.header.size)) ) + { + socket->receiver_window_available -= + ntohs (io_handle->messages[packet]->header.header.size); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Placing DATA message with sequence %u in send queue\n", + GNUNET_i2s (&socket->other_peer), + ntohl (io_handle->messages[packet]->sequence_number)); + copy_and_queue_message (socket, + &io_handle->messages[packet]->header, + NULL, + NULL); + packet++; + } + if (GNUNET_SCHEDULER_NO_TASK == socket->retransmission_timeout_task_id) + socket->retransmission_timeout_task_id = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 8), + &retransmission_timeout_task, + socket); } @@ -671,7 +871,7 @@ write_data (struct GNUNET_STREAM_Socket *socket) */ static void call_read_processor (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_STREAM_Socket *socket = cls; size_t read_size; @@ -680,87 +880,95 @@ call_read_processor (void *cls, uint32_t sequence_increase; uint32_t offset_increase; - socket->read_task = GNUNET_SCHEDULER_NO_TASK; + socket->read_task_id = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; + if (NULL == socket->receive_buffer) + return; + GNUNET_assert (NULL != socket->read_handle); GNUNET_assert (NULL != socket->read_handle->proc); /* Check the bitmap for any holes */ for (packet=0; packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH; packet++) - { - if (GNUNET_NO == ackbitmap_is_bit_set (&socket->ack_bitmap, - packet)) - break; - } + { + if (GNUNET_NO == ackbitmap_is_bit_set (&socket->ack_bitmap, + packet)) + break; + } /* We only call read processor if we have the first packet */ GNUNET_assert (0 < packet); - valid_read_size = socket->receive_buffer_boundaries[packet-1] - socket->copy_offset; - GNUNET_assert (0 != valid_read_size); - /* Cancel the read_io_timeout_task */ - GNUNET_SCHEDULER_cancel (socket->read_io_timeout_task); - socket->read_io_timeout_task = GNUNET_SCHEDULER_NO_TASK; - + GNUNET_SCHEDULER_cancel (socket->read_io_timeout_task_id); + socket->read_io_timeout_task_id = GNUNET_SCHEDULER_NO_TASK; /* Call the data processor */ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Calling read processor\n", + GNUNET_i2s (&socket->other_peer)); read_size = socket->read_handle->proc (socket->read_handle->proc_cls, socket->status, socket->receive_buffer + socket->copy_offset, valid_read_size); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Read processor read %d bytes\n", + GNUNET_i2s (&socket->other_peer), read_size); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Read processor completed successfully\n", + GNUNET_i2s (&socket->other_peer)); /* Free the read handle */ GNUNET_free (socket->read_handle); socket->read_handle = NULL; - GNUNET_assert (read_size <= valid_read_size); socket->copy_offset += read_size; - /* Determine upto which packet we can remove from the buffer */ for (packet = 0; packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH; packet++) + { + if (socket->copy_offset == socket->receive_buffer_boundaries[packet]) + { packet++; break; } if (socket->copy_offset < socket->receive_buffer_boundaries[packet]) break; + } /* If no packets can be removed we can't move the buffer */ if (0 == packet) return; - sequence_increase = packet; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Sequence increase after read processor completion: %u\n", + GNUNET_i2s (&socket->other_peer), sequence_increase); /* Shift the data in the receive buffer */ memmove (socket->receive_buffer, socket->receive_buffer + socket->receive_buffer_boundaries[sequence_increase-1], - socket->receive_buffer_size - socket->receive_buffer_boundaries[sequence_increase-1]); - + socket->receive_buffer_size + - socket->receive_buffer_boundaries[sequence_increase-1]); /* Shift the bitmap */ socket->ack_bitmap = socket->ack_bitmap >> sequence_increase; - /* Set read_sequence_number */ socket->read_sequence_number += sequence_increase; - /* Set read_offset */ offset_increase = socket->receive_buffer_boundaries[sequence_increase-1]; socket->read_offset += offset_increase; - /* Fix copy_offset */ GNUNET_assert (offset_increase <= socket->copy_offset); socket->copy_offset -= offset_increase; - /* Fix relative boundaries */ for (packet=0; packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH; packet++) + { + if (packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH - sequence_increase) { - if (packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH - sequence_increase) - { - socket->receive_buffer_boundaries[packet] = - socket->receive_buffer_boundaries[packet + sequence_increase] - - offset_increase; - } - else - socket->receive_buffer_boundaries[packet] = 0; + socket->receive_buffer_boundaries[packet] = + socket->receive_buffer_boundaries[packet + sequence_increase] + - offset_increase; } + else + socket->receive_buffer_boundaries[packet] = 0; + } } @@ -772,20 +980,32 @@ call_read_processor (void *cls, */ static void read_io_timeout (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_STREAM_Socket *socket = cls; + GNUNET_STREAM_DataProcessor proc; + void *proc_cls; - socket->read_io_timeout_task = GNUNET_SCHEDULER_NO_TASK; - if (socket->read_task != GNUNET_SCHEDULER_NO_TASK) + socket->read_io_timeout_task_id = GNUNET_SCHEDULER_NO_TASK; + if (socket->read_task_id != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel (socket->read_task); - socket->read_task = GNUNET_SCHEDULER_NO_TASK; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Read task timedout - Cancelling it\n", + GNUNET_i2s (&socket->other_peer)); + GNUNET_SCHEDULER_cancel (socket->read_task_id); + socket->read_task_id = GNUNET_SCHEDULER_NO_TASK; } GNUNET_assert (NULL != socket->read_handle); - + proc = socket->read_handle->proc; + proc_cls = socket->read_handle->proc_cls; + GNUNET_free (socket->read_handle); socket->read_handle = NULL; + /* Call the read processor to signal timeout */ + proc (proc_cls, + GNUNET_STREAM_TIMEOUT, + NULL, + 0); } @@ -815,96 +1035,150 @@ handle_data (struct GNUNET_STREAM_Socket *socket, size = htons (msg->header.header.size); if (size < sizeof (struct GNUNET_STREAM_DataMessage)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } - switch (socket->state) - { - case STATE_ESTABLISHED: - case STATE_TRANSMIT_CLOSED: - case STATE_TRANSMIT_CLOSE_WAIT: + if (0 != memcmp (sender, + &socket->other_peer, + sizeof (struct GNUNET_PeerIdentity))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received DATA from non-confirming peer\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_YES; + } - /* check if the message's sequence number is in the range we are - expecting */ - relative_sequence_number = - ntohl (msg->sequence_number) - socket->read_sequence_number; - if ( relative_sequence_number > 64) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Ignoring received message with sequence number %d", - ntohl (msg->sequence_number)); - return GNUNET_YES; - } - - /* Check if we have to allocate the buffer */ - size -= sizeof (struct GNUNET_STREAM_DataMessage); - relative_offset = ntohl (msg->offset) - socket->read_offset; - bytes_needed = relative_offset + size; - - if (bytes_needed > socket->receive_buffer_size) - { - if (bytes_needed <= RECEIVE_BUFFER_SIZE) - { - socket->receive_buffer = GNUNET_realloc (socket->receive_buffer, - bytes_needed); - socket->receive_buffer_size = bytes_needed; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Cannot accommodate packet %d as buffer is full\n", - ntohl (msg->sequence_number)); - return GNUNET_YES; - } - } - - /* Copy Data to buffer */ - payload = &msg[1]; - GNUNET_assert (relative_offset + size <= socket->receive_buffer_size); - memcpy (socket->receive_buffer + relative_offset, - payload, - size); - socket->receive_buffer_boundaries[relative_sequence_number] = - relative_offset + size; + switch (socket->state) + { + case STATE_ESTABLISHED: + case STATE_TRANSMIT_CLOSED: + case STATE_TRANSMIT_CLOSE_WAIT: - /* Modify the ACK bitmap */ - ackbitmap_modify_bit (&socket->ack_bitmap, - relative_sequence_number, - GNUNET_YES); - + /* check if the message's sequence number is in the range we are + expecting */ + relative_sequence_number = + ntohl (msg->sequence_number) - socket->read_sequence_number; + if ( relative_sequence_number > GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Ignoring received message with sequence number %u\n", + GNUNET_i2s (&socket->other_peer), + ntohl (msg->sequence_number)); /* Start ACK sending task if one is not already present */ - if (0 == socket->ack_task_id) - { - socket->ack_task_id = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_ntoh - (msg->ack_deadline), - &ack_task, - socket); - } - - if ((NULL != socket->read_handle) /* A read handle is waiting */ - /* There is no current read task */ - && (GNUNET_SCHEDULER_NO_TASK == socket->read_task) - /* We have the first packet */ - && (GNUNET_YES == ackbitmap_is_bit_set(&socket->ack_bitmap, - 0))) - { - socket->read_task = - GNUNET_SCHEDULER_add_now (&call_read_processor, - socket); - } + if (GNUNET_SCHEDULER_NO_TASK == socket->ack_task_id) + { + socket->ack_task_id = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_ntoh + (msg->ack_deadline), + &ack_task, + socket); + } + return GNUNET_YES; + } - break; + /* Check if we have already seen this message */ + if (GNUNET_YES == ackbitmap_is_bit_set (&socket->ack_bitmap, + relative_sequence_number)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Ignoring already received message with sequence number %u\n", + GNUNET_i2s (&socket->other_peer), + ntohl (msg->sequence_number)); + /* Start ACK sending task if one is not already present */ + if (GNUNET_SCHEDULER_NO_TASK == socket->ack_task_id) + { + socket->ack_task_id = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_ntoh + (msg->ack_deadline), + &ack_task, + socket); + } + return GNUNET_YES; + } - default: - /* FIXME: call statistics */ - break; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Receiving DATA with sequence number: %u and size: %d from %s\n", + GNUNET_i2s (&socket->other_peer), + ntohl (msg->sequence_number), + ntohs (msg->header.header.size), + GNUNET_i2s (&socket->other_peer)); + + /* Check if we have to allocate the buffer */ + size -= sizeof (struct GNUNET_STREAM_DataMessage); + relative_offset = ntohl (msg->offset) - socket->read_offset; + bytes_needed = relative_offset + size; + if (bytes_needed > socket->receive_buffer_size) + { + if (bytes_needed <= RECEIVE_BUFFER_SIZE) + { + socket->receive_buffer = GNUNET_realloc (socket->receive_buffer, + bytes_needed); + socket->receive_buffer_size = bytes_needed; + } + else + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Cannot accommodate packet %d as buffer is full\n", + GNUNET_i2s (&socket->other_peer), + ntohl (msg->sequence_number)); + return GNUNET_YES; + } + } + + /* Copy Data to buffer */ + payload = &msg[1]; + GNUNET_assert (relative_offset + size <= socket->receive_buffer_size); + memcpy (socket->receive_buffer + relative_offset, + payload, + size); + socket->receive_buffer_boundaries[relative_sequence_number] = + relative_offset + size; + + /* Modify the ACK bitmap */ + ackbitmap_modify_bit (&socket->ack_bitmap, + relative_sequence_number, + GNUNET_YES); + + /* Start ACK sending task if one is not already present */ + if (GNUNET_SCHEDULER_NO_TASK == socket->ack_task_id) + { + socket->ack_task_id = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_ntoh + (msg->ack_deadline), + &ack_task, + socket); + } + + if ((NULL != socket->read_handle) /* A read handle is waiting */ + /* There is no current read task */ + && (GNUNET_SCHEDULER_NO_TASK == socket->read_task_id) + /* We have the first packet */ + && (GNUNET_YES == ackbitmap_is_bit_set(&socket->ack_bitmap, + 0))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Scheduling read processor\n", + GNUNET_i2s (&socket->other_peer)); + + socket->read_task_id = + GNUNET_SCHEDULER_add_now (&call_read_processor, + socket); } + + break; + + default: + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received data message when it cannot be handled\n", + GNUNET_i2s (&socket->other_peer)); + break; + } return GNUNET_YES; } + /** * Client's message Handler for GNUNET_MESSAGE_TYPE_STREAM_DATA * @@ -919,11 +1193,11 @@ handle_data (struct GNUNET_STREAM_Socket *socket, */ static int client_handle_data (void *cls, - struct GNUNET_MESH_Tunnel *tunnel, - void **tunnel_ctx, - const struct GNUNET_PeerIdentity *sender, - const struct GNUNET_MessageHeader *message, - const struct GNUNET_ATS_Information*atsi) + struct GNUNET_MESH_Tunnel *tunnel, + void **tunnel_ctx, + const struct GNUNET_PeerIdentity *sender, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information*atsi) { struct GNUNET_STREAM_Socket *socket = cls; @@ -945,10 +1219,31 @@ static void set_state_established (void *cls, struct GNUNET_STREAM_Socket *socket) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attaining ESTABLISHED state\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Attaining ESTABLISHED state\n", + GNUNET_i2s (&socket->other_peer)); socket->write_offset = 0; socket->read_offset = 0; socket->state = STATE_ESTABLISHED; + /* FIXME: What if listen_cb is NULL */ + if (NULL != socket->lsocket) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Calling listen callback\n", + GNUNET_i2s (&socket->other_peer)); + if (GNUNET_SYSERR == + socket->lsocket->listen_cb (socket->lsocket->listen_cb_cls, + socket, + &socket->other_peer)) + { + socket->state = STATE_CLOSED; + /* FIXME: We should close in a decent way */ + GNUNET_MESH_tunnel_destroy (socket->tunnel); /* Destroy the tunnel */ + GNUNET_free (socket); + } + } + else if (socket->open_cb) + socket->open_cb (socket->open_cls, socket); } @@ -963,11 +1258,114 @@ set_state_hello_wait (void *cls, struct GNUNET_STREAM_Socket *socket) { GNUNET_assert (STATE_INIT == socket->state); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attaining HELLO_WAIT state\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Attaining HELLO_WAIT state\n", + GNUNET_i2s (&socket->other_peer)); socket->state = STATE_HELLO_WAIT; } +/** + * Callback to set state to CLOSE_WAIT + * + * @param cls the closure from queue_message + * @param socket the socket requiring state change + */ +static void +set_state_close_wait (void *cls, + struct GNUNET_STREAM_Socket *socket) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Attaing CLOSE_WAIT state\n", + GNUNET_i2s (&socket->other_peer)); + socket->state = STATE_CLOSE_WAIT; + GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */ + socket->receive_buffer = NULL; + socket->receive_buffer_size = 0; +} + + +/** + * Callback to set state to RECEIVE_CLOSE_WAIT + * + * @param cls the closure from queue_message + * @param socket the socket requiring state change + */ +static void +set_state_receive_close_wait (void *cls, + struct GNUNET_STREAM_Socket *socket) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Attaing RECEIVE_CLOSE_WAIT state\n", + GNUNET_i2s (&socket->other_peer)); + socket->state = STATE_RECEIVE_CLOSE_WAIT; + GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */ + socket->receive_buffer = NULL; + socket->receive_buffer_size = 0; +} + + +/** + * Callback to set state to TRANSMIT_CLOSE_WAIT + * + * @param cls the closure from queue_message + * @param socket the socket requiring state change + */ +static void +set_state_transmit_close_wait (void *cls, + struct GNUNET_STREAM_Socket *socket) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Attaing TRANSMIT_CLOSE_WAIT state\n", + GNUNET_i2s (&socket->other_peer)); + socket->state = STATE_TRANSMIT_CLOSE_WAIT; +} + + +/** + * Callback to set state to CLOSED + * + * @param cls the closure from queue_message + * @param socket the socket requiring state change + */ +static void +set_state_closed (void *cls, + struct GNUNET_STREAM_Socket *socket) +{ + socket->state = STATE_CLOSED; +} + +/** + * Returns a new HelloAckMessage. Also sets the write sequence number for the + * socket + * + * @param socket the socket for which this HelloAckMessage has to be generated + * @return the HelloAckMessage + */ +static struct GNUNET_STREAM_HelloAckMessage * +generate_hello_ack_msg (struct GNUNET_STREAM_Socket *socket) +{ + struct GNUNET_STREAM_HelloAckMessage *msg; + + /* Get the random sequence number */ + socket->write_sequence_number = + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Generated write sequence number %u\n", + GNUNET_i2s (&socket->other_peer), + (unsigned int) socket->write_sequence_number); + + msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_HelloAckMessage)); + msg->header.header.size = + htons (sizeof (struct GNUNET_STREAM_HelloAckMessage)); + msg->header.header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK); + msg->sequence_number = htonl (socket->write_sequence_number); + msg->receiver_window_size = htonl (RECEIVE_BUFFER_SIZE); + + return msg; +} + + /** * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK * @@ -992,37 +1390,48 @@ client_handle_hello_ack (void *cls, const struct GNUNET_STREAM_HelloAckMessage *ack_msg; struct GNUNET_STREAM_HelloAckMessage *reply; + if (0 != memcmp (sender, + &socket->other_peer, + sizeof (struct GNUNET_PeerIdentity))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received HELLO_ACK from non-confirming peer\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_YES; + } ack_msg = (const struct GNUNET_STREAM_HelloAckMessage *) message; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received HELLO_ACK from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + GNUNET_assert (socket->tunnel == tunnel); switch (socket->state) { case STATE_HELLO_WAIT: - socket->read_sequence_number = ntohl (ack_msg->sequence_number); - socket->receive_window_available = ntohl (ack_msg->receive_window_size); - /* Get the random sequence number */ - socket->write_sequence_number = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); - reply = - GNUNET_malloc (sizeof (struct GNUNET_STREAM_HelloAckMessage)); - reply->header.header.size = - htons (sizeof (struct GNUNET_STREAM_MessageHeader)); - reply->header.header.type = - htons (GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK); - reply->sequence_number = htonl (socket->write_sequence_number); - reply->receive_window_size = htonl (RECEIVE_BUFFER_SIZE); - queue_message (socket, - &reply->header, - &set_state_established, - NULL); - return GNUNET_OK; + socket->read_sequence_number = ntohl (ack_msg->sequence_number); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Read sequence number %u\n", + GNUNET_i2s (&socket->other_peer), + (unsigned int) socket->read_sequence_number); + socket->receiver_window_available = ntohl (ack_msg->receiver_window_size); + reply = generate_hello_ack_msg (socket); + queue_message (socket, + &reply->header, + &set_state_established, + NULL); + return GNUNET_OK; case STATE_ESTABLISHED: case STATE_RECEIVE_CLOSE_WAIT: // call statistics (# ACKs ignored++) return GNUNET_OK; case STATE_INIT: default: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Server sent HELLO_ACK when in state %d\n", socket->state); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Server %s sent HELLO_ACK when in state %d\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer), + socket->state); socket->state = STATE_CLOSED; // introduce STATE_ERROR? return GNUNET_SYSERR; } @@ -1050,7 +1459,7 @@ client_handle_reset (void *cls, const struct GNUNET_MessageHeader *message, const struct GNUNET_ATS_Information*atsi) { - struct GNUNET_STREAM_Socket *socket = cls; + // struct GNUNET_STREAM_Socket *socket = cls; return GNUNET_OK; } @@ -1077,22 +1486,22 @@ handle_transmit_close (struct GNUNET_STREAM_Socket *socket, struct GNUNET_STREAM_MessageHeader *reply; switch (socket->state) - { - case STATE_ESTABLISHED: - socket->state = STATE_RECEIVE_CLOSED; + { + case STATE_ESTABLISHED: + socket->state = STATE_RECEIVE_CLOSED; - /* Send TRANSMIT_CLOSE_ACK */ - reply = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); - reply->header.type = - htons (GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK); - reply->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); - queue_message (socket, reply, NULL, NULL); - break; + /* Send TRANSMIT_CLOSE_ACK */ + reply = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); + reply->header.type = + htons (GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK); + reply->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); + queue_message (socket, reply, NULL, NULL); + break; - default: - /* FIXME: Call statistics? */ - break; - } + default: + /* FIXME: Call statistics? */ + break; + } return GNUNET_YES; } @@ -1127,6 +1536,141 @@ client_handle_transmit_close (void *cls, } +/** + * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_*_CLOSE_ACK messages + * + * @param socket the socket + * @param tunnel connection to the other end + * @param sender who sent the message + * @param message the actual message + * @param atsi performance data for the connection + * @param operation the close operation which is being ACK'ed + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handle_generic_close_ack (struct GNUNET_STREAM_Socket *socket, + struct GNUNET_MESH_Tunnel *tunnel, + const struct GNUNET_PeerIdentity *sender, + const struct GNUNET_STREAM_MessageHeader *message, + const struct GNUNET_ATS_Information *atsi, + int operation) +{ + struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; + + shutdown_handle = socket->shutdown_handle; + if (NULL == shutdown_handle) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received CLOSE_ACK when shutdown handle is NULL\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + } + + switch (operation) + { + case SHUT_RDWR: + switch (socket->state) + { + case STATE_CLOSE_WAIT: + if (SHUT_RDWR != shutdown_handle->operation) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received CLOSE_ACK when shutdown handle is not for " + "SHUT_RDWR\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + } + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received CLOSE_ACK from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + socket->state = STATE_CLOSED; + break; + default: + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received CLOSE_ACK when in it not expected\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + } + break; + + case SHUT_RD: + switch (socket->state) + { + case STATE_RECEIVE_CLOSE_WAIT: + if (SHUT_RD != shutdown_handle->operation) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received RECEIVE_CLOSE_ACK when shutdown handle " + "is not for SHUT_RD\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + } + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received RECEIVE_CLOSE_ACK from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + socket->state = STATE_RECEIVE_CLOSED; + break; + default: + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received RECEIVE_CLOSE_ACK when in it not expected\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + } + + break; + case SHUT_WR: + switch (socket->state) + { + case STATE_TRANSMIT_CLOSE_WAIT: + if (SHUT_WR != shutdown_handle->operation) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received TRANSMIT_CLOSE_ACK when shutdown handle " + "is not for SHUT_WR\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + } + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received TRANSMIT_CLOSE_ACK from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + socket->state = STATE_TRANSMIT_CLOSED; + break; + default: + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received TRANSMIT_CLOSE_ACK when in it not expected\n", + GNUNET_i2s (&socket->other_peer)); + + return GNUNET_OK; + } + break; + default: + GNUNET_assert (0); + } + + if (NULL != shutdown_handle->completion_cb) /* Shutdown completion */ + shutdown_handle->completion_cb(shutdown_handle->completion_cls, + operation); + GNUNET_free (shutdown_handle); /* Free shutdown handle */ + socket->shutdown_handle = NULL; + if (GNUNET_SCHEDULER_NO_TASK + != shutdown_handle->close_msg_retransmission_task_id) + { + GNUNET_SCHEDULER_cancel + (shutdown_handle->close_msg_retransmission_task_id); + shutdown_handle->close_msg_retransmission_task_id = + GNUNET_SCHEDULER_NO_TASK; + } + return GNUNET_OK; +} + + /** * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK * @@ -1149,6 +1693,67 @@ client_handle_transmit_close_ack (void *cls, { struct GNUNET_STREAM_Socket *socket = cls; + return handle_generic_close_ack (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) + message, + atsi, + SHUT_WR); +} + + +/** + * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE + * + * @param socket the socket + * @param tunnel connection to the other end + * @param sender who sent the message + * @param message the actual message + * @param atsi performance data for the connection + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handle_receive_close (struct GNUNET_STREAM_Socket *socket, + struct GNUNET_MESH_Tunnel *tunnel, + const struct GNUNET_PeerIdentity *sender, + const struct GNUNET_STREAM_MessageHeader *message, + const struct GNUNET_ATS_Information *atsi) +{ + struct GNUNET_STREAM_MessageHeader *receive_close_ack; + + switch (socket->state) + { + case STATE_INIT: + case STATE_LISTEN: + case STATE_HELLO_WAIT: + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Ignoring RECEIVE_CLOSE as it cannot be handled now\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + default: + break; + } + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received RECEIVE_CLOSE from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + receive_close_ack = + GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); + receive_close_ack->header.size = + htons (sizeof (struct GNUNET_STREAM_MessageHeader)); + receive_close_ack->header.type = + htons (GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK); + queue_message (socket, + receive_close_ack, + &set_state_closed, + NULL); + + /* FIXME: Handle the case where write handle is present; the write operation + should be deemed as finised and the write continuation callback + has to be called with the stream status GNUNET_STREAM_SHUTDOWN */ return GNUNET_OK; } @@ -1175,7 +1780,12 @@ client_handle_receive_close (void *cls, { struct GNUNET_STREAM_Socket *socket = cls; - return GNUNET_OK; + return + handle_receive_close (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) message, + atsi); } @@ -1201,6 +1811,66 @@ client_handle_receive_close_ack (void *cls, { struct GNUNET_STREAM_Socket *socket = cls; + return handle_generic_close_ack (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) + message, + atsi, + SHUT_RD); +} + + +/** + * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE + * + * @param socket the socket + * @param tunnel connection to the other end + * @param sender who sent the message + * @param message the actual message + * @param atsi performance data for the connection + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handle_close (struct GNUNET_STREAM_Socket *socket, + struct GNUNET_MESH_Tunnel *tunnel, + const struct GNUNET_PeerIdentity *sender, + const struct GNUNET_STREAM_MessageHeader *message, + const struct GNUNET_ATS_Information*atsi) +{ + struct GNUNET_STREAM_MessageHeader *close_ack; + + switch (socket->state) + { + case STATE_INIT: + case STATE_LISTEN: + case STATE_HELLO_WAIT: + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Ignoring RECEIVE_CLOSE as it cannot be handled now\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + default: + break; + } + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received CLOSE from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + close_ack = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); + close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); + close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK); + queue_message (socket, + close_ack, + &set_state_closed, + NULL); + if (socket->state == STATE_CLOSED) + return GNUNET_OK; + + GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */ + socket->receive_buffer = NULL; + socket->receive_buffer_size = 0; return GNUNET_OK; } @@ -1227,7 +1897,11 @@ client_handle_close (void *cls, { struct GNUNET_STREAM_Socket *socket = cls; - return GNUNET_OK; + return handle_close (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) message, + atsi); } @@ -1249,11 +1923,17 @@ client_handle_close_ack (void *cls, void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *message, - const struct GNUNET_ATS_Information*atsi) + const struct GNUNET_ATS_Information *atsi) { struct GNUNET_STREAM_Socket *socket = cls; - return GNUNET_OK; + return handle_generic_close_ack (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) + message, + atsi, + SHUT_RDWR); } /*****************************/ @@ -1313,31 +1993,39 @@ server_handle_hello (void *cls, struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; struct GNUNET_STREAM_HelloAckMessage *reply; + if (0 != memcmp (sender, + &socket->other_peer, + sizeof (struct GNUNET_PeerIdentity))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received HELLO from non-confirming peer\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_YES; + } + + GNUNET_assert (GNUNET_MESSAGE_TYPE_STREAM_HELLO == + ntohs (message->type)); GNUNET_assert (socket->tunnel == tunnel); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received HELLO from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + if (STATE_INIT == socket->state) - { - /* Get the random sequence number */ - socket->write_sequence_number = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); - reply = - GNUNET_malloc (sizeof (struct GNUNET_STREAM_HelloAckMessage)); - reply->header.header.size = - htons (sizeof (struct GNUNET_STREAM_MessageHeader)); - reply->header.header.type = - htons (GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK); - reply->sequence_number = htonl (socket->write_sequence_number); - queue_message (socket, - &reply->header, - &set_state_hello_wait, - NULL); - } + { + reply = generate_hello_ack_msg (socket); + queue_message (socket, + &reply->header, + &set_state_hello_wait, + NULL); + } else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client sent HELLO when in state %d\n", socket->state); - /* FIXME: Send RESET? */ + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Client sent HELLO when in state %d\n", socket->state); + /* FIXME: Send RESET? */ - } + } return GNUNET_OK; } @@ -1365,23 +2053,33 @@ server_handle_hello_ack (void *cls, struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; const struct GNUNET_STREAM_HelloAckMessage *ack_message; - ack_message = (struct GNUNET_STREAM_HelloAckMessage *) message; + GNUNET_assert (GNUNET_MESSAGE_TYPE_STREAM_HELLO_ACK == + ntohs (message->type)); GNUNET_assert (socket->tunnel == tunnel); + ack_message = (struct GNUNET_STREAM_HelloAckMessage *) message; if (STATE_HELLO_WAIT == socket->state) - { - socket->read_sequence_number = ntohl (ack_message->sequence_number); - socket->receive_window_available = - ntohl (ack_message->receive_window_size); - /* Attain ESTABLISHED state */ - set_state_established (NULL, socket); - } + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received HELLO_ACK from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + socket->read_sequence_number = ntohl (ack_message->sequence_number); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Read sequence number %u\n", + GNUNET_i2s (&socket->other_peer), + (unsigned int) socket->read_sequence_number); + socket->receiver_window_available = + ntohl (ack_message->receiver_window_size); + /* Attain ESTABLISHED state */ + set_state_established (NULL, socket); + } else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client sent HELLO_ACK when in state %d\n", socket->state); - /* FIXME: Send RESET? */ + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Client sent HELLO_ACK when in state %d\n", socket->state); + /* FIXME: Send RESET? */ - } + } return GNUNET_OK; } @@ -1406,7 +2104,7 @@ server_handle_reset (void *cls, const struct GNUNET_MessageHeader *message, const struct GNUNET_ATS_Information*atsi) { - struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; + // struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; return GNUNET_OK; } @@ -1464,7 +2162,13 @@ server_handle_transmit_close_ack (void *cls, { struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; - return GNUNET_OK; + return handle_generic_close_ack (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) + message, + atsi, + SHUT_WR); } @@ -1490,7 +2194,12 @@ server_handle_receive_close (void *cls, { struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; - return GNUNET_OK; + return + handle_receive_close (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) message, + atsi); } @@ -1516,14 +2225,21 @@ server_handle_receive_close_ack (void *cls, { struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; - return GNUNET_OK; + return handle_generic_close_ack (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) + message, + atsi, + SHUT_RD); } /** * Server's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE * - * @param cls the closure + * @param cls the listen socket (from GNUNET_MESH_connect in + * GNUNET_STREAM_listen) * @param tunnel connection to the other end * @param tunnel_ctx the socket * @param sender who sent the message @@ -1541,8 +2257,12 @@ server_handle_close (void *cls, const struct GNUNET_ATS_Information*atsi) { struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; - - return GNUNET_OK; + + return handle_close (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) message, + atsi); } @@ -1568,12 +2288,18 @@ server_handle_close_ack (void *cls, { struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; - return GNUNET_OK; + return handle_generic_close_ack (socket, + tunnel, + sender, + (const struct GNUNET_STREAM_MessageHeader *) + message, + atsi, + SHUT_RDWR); } /** - * Message Handler for mesh + * Handler for DATA_ACK messages * * @param socket the socket through which the ack was received * @param tunnel connection to the other end @@ -1590,30 +2316,132 @@ handle_ack (struct GNUNET_STREAM_Socket *socket, const struct GNUNET_STREAM_AckMessage *ack, const struct GNUNET_ATS_Information*atsi) { + unsigned int packet; + int need_retransmission; + + + if (0 != memcmp (sender, + &socket->other_peer, + sizeof (struct GNUNET_PeerIdentity))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received ACK from non-confirming peer\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_YES; + } + switch (socket->state) + { + case (STATE_ESTABLISHED): + case (STATE_RECEIVE_CLOSED): + case (STATE_RECEIVE_CLOSE_WAIT): + if (NULL == socket->write_handle) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received DATA_ACK when write_handle is NULL\n", + GNUNET_i2s (&socket->other_peer)); + return GNUNET_OK; + } + /* FIXME: increment in the base sequence number is breaking current flow + */ + if (!((socket->write_sequence_number + - ntohl (ack->base_sequence_number)) < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received DATA_ACK with unexpected base sequence number\n", + GNUNET_i2s (&socket->other_peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Current write sequence: %u; Ack's base sequence: %u\n", + GNUNET_i2s (&socket->other_peer), + socket->write_sequence_number, + ntohl (ack->base_sequence_number)); + return GNUNET_OK; + } + /* FIXME: include the case when write_handle is cancelled - ignore the + acks */ + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Received DATA_ACK from %s\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + + /* Cancel the retransmission task */ + if (GNUNET_SCHEDULER_NO_TASK != socket->retransmission_timeout_task_id) + { + GNUNET_SCHEDULER_cancel (socket->retransmission_timeout_task_id); + socket->retransmission_timeout_task_id = + GNUNET_SCHEDULER_NO_TASK; + } + + for (packet=0; packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH; packet++) + { + if (NULL == socket->write_handle->messages[packet]) break; + if (ntohl (ack->base_sequence_number) + >= ntohl (socket->write_handle->messages[packet]->sequence_number)) + ackbitmap_modify_bit (&socket->write_handle->ack_bitmap, + packet, + GNUNET_YES); + else + if (GNUNET_YES == + ackbitmap_is_bit_set (&socket->write_handle->ack_bitmap, + ntohl (socket->write_handle->messages[packet]->sequence_number) + - ntohl (ack->base_sequence_number))) + ackbitmap_modify_bit (&socket->write_handle->ack_bitmap, + packet, + GNUNET_YES); + } + + /* Update the receive window remaining + FIXME : Should update with the value from a data ack with greater + sequence number */ + socket->receiver_window_available = + ntohl (ack->receive_window_remaining); + + /* Check if we have received all acknowledgements */ + need_retransmission = GNUNET_NO; + for (packet=0; packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH; packet++) + { + if (NULL == socket->write_handle->messages[packet]) break; + if (GNUNET_YES != ackbitmap_is_bit_set + (&socket->write_handle->ack_bitmap,packet)) + { + need_retransmission = GNUNET_YES; + break; + } + } + if (GNUNET_YES == need_retransmission) { - case (STATE_ESTABLISHED): - if (NULL == socket->write_handle) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received DATA ACK when write_handle is NULL\n"); - return GNUNET_OK; - } - - socket->write_handle->ack_bitmap = GNUNET_ntohll (ack->bitmap); - socket->receive_window_available = - ntohl (ack->receive_window_remaining); write_data (socket); - break; - default: - break; } + else /* We have to call the write continuation callback now */ + { + /* Free the packets */ + for (packet=0; packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH; packet++) + { + GNUNET_free_non_null (socket->write_handle->messages[packet]); + } + if (NULL != socket->write_handle->write_cont) + socket->write_handle->write_cont + (socket->write_handle->write_cont_cls, + socket->status, + socket->write_handle->size); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Write completion callback completed\n", + GNUNET_i2s (&socket->other_peer)); + /* We are done with the write handle - Freeing it */ + GNUNET_free (socket->write_handle); + socket->write_handle = NULL; + } + break; + default: + break; + } return GNUNET_OK; } /** - * Message Handler for mesh + * Handler for DATA_ACK messages * * @param cls the 'struct GNUNET_STREAM_Socket' * @param tunnel connection to the other end @@ -1640,7 +2468,7 @@ client_handle_ack (void *cls, /** - * Message Handler for mesh + * Handler for DATA_ACK messages * * @param cls the server's listen socket * @param tunnel connection to the other end @@ -1738,19 +2566,21 @@ mesh_peer_connect_callback (void *cls, { struct GNUNET_STREAM_Socket *socket = cls; struct GNUNET_STREAM_MessageHeader *message; - - if (0 != memcmp (&socket->other_peer, - peer, + + if (0 != memcmp (peer, + &socket->other_peer, sizeof (struct GNUNET_PeerIdentity))) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "A peer (%s) which is not our target has connected to our tunnel", - GNUNET_i2s (peer)); - return; - } + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: A peer which is not our target has connected to our tunnel\n", + GNUNET_i2s(peer)); + return; + } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Target peer %s connected\n", GNUNET_i2s (peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Target peer %s connected\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); /* Set state to INIT */ socket->state = STATE_INIT; @@ -1766,14 +2596,10 @@ mesh_peer_connect_callback (void *cls, /* Call open callback */ if (NULL == socket->open_cb) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "STREAM_open callback is NULL\n"); - } - else - { - socket->open_cb (socket->open_cls, socket); - } + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "STREAM_open callback is NULL\n"); + } } @@ -1787,7 +2613,112 @@ static void mesh_peer_disconnect_callback (void *cls, const struct GNUNET_PeerIdentity *peer) { + struct GNUNET_STREAM_Socket *socket=cls; + + /* If the state is SHUTDOWN its ok; else set the state of the socket to SYSERR */ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Other peer %s disconnected \n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); +} + + +/** + * Method called whenever a peer creates a tunnel to us + * + * @param cls closure + * @param tunnel new handle to the tunnel + * @param initiator peer that started the tunnel + * @param atsi performance information for the tunnel + * @return initial tunnel context for the tunnel + * (can be NULL -- that's not an error) + */ +static void * +new_tunnel_notify (void *cls, + struct GNUNET_MESH_Tunnel *tunnel, + const struct GNUNET_PeerIdentity *initiator, + const struct GNUNET_ATS_Information *atsi) +{ + struct GNUNET_STREAM_ListenSocket *lsocket = cls; + struct GNUNET_STREAM_Socket *socket; + + /* FIXME: If a tunnel is already created, we should not accept new tunnels + from the same peer again until the socket is closed */ + + socket = GNUNET_malloc (sizeof (struct GNUNET_STREAM_Socket)); + socket->other_peer = *initiator; + socket->tunnel = tunnel; + socket->session_id = 0; /* FIXME */ + socket->state = STATE_INIT; + socket->lsocket = lsocket; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Peer %s initiated tunnel to us\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + + /* FIXME: Copy MESH handle from lsocket to socket */ + + return socket; +} + + +/** + * Function called whenever an inbound tunnel is destroyed. Should clean up + * any associated state. This function is NOT called if the client has + * explicitly asked for the tunnel to be destroyed using + * GNUNET_MESH_tunnel_destroy. It must NOT call GNUNET_MESH_tunnel_destroy on + * the tunnel. + * + * @param cls closure (set from GNUNET_MESH_connect) + * @param tunnel connection to the other end (henceforth invalid) + * @param tunnel_ctx place where local state associated + * with the tunnel is stored + */ +static void +tunnel_cleaner (void *cls, + const struct GNUNET_MESH_Tunnel *tunnel, + void *tunnel_ctx) +{ + struct GNUNET_STREAM_Socket *socket = tunnel_ctx; + + if (tunnel != socket->tunnel) + return; + + GNUNET_break_op(0); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: Peer %s has terminated connection abruptly\n", + GNUNET_i2s (&socket->other_peer), + GNUNET_i2s (&socket->other_peer)); + socket->status = GNUNET_STREAM_SHUTDOWN; + + /* Clear Transmit handles */ + if (NULL != socket->transmit_handle) + { + GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle); + socket->transmit_handle = NULL; + } + if (NULL != socket->ack_transmit_handle) + { + GNUNET_MESH_notify_transmit_ready_cancel (socket->ack_transmit_handle); + GNUNET_free (socket->ack_msg); + socket->ack_msg = NULL; + socket->ack_transmit_handle = NULL; + } + /* Stop Tasks using socket->tunnel */ + if (GNUNET_SCHEDULER_NO_TASK != socket->ack_task_id) + { + GNUNET_SCHEDULER_cancel (socket->ack_task_id); + socket->ack_task_id = GNUNET_SCHEDULER_NO_TASK; + } + if (GNUNET_SCHEDULER_NO_TASK != socket->retransmission_timeout_task_id) + { + GNUNET_SCHEDULER_cancel (socket->retransmission_timeout_task_id); + socket->retransmission_timeout_task_id = GNUNET_SCHEDULER_NO_TASK; + } + /* FIXME: Cancel all other tasks using socket->tunnel */ + socket->tunnel = NULL; } @@ -1819,54 +2750,166 @@ GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg, { struct GNUNET_STREAM_Socket *socket; enum GNUNET_STREAM_Option option; + GNUNET_MESH_ApplicationType ports[] = {app_port, 0}; va_list vargs; /* Variable arguments */ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s\n", __func__); socket = GNUNET_malloc (sizeof (struct GNUNET_STREAM_Socket)); socket->other_peer = *target; socket->open_cb = open_cb; socket->open_cls = open_cb_cls; - /* Set defaults */ socket->retransmit_timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, default_timeout); - va_start (vargs, open_cb_cls); /* Parse variable args */ do { option = va_arg (vargs, enum GNUNET_STREAM_Option); switch (option) - { - case GNUNET_STREAM_OPTION_INITIAL_RETRANSMIT_TIMEOUT: - /* Expect struct GNUNET_TIME_Relative */ - socket->retransmit_timeout = va_arg (vargs, - struct GNUNET_TIME_Relative); - break; - case GNUNET_STREAM_OPTION_END: - break; - } + { + case GNUNET_STREAM_OPTION_INITIAL_RETRANSMIT_TIMEOUT: + /* Expect struct GNUNET_TIME_Relative */ + socket->retransmit_timeout = va_arg (vargs, + struct GNUNET_TIME_Relative); + break; + case GNUNET_STREAM_OPTION_END: + break; + } } while (GNUNET_STREAM_OPTION_END != option); va_end (vargs); /* End of variable args parsing */ - socket->mesh = GNUNET_MESH_connect (cfg, /* the configuration handle */ - 1, /* QUEUE size as parameter? */ + 10, /* QUEUE size as parameter? */ socket, /* cls */ NULL, /* No inbound tunnel handler */ - NULL, /* No inbound tunnel cleaner */ + NULL, /* No in-tunnel cleaner */ client_message_handlers, - NULL); /* We don't get inbound tunnels */ - // FIXME: if (NULL == socket->mesh) ... + ports); /* We don't get inbound tunnels */ + if (NULL == socket->mesh) /* Fail if we cannot connect to mesh */ + { + GNUNET_free (socket); + return NULL; + } /* Now create the mesh tunnel to target */ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Creating MESH Tunnel\n"); socket->tunnel = GNUNET_MESH_tunnel_create (socket->mesh, NULL, /* Tunnel context */ &mesh_peer_connect_callback, &mesh_peer_disconnect_callback, socket); - // FIXME: if (NULL == socket->tunnel) ... - + GNUNET_assert (NULL != socket->tunnel); + GNUNET_MESH_peer_request_connect_add (socket->tunnel, + &socket->other_peer); + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s() END\n", __func__); return socket; } +/** + * Shutdown the stream for reading or writing (similar to man 2 shutdown). + * + * @param socket the stream socket + * @param operation SHUT_RD, SHUT_WR or SHUT_RDWR + * @param completion_cb the callback that will be called upon successful + * shutdown of given operation + * @param completion_cls the closure for the completion callback + * @return the shutdown handle + */ +struct GNUNET_STREAM_ShutdownHandle * +GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket, + int operation, + GNUNET_STREAM_ShutdownCompletion completion_cb, + void *completion_cls) +{ + struct GNUNET_STREAM_ShutdownHandle *handle; + struct GNUNET_STREAM_MessageHeader *msg; + + GNUNET_assert (NULL == socket->shutdown_handle); + + handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ShutdownHandle)); + handle->socket = socket; + handle->completion_cb = completion_cb; + handle->completion_cls = completion_cls; + socket->shutdown_handle = handle; + + msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); + msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); + switch (operation) + { + case SHUT_RD: + handle->operation = SHUT_RD; + if (NULL != socket->read_handle) + LOG (GNUNET_ERROR_TYPE_WARNING, + "Existing read handle should be cancelled before shutting" + " down reading\n"); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE); + queue_message (socket, + msg, + &set_state_receive_close_wait, + NULL); + break; + case SHUT_WR: + handle->operation = SHUT_WR; + if (NULL != socket->write_handle) + LOG (GNUNET_ERROR_TYPE_WARNING, + "Existing write handle should be cancelled before shutting" + " down writing\n"); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE); + queue_message (socket, + msg, + &set_state_transmit_close_wait, + NULL); + break; + case SHUT_RDWR: + handle->operation = SHUT_RDWR; + if (NULL != socket->write_handle) + LOG (GNUNET_ERROR_TYPE_WARNING, + "Existing write handle should be cancelled before shutting" + " down writing\n"); + if (NULL != socket->read_handle) + LOG (GNUNET_ERROR_TYPE_WARNING, + "Existing read handle should be cancelled before shutting" + " down reading\n"); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE); + queue_message (socket, + msg, + &set_state_close_wait, + NULL); + break; + default: + LOG (GNUNET_ERROR_TYPE_WARNING, + "GNUNET_STREAM_shutdown called with invalid value for " + "parameter operation -- Ignoring\n"); + GNUNET_free (msg); + GNUNET_free (handle); + return NULL; + } + handle->close_msg_retransmission_task_id = + GNUNET_SCHEDULER_add_delayed (socket->retransmit_timeout, + &close_msg_retransmission_task, + handle); + return handle; +} + + +/** + * Cancels a pending shutdown + * + * @param handle the shutdown handle returned from GNUNET_STREAM_shutdown + */ +void +GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle) +{ + if (GNUNET_SCHEDULER_NO_TASK != handle->close_msg_retransmission_task_id) + GNUNET_SCHEDULER_cancel (handle->close_msg_retransmission_task_id); + GNUNET_free (handle); + return; +} + + /** * Closes the stream * @@ -1877,20 +2920,45 @@ GNUNET_STREAM_close (struct GNUNET_STREAM_Socket *socket) { struct MessageQueue *head; - if (socket->read_task != GNUNET_SCHEDULER_NO_TASK) + if (NULL != socket->read_handle) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Closing STREAM socket when a read handle is pending\n"); + } + if (NULL != socket->write_handle) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Closing STREAM socket when a write handle is pending\n"); + } + + if (socket->read_task_id != GNUNET_SCHEDULER_NO_TASK) { /* socket closed with read task pending!? */ GNUNET_break (0); - GNUNET_SCHEDULER_cancel (socket->read_task); - socket->read_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_SCHEDULER_cancel (socket->read_task_id); + socket->read_task_id = GNUNET_SCHEDULER_NO_TASK; + } + + /* Terminate the ack'ing tasks if they are still present */ + if (socket->ack_task_id != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (socket->ack_task_id); + socket->ack_task_id = GNUNET_SCHEDULER_NO_TASK; } /* Clear Transmit handles */ if (NULL != socket->transmit_handle) - { - GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle); - socket->transmit_handle = NULL; - } + { + GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle); + socket->transmit_handle = NULL; + } + if (NULL != socket->ack_transmit_handle) + { + GNUNET_MESH_notify_transmit_ready_cancel (socket->ack_transmit_handle); + GNUNET_free (socket->ack_msg); + socket->ack_msg = NULL; + socket->ack_transmit_handle = NULL; + } /* Clear existing message queue */ while (NULL != (head = socket->queue_head)) { @@ -1903,100 +2971,28 @@ GNUNET_STREAM_close (struct GNUNET_STREAM_Socket *socket) /* Close associated tunnel */ if (NULL != socket->tunnel) - { - GNUNET_MESH_tunnel_destroy (socket->tunnel); - socket->tunnel = NULL; - } + { + GNUNET_MESH_tunnel_destroy (socket->tunnel); + socket->tunnel = NULL; + } /* Close mesh connection */ - if (NULL != socket->mesh) - { - GNUNET_MESH_disconnect (socket->mesh); - socket->mesh = NULL; - } + if (NULL != socket->mesh && NULL == socket->lsocket) + { + GNUNET_MESH_disconnect (socket->mesh); + socket->mesh = NULL; + } /* Release receive buffer */ if (NULL != socket->receive_buffer) - { - GNUNET_free (socket->receive_buffer); - } + { + GNUNET_free (socket->receive_buffer); + } GNUNET_free (socket); } -/** - * Method called whenever a peer creates a tunnel to us - * - * @param cls closure - * @param tunnel new handle to the tunnel - * @param initiator peer that started the tunnel - * @param atsi performance information for the tunnel - * @return initial tunnel context for the tunnel - * (can be NULL -- that's not an error) - */ -static void * -new_tunnel_notify (void *cls, - struct GNUNET_MESH_Tunnel *tunnel, - const struct GNUNET_PeerIdentity *initiator, - const struct GNUNET_ATS_Information *atsi) -{ - struct GNUNET_STREAM_ListenSocket *lsocket = cls; - struct GNUNET_STREAM_Socket *socket; - - socket = GNUNET_malloc (sizeof (struct GNUNET_STREAM_Socket)); - socket->tunnel = tunnel; - socket->session_id = 0; /* FIXME */ - socket->other_peer = *initiator; - socket->state = STATE_INIT; - - if (GNUNET_SYSERR == lsocket->listen_cb (lsocket->listen_cb_cls, - socket, - &socket->other_peer)) - { - socket->state = STATE_CLOSED; - /* FIXME: Send CLOSE message and then free */ - GNUNET_free (socket); - GNUNET_MESH_tunnel_destroy (tunnel); /* Destroy the tunnel */ - } - return socket; -} - - -/** - * Function called whenever an inbound tunnel is destroyed. Should clean up - * any associated state. This function is NOT called if the client has - * explicitly asked for the tunnel to be destroyed using - * GNUNET_MESH_tunnel_destroy. It must NOT call GNUNET_MESH_tunnel_destroy on - * the tunnel. - * - * @param cls closure (set from GNUNET_MESH_connect) - * @param tunnel connection to the other end (henceforth invalid) - * @param tunnel_ctx place where local state associated - * with the tunnel is stored - */ -static void -tunnel_cleaner (void *cls, - const struct GNUNET_MESH_Tunnel *tunnel, - void *tunnel_ctx) -{ - struct GNUNET_STREAM_Socket *socket = tunnel_ctx; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer %s has terminated connection abruptly\n", - GNUNET_i2s (&socket->other_peer)); - - socket->status = GNUNET_STREAM_SHUTDOWN; - /* Clear Transmit handles */ - if (NULL != socket->transmit_handle) - { - GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle); - socket->transmit_handle = NULL; - } - socket->tunnel = NULL; -} - - /** * Listens for stream connections for a specific application ports * @@ -2015,10 +3011,8 @@ GNUNET_STREAM_listen (const struct GNUNET_CONFIGURATION_Handle *cfg, { /* FIXME: Add variable args for passing configration options? */ struct GNUNET_STREAM_ListenSocket *lsocket; - GNUNET_MESH_ApplicationType app_types[2]; + GNUNET_MESH_ApplicationType ports[] = {app_port, 0}; - app_types[0] = app_port; - app_types[1] = 0; lsocket = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ListenSocket)); lsocket->port = app_port; lsocket->listen_cb = listen_cb; @@ -2029,7 +3023,8 @@ GNUNET_STREAM_listen (const struct GNUNET_CONFIGURATION_Handle *cfg, &new_tunnel_notify, &tunnel_cleaner, server_message_handlers, - app_types); + ports); + GNUNET_assert (NULL != lsocket->mesh); return lsocket; } @@ -2043,6 +3038,7 @@ void GNUNET_STREAM_listen_close (struct GNUNET_STREAM_ListenSocket *lsocket) { /* Close MESH connection */ + GNUNET_assert (NULL != lsocket->mesh); GNUNET_MESH_disconnect (lsocket->mesh); GNUNET_free (lsocket); @@ -2050,15 +3046,22 @@ GNUNET_STREAM_listen_close (struct GNUNET_STREAM_ListenSocket *lsocket) /** - * Tries to write the given data to the stream + * Tries to write the given data to the stream. The maximum size of data that + * can be written as part of a write operation is (64 * (64000 - sizeof (struct + * GNUNET_STREAM_DataMessage))). If size is greater than this it is not an API + * violation, however only the said number of maximum bytes will be written. * * @param socket the socket representing a stream * @param data the data buffer from where the data is written into the stream * @param size the number of bytes to be written from the data buffer * @param timeout the timeout period - * @param write_cont the function to call upon writing some bytes into the stream + * @param write_cont the function to call upon writing some bytes into the + * stream * @param write_cont_cls the closure - * @return handle to cancel the operation + * + * @return handle to cancel the operation; if a previous write is pending or + * the stream has been shutdown for this operation then write_cont is + * immediately called and NULL is returned. */ struct GNUNET_STREAM_IOWriteHandle * GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, @@ -2075,6 +3078,10 @@ GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, uint32_t payload_size; struct GNUNET_STREAM_DataMessage *data_msg; const void *sweep; + struct GNUNET_TIME_Relative ack_deadline; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s\n", __func__); /* Return NULL if there is already a write request pending */ if (NULL != socket->write_handle) @@ -2082,70 +3089,101 @@ GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, GNUNET_break (0); return NULL; } - if (!((STATE_ESTABLISHED == socket->state) - || (STATE_RECEIVE_CLOSE_WAIT == socket->state) - || (STATE_RECEIVE_CLOSED == socket->state))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Attempting to write on a closed (OR) not-yet-established" - "stream\n"); - return NULL; - } + + switch (socket->state) + { + case STATE_TRANSMIT_CLOSED: + case STATE_TRANSMIT_CLOSE_WAIT: + case STATE_CLOSED: + case STATE_CLOSE_WAIT: + if (NULL != write_cont) + write_cont (write_cont_cls, GNUNET_STREAM_SHUTDOWN, 0); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s() END\n", __func__); + return NULL; + case STATE_INIT: + case STATE_LISTEN: + case STATE_HELLO_WAIT: + if (NULL != write_cont) + /* FIXME: GNUNET_STREAM_SYSERR?? */ + write_cont (write_cont_cls, GNUNET_STREAM_SYSERR, 0); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s() END\n", __func__); + return NULL; + case STATE_ESTABLISHED: + case STATE_RECEIVE_CLOSED: + case STATE_RECEIVE_CLOSE_WAIT: + break; + } + if (GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH * max_payload_size < size) size = GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH * max_payload_size; num_needed_packets = (size + (max_payload_size - 1)) / max_payload_size; io_handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_IOWriteHandle)); + io_handle->socket = socket; + io_handle->write_cont = write_cont; + io_handle->write_cont_cls = write_cont_cls; + io_handle->size = size; sweep = data; + /* FIXME: Remove the fixed delay for ack deadline; Set it to the value + determined from RTT */ + ack_deadline = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5); /* Divide the given buffer into packets for sending */ for (packet=0; packet < num_needed_packets; packet++) + { + if ((packet + 1) * max_payload_size < size) + { + payload_size = max_payload_size; + packet_size = MAX_PACKET_SIZE; + } + else { - if ((packet + 1) * max_payload_size < size) - { - payload_size = max_payload_size; - packet_size = MAX_PACKET_SIZE; - } - else - { - payload_size = size - packet * max_payload_size; - packet_size = payload_size + sizeof (struct - GNUNET_STREAM_DataMessage); - } - io_handle->messages[packet] = GNUNET_malloc (packet_size); - io_handle->messages[packet]->header.header.size = htons (packet_size); - io_handle->messages[packet]->header.header.type = - htons (GNUNET_MESSAGE_TYPE_STREAM_DATA); - io_handle->messages[packet]->sequence_number = - htons (socket->write_sequence_number++); - io_handle->messages[packet]->offset = htons (socket->write_offset); - - /* FIXME: Remove the fixed delay for ack deadline; Set it to the value - determined from RTT */ - io_handle->messages[packet]->ack_deadline = - GNUNET_TIME_relative_hton (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5)); - data_msg = io_handle->messages[packet]; - /* Copy data from given buffer to the packet */ - memcpy (&data_msg[1], - sweep, - payload_size); - sweep += payload_size; - socket->write_offset += payload_size; + payload_size = size - packet * max_payload_size; + packet_size = payload_size + sizeof (struct + GNUNET_STREAM_DataMessage); } + io_handle->messages[packet] = GNUNET_malloc (packet_size); + io_handle->messages[packet]->header.header.size = htons (packet_size); + io_handle->messages[packet]->header.header.type = + htons (GNUNET_MESSAGE_TYPE_STREAM_DATA); + io_handle->messages[packet]->sequence_number = + htonl (socket->write_sequence_number++); + io_handle->messages[packet]->offset = htonl (socket->write_offset); + + /* FIXME: Remove the fixed delay for ack deadline; Set it to the value + determined from RTT */ + io_handle->messages[packet]->ack_deadline = + GNUNET_TIME_relative_hton (ack_deadline); + data_msg = io_handle->messages[packet]; + /* Copy data from given buffer to the packet */ + memcpy (&data_msg[1], + sweep, + payload_size); + sweep += payload_size; + socket->write_offset += payload_size; + } socket->write_handle = io_handle; write_data (socket); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s() END\n", __func__); + return io_handle; } + /** - * Tries to read data from the stream + * Tries to read data from the stream. * * @param socket the socket representing a stream * @param timeout the timeout period * @param proc function to call with data (once only) * @param proc_cls the closure for proc - * @return handle to cancel the operation + * + * @return handle to cancel the operation; if the stream has been shutdown for + * this type of opeartion then the DataProcessor is immediately + * called with GNUNET_STREAM_SHUTDOWN as status and NULL if returned */ struct GNUNET_STREAM_IOReadHandle * GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket, @@ -2155,26 +3193,99 @@ GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket, { struct GNUNET_STREAM_IOReadHandle *read_handle; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: %s()\n", + GNUNET_i2s (&socket->other_peer), + __func__); + /* Return NULL if there is already a read handle; the user has to cancel that - first before continuing or has to wait until it is completed */ + first before continuing or has to wait until it is completed */ if (NULL != socket->read_handle) return NULL; + GNUNET_assert (NULL != proc); + + switch (socket->state) + { + case STATE_RECEIVE_CLOSED: + case STATE_RECEIVE_CLOSE_WAIT: + case STATE_CLOSED: + case STATE_CLOSE_WAIT: + proc (proc_cls, GNUNET_STREAM_SHUTDOWN, NULL, 0); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: %s() END\n", + GNUNET_i2s (&socket->other_peer), + __func__); + return NULL; + default: + break; + } + read_handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_IOReadHandle)); read_handle->proc = proc; + read_handle->proc_cls = proc_cls; socket->read_handle = read_handle; /* Check if we have a packet at bitmap 0 */ if (GNUNET_YES == ackbitmap_is_bit_set (&socket->ack_bitmap, 0)) - { - socket->read_task = GNUNET_SCHEDULER_add_now (&call_read_processor, - socket); + { + socket->read_task_id = GNUNET_SCHEDULER_add_now (&call_read_processor, + socket); - } + } /* Setup the read timeout task */ - socket->read_io_timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, - &read_io_timeout, - socket); + socket->read_io_timeout_task_id = + GNUNET_SCHEDULER_add_delayed (timeout, + &read_io_timeout, + socket); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "%s: %s() END\n", + GNUNET_i2s (&socket->other_peer), + __func__); return read_handle; } + + +/** + * Cancel pending write operation. + * + * @param ioh handle to operation to cancel + */ +void +GNUNET_STREAM_io_write_cancel (struct GNUNET_STREAM_IOWriteHandle *ioh) +{ + struct GNUNET_STREAM_Socket *socket = ioh->socket; + unsigned int packet; + + GNUNET_assert (NULL != socket->write_handle); + GNUNET_assert (socket->write_handle == ioh); + + if (GNUNET_SCHEDULER_NO_TASK != socket->retransmission_timeout_task_id) + { + GNUNET_SCHEDULER_cancel (socket->retransmission_timeout_task_id); + socket->retransmission_timeout_task_id = GNUNET_SCHEDULER_NO_TASK; + } + + for (packet=0; packet < GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH; packet++) + { + if (NULL == ioh->messages[packet]) break; + GNUNET_free (ioh->messages[packet]); + } + + GNUNET_free (socket->write_handle); + socket->write_handle = NULL; + return; +} + + +/** + * Cancel pending read operation. + * + * @param ioh handle to operation to cancel + */ +void +GNUNET_STREAM_io_read_cancel (struct GNUNET_STREAM_IOReadHandle *ioh) +{ + return; +} diff --git a/src/stream/stream_protocol.h b/src/stream/stream_protocol.h index 0c1987e..0c5376f 100644 --- a/src/stream/stream_protocol.h +++ b/src/stream/stream_protocol.h @@ -127,10 +127,8 @@ struct GNUNET_STREAM_AckMessage GNUNET_STREAM_AckBitmap bitmap GNUNET_PACKED; /** - * The sequence number of the Data Message upto which the receiver has filled - * its buffer without any missing packets - * - * FIXME: Do we need this? + * The sequence number of the next Data Message receiver is + * anticipating. Data messages less than this number are received by receiver */ uint32_t base_sequence_number GNUNET_PACKED; @@ -163,7 +161,7 @@ struct GNUNET_STREAM_HelloAckMessage * * FIXME: Remove if not needed */ - uint32_t receive_window_size; + uint32_t receiver_window_size; }; diff --git a/src/stream/test_stream_2peers.c b/src/stream/test_stream_2peers.c new file mode 100644 index 0000000..1fdc0ee --- /dev/null +++ b/src/stream/test_stream_2peers.c @@ -0,0 +1,560 @@ +/* + This file is part of GNUnet. + (C) 2011, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file stream/test_stream_2peers.c + * @brief Stream API testing between 2 peers using testing API + * @author Sree Harsha Totakura + */ + +#include + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_mesh_service.h" +#include "gnunet_stream_lib.h" +#include "gnunet_testing_lib.h" + +#define VERBOSE 1 + +/** + * Number of peers + */ +#define NUM_PEERS 2 + +/** + * Structure for holding peer's sockets and IO Handles + */ +struct PeerData +{ + /** + * Peer's stream socket + */ + struct GNUNET_STREAM_Socket *socket; + + /** + * Peer's io write handle + */ + struct GNUNET_STREAM_IOWriteHandle *io_write_handle; + + /** + * Peer's io read handle + */ + struct GNUNET_STREAM_IOReadHandle *io_read_handle; + + /** + * Peer's shutdown handle + */ + struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; + + /** + * Our Peer id + */ + struct GNUNET_PeerIdentity our_id; + + /** + * Bytes the peer has written + */ + unsigned int bytes_wrote; + + /** + * Byte the peer has read + */ + unsigned int bytes_read; +}; + +/** + * The current peer group + */ +static struct GNUNET_TESTING_PeerGroup *pg; + +/** + * Peer 1 daemon + */ +static struct GNUNET_TESTING_Daemon *d1; + +/** + * Peer 2 daemon + */ +static struct GNUNET_TESTING_Daemon *d2; + +static struct PeerData peer1; +static struct PeerData peer2; +static struct GNUNET_STREAM_ListenSocket *peer2_listen_socket; +static struct GNUNET_CONFIGURATION_Handle *config; + +static GNUNET_SCHEDULER_TaskIdentifier abort_task; + +static char *data = "ABCD"; +static int result; + +static int writing_success; +static int reading_success; + + +/** + * Input processor + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param data traffic from the other side + * @param size the number of bytes available in data read + * @return number of bytes of processed from 'data' (any data remaining should be + * given to the next time the read processor is called). + */ +static size_t +input_processor (void *cls, + enum GNUNET_STREAM_Status status, + const void *input_data, + size_t size); + +/** + * Task for calling STREAM_read + * + * @param cls the peer data entity + * @param tc the task context + */ +static void +stream_read_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerData *peer = cls; + + peer->io_read_handle = GNUNET_STREAM_read (peer->socket, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 5), + &input_processor, + peer); + GNUNET_assert (NULL != peer->io_read_handle); +} + +/** + * The write completion function; called upon writing some data to stream or + * upon error + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param size the number of bytes read or written + */ +static void +write_completion (void *cls, + enum GNUNET_STREAM_Status status, + size_t size); + + +/** + * Task for calling STREAM_write + * + * @param cls the peer data entity + * @param tc the task context + */ +static void +stream_write_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerData *peer = cls; + + peer->io_write_handle = + GNUNET_STREAM_write (peer->socket, + (void *) data, + strlen(data) - peer->bytes_wrote, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 5), + &write_completion, + peer); + + GNUNET_assert (NULL != peer->io_write_handle); + } + + +/** + * Check whether peers successfully shut down. + */ +static void +peergroup_shutdown_callback (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Shutdown of peers failed!\n"); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "All peers successfully shut down!\n"); + } + GNUNET_CONFIGURATION_destroy (config); +} + + +/** + * Close sockets and stop testing deamons nicely + */ +static void +do_close (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (NULL != peer1.socket) + GNUNET_STREAM_close (peer1.socket); + if (NULL != peer2.socket) + GNUNET_STREAM_close (peer2.socket); + if (NULL != peer2_listen_socket) + GNUNET_STREAM_listen_close (peer2_listen_socket); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n"); + if (0 != abort_task) + { + GNUNET_SCHEDULER_cancel (abort_task); + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n"); + + GNUNET_TESTING_daemons_stop (pg, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 5), + &peergroup_shutdown_callback, + NULL); +} + + +/** + * Completion callback for shutdown + * + * @param cls the closure from GNUNET_STREAM_shutdown call + * @param operation the operation that was shutdown (SHUT_RD, SHUT_WR, + * SHUT_RDWR) + */ +static void +shutdown_completion (void *cls, + int operation) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "STREAM shutdown successful\n"); + GNUNET_SCHEDULER_add_now (&do_close, + cls); +} + + + +/** + * Shutdown sockets gracefully + */ +static void +do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + peer1.shutdown_handle = GNUNET_STREAM_shutdown (peer1.socket, + SHUT_RDWR, + &shutdown_completion, + cls); +} + + +/** + * Something went wrong and timed out. Kill everything and set error flag + */ +static void +do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: ABORT\n"); + result = GNUNET_SYSERR; + abort_task = 0; + do_close (cls, tc); +} + + +/** + * The write completion function; called upon writing some data to stream or + * upon error + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param size the number of bytes read or written + */ +static void +write_completion (void *cls, + enum GNUNET_STREAM_Status status, + size_t size) +{ + struct PeerData *peer=cls; + + GNUNET_assert (GNUNET_STREAM_OK == status); + GNUNET_assert (size <= strlen (data)); + peer->bytes_wrote += size; + + if (peer->bytes_wrote < strlen(data)) /* Have more data to send */ + { + GNUNET_SCHEDULER_add_now (&stream_write_task, peer); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Writing completed\n"); + + if (&peer1 == peer) /* Peer1 has finished writing; should read now */ + { + peer->bytes_read = 0; + GNUNET_SCHEDULER_add_now (&stream_read_task, peer); + } + else + { + writing_success = GNUNET_YES; + if (GNUNET_YES == reading_success) + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + } + } +} + + +/** + * Function executed after stream has been established + * + * @param cls the closure from GNUNET_STREAM_open + * @param socket socket to use to communicate with the other side (read/write) + */ +static void +stream_open_cb (void *cls, + struct GNUNET_STREAM_Socket *socket) +{ + struct PeerData *peer=cls; + + GNUNET_assert (&peer1 == peer); + GNUNET_assert (socket == peer1.socket); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s: Stream established from peer1\n", + GNUNET_i2s (&peer1.our_id)); + peer->bytes_wrote = 0; + GNUNET_SCHEDULER_add_now (&stream_write_task, peer); +} + + +/** + * Input processor + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param data traffic from the other side + * @param size the number of bytes available in data read + * @return number of bytes of processed from 'data' (any data remaining should be + * given to the next time the read processor is called). + */ +static size_t +input_processor (void *cls, + enum GNUNET_STREAM_Status status, + const void *input_data, + size_t size) +{ + struct PeerData *peer; + + peer = (struct PeerData *) cls; + + if (GNUNET_STREAM_TIMEOUT == status) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Read operation timedout - reading again!\n"); + GNUNET_assert (0 == size); + GNUNET_SCHEDULER_add_now (&stream_read_task, peer); + return 0; + } + + GNUNET_assert (GNUNET_STREAM_OK == status); + GNUNET_assert (size <= strlen (data)); + GNUNET_assert (0 == strncmp ((const char *) data + peer->bytes_read, + (const char *) input_data, + size)); + peer->bytes_read += size; + + if (peer->bytes_read < strlen (data)) + { + GNUNET_SCHEDULER_add_now (&stream_read_task, peer); + } + else + { + if (&peer2 == peer) /* Peer2 has completed reading; should write */ + { + peer->bytes_wrote = 0; + GNUNET_SCHEDULER_add_now (&stream_write_task, peer); + } + else /* Peer1 has completed reading. End of tests */ + { + reading_success = GNUNET_YES; + if (GNUNET_YES == writing_success) + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + } + } + return size; +} + + +/** + * Functions of this type are called upon new stream connection from other peers + * + * @param cls the closure from GNUNET_STREAM_listen + * @param socket the socket representing the stream + * @param initiator the identity of the peer who wants to establish a stream + * with us + * @return GNUNET_OK to keep the socket open, GNUNET_SYSERR to close the + * stream (the socket will be invalid after the call) + */ +static int +stream_listen_cb (void *cls, + struct GNUNET_STREAM_Socket *socket, + const struct GNUNET_PeerIdentity *initiator) +{ + GNUNET_assert (NULL != socket); + GNUNET_assert (NULL != initiator); + GNUNET_assert (socket != peer1.socket); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s: Peer connected: %s\n", + GNUNET_i2s (&peer2.our_id), + GNUNET_i2s(initiator)); + + peer2.socket = socket; + peer2.bytes_read = 0; + GNUNET_SCHEDULER_add_now (&stream_read_task, &peer2); + return GNUNET_OK; +} + + +/** + * Callback to be called when testing peer group is ready + * + * @param cls NULL + * @param emsg NULL on success + */ +void +peergroup_ready (void *cls, const char *emsg) +{ + if (NULL != emsg) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Starting peer group failed: %s\n", emsg); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer group is now ready\n"); + + GNUNET_assert (2 == GNUNET_TESTING_daemons_running (pg)); + + d1 = GNUNET_TESTING_daemon_get (pg, 0); + GNUNET_assert (NULL != d1); + + d2 = GNUNET_TESTING_daemon_get (pg, 1); + GNUNET_assert (NULL != d2); + + GNUNET_TESTING_get_peer_identity (d1->cfg, + &peer1.our_id); + GNUNET_TESTING_get_peer_identity (d2->cfg, + &peer2.our_id); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s : %s\n", + GNUNET_i2s (&peer1.our_id), + GNUNET_i2s (&d1->id)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s : %s\n", + GNUNET_i2s (&peer2.our_id), + GNUNET_i2s (&d2->id)); + + peer2_listen_socket = GNUNET_STREAM_listen (d2->cfg, + 10, /* App port */ + &stream_listen_cb, + NULL); + GNUNET_assert (NULL != peer2_listen_socket); + + /* Connect to stream library */ + peer1.socket = GNUNET_STREAM_open (d1->cfg, + &d2->id, /* Null for local peer? */ + 10, /* App port */ + &stream_open_cb, + &peer1, + GNUNET_STREAM_OPTION_END); + GNUNET_assert (NULL != peer1.socket); +} + + +/** + * Initialize framework and start test + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_TESTING_Host *hosts; /* FIXME: free hosts (DLL) */ + + GNUNET_log_setup ("test_stream_2peers", + "DEBUG", + NULL); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting test\n"); + /* Duplicate the configuration */ + config = GNUNET_CONFIGURATION_dup (cfg); + + hosts = GNUNET_TESTING_hosts_load (config); + + pg = GNUNET_TESTING_peergroup_start (config, + 2, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 3), + NULL, + &peergroup_ready, + NULL, + hosts); + GNUNET_assert (NULL != pg); + + abort_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 40), &do_abort, + NULL); +} + +/** + * Main function + */ +int main (int argc, char **argv) +{ + int ret; + + char *argv2[] = { "test-stream-2peers", + "-L", "DEBUG", + "-c", "test_stream_local.conf", + NULL}; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + ret = + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test-stream-2peers", "nohelp", options, &run, NULL); + + if (GNUNET_OK != ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", + ret); + return 1; + } + if (GNUNET_SYSERR == result) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); + return 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test ok\n"); + return 0; +} diff --git a/src/stream/test_stream_2peers_halfclose.c b/src/stream/test_stream_2peers_halfclose.c new file mode 100644 index 0000000..7997c20 --- /dev/null +++ b/src/stream/test_stream_2peers_halfclose.c @@ -0,0 +1,786 @@ +/* + This file is part of GNUnet. + (C) 2011, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file stream/test_stream_2peers_halfclose.c + * @brief Testcases for Stream API halfclosed connections between 2 peers + * @author Sree Harsha Totakura + */ + +#include + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_mesh_service.h" +#include "gnunet_stream_lib.h" +#include "gnunet_testing_lib.h" +#include "gnunet_scheduler_lib.h" + +#define VERBOSE 1 + +/** + * Number of peers + */ +#define NUM_PEERS 2 + +/** + * Structure for holding peer's sockets and IO Handles + */ +struct PeerData +{ + /** + * Peer's stream socket + */ + struct GNUNET_STREAM_Socket *socket; + + /** + * Peer's io write handle + */ + struct GNUNET_STREAM_IOWriteHandle *io_write_handle; + + /** + * Peer's io read handle + */ + struct GNUNET_STREAM_IOReadHandle *io_read_handle; + + /** + * Peer's shutdown handle + */ + struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; + + /** + * Our Peer id + */ + struct GNUNET_PeerIdentity our_id; + + /** + * Bytes the peer has written + */ + unsigned int bytes_wrote; + + /** + * Byte the peer has read + */ + unsigned int bytes_read; + + /** + * GNUNET_YES if the peer has successfully completed the current test + */ + unsigned int test_ok; + + /** + * The shutdown operation that has to be used by the stream_shutdown_task + */ + int shutdown_operation; +}; + +/** + * The current peer group + */ +static struct GNUNET_TESTING_PeerGroup *pg; + +/** + * Peer 1 daemon + */ +static struct GNUNET_TESTING_Daemon *d1; + +/** + * Peer 2 daemon + */ +static struct GNUNET_TESTING_Daemon *d2; + + +/** + * Peer1 writes first and then calls for SHUT_WR + * Peer2 reads first and then calls for SHUT_RD + * Attempt to write again by Peer1 should be rejected + * Attempt to read again by Peer2 should be rejected + * Peer1 then reads from Peer2 which writes + */ +static struct PeerData peer1; +static struct PeerData peer2; +static struct GNUNET_STREAM_ListenSocket *peer2_listen_socket; +static struct GNUNET_CONFIGURATION_Handle *config; + +static GNUNET_SCHEDULER_TaskIdentifier abort_task; +static GNUNET_SCHEDULER_TaskIdentifier read_task; + +static char *data = "ABCD"; +static int result; + +/** + * Enumeration for various tests that are to be passed in the same order as + * below + */ +enum Test + { + /** + * Peer1 writing; Peer2 reading + */ + PEER1_WRITE, + + /** + * Peer1 write shutdown; Peer2 should get an error when it tries to read; + */ + PEER1_WRITE_SHUTDOWN, + + /** + * Peer1 reads; Peer2 writes (connection is halfclosed) + */ + PEER1_HALFCLOSE_READ, + + /** + * Peer1 attempts to write; Should fail with stream already shutdown error + */ + PEER1_HALFCLOSE_WRITE_FAIL, + + /** + * Peer1 read shutdown; Peer2 should get stream shutdown error during write + */ + PEER1_READ_SHUTDOWN, + + /** + * All tests successfully finished + */ + SUCCESS + }; + +/** + * Current running test + */ +enum Test current_test; + +/** + * Input processor + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param data traffic from the other side + * @param size the number of bytes available in data read + * @return number of bytes of processed from 'data' (any data remaining should be + * given to the next time the read processor is called). + */ +static size_t +input_processor (void *cls, + enum GNUNET_STREAM_Status status, + const void *input_data, + size_t size); + + +/** + * The transition function; responsible for the transitions among tests + */ +static void +transition(); + + +/** + * Task for calling STREAM_read + * + * @param cls the peer data entity + * @param tc the task context + */ +static void +stream_read_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerData *peer = cls; + + peer->io_read_handle = GNUNET_STREAM_read (peer->socket, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 5), + &input_processor, + cls); + switch (current_test) + { + case PEER1_WRITE_SHUTDOWN: + GNUNET_assert (&peer2 == peer); + GNUNET_assert (NULL == peer->io_read_handle); + transition (); /* to PEER1_HALFCLOSE_READ */ + break; + default: + GNUNET_assert (NULL != peer->io_read_handle); + } +} + + +/** + * The write completion function; called upon writing some data to stream or + * upon error + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param size the number of bytes read or written + */ +static void +write_completion (void *cls, + enum GNUNET_STREAM_Status status, + size_t size); + + +/** + * Task for calling STREAM_write + * + * @param cls the peer data entity + * @param tc the task context + */ +static void +stream_write_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerData *peer = cls; + + peer->io_write_handle = + GNUNET_STREAM_write (peer->socket, + (void *) data, + strlen(data) - peer->bytes_wrote, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 5), + &write_completion, + peer); + switch (current_test) + { + case PEER1_HALFCLOSE_WRITE_FAIL: + GNUNET_assert (&peer1 == peer); + GNUNET_assert (NULL == peer->io_write_handle); + transition(); /* To PEER1_READ_SHUTDOWN */ + break; + case PEER1_READ_SHUTDOWN: + GNUNET_assert (&peer2 == peer); + GNUNET_assert (NULL == peer->io_write_handle); + transition (); /* To SUCCESS */ + break; + default: + GNUNET_assert (NULL != peer->io_write_handle); + } +} + + +/** + * Check whether peers successfully shut down. + */ +static void +peergroup_shutdown_callback (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Shutdown of peers failed!\n"); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "All peers successfully shut down!\n"); + } + GNUNET_CONFIGURATION_destroy (config); +} + + +/** + * Close sockets and stop testing deamons nicely + */ +static void +do_close (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (NULL != peer1.socket) + GNUNET_STREAM_close (peer1.socket); + if (NULL != peer2.socket) + GNUNET_STREAM_close (peer2.socket); + if (NULL != peer2_listen_socket) + GNUNET_STREAM_listen_close (peer2_listen_socket); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n"); + if (0 != abort_task) + { + GNUNET_SCHEDULER_cancel (abort_task); + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n"); + + GNUNET_TESTING_daemons_stop (pg, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 5), + &peergroup_shutdown_callback, + NULL); +} + + +/** + * Completion callback for shutdown + * + * @param cls the closure from GNUNET_STREAM_shutdown call + * @param operation the operation that was shutdown (SHUT_RD, SHUT_WR, + * SHUT_RDWR) + */ +void +shutdown_completion (void *cls, + int operation) +{ + switch (current_test) + { + case PEER1_WRITE: + GNUNET_assert (0); + case PEER1_WRITE_SHUTDOWN: + GNUNET_assert (cls == &peer1); + GNUNET_assert (SHUT_WR == operation); + peer1.test_ok = GNUNET_YES; + /* Peer2 should read with error */ + peer2.bytes_read = 0; + GNUNET_SCHEDULER_add_now (&stream_read_task, &peer2); + break; + case PEER1_READ_SHUTDOWN: + peer1.test_ok = GNUNET_YES; + peer2.bytes_wrote = 0; + GNUNET_SCHEDULER_add_now (&stream_write_task, &peer2); + break; + case PEER1_HALFCLOSE_READ: + case PEER1_HALFCLOSE_WRITE_FAIL: + case SUCCESS: + GNUNET_assert (0); /* We shouldn't reach here */ + } +} + + +/** + * Task for calling STREAM_shutdown + * + * @param cls the peer entity + * @param tc the TaskContext + */ +static void +stream_shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerData *peer = cls; + + peer->shutdown_handle = GNUNET_STREAM_shutdown (peer->socket, + peer->shutdown_operation, + &shutdown_completion, + peer); + GNUNET_assert (NULL != peer->shutdown_handle); +} + + +/** + * Something went wrong and timed out. Kill everything and set error flag + */ +static void +do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: ABORT\n"); + if (0 != read_task) + { + GNUNET_SCHEDULER_cancel (read_task); + } + result = GNUNET_SYSERR; + abort_task = 0; + do_close (cls, tc); +} + + +/** + * The transition function; responsible for the transitions among tests + */ +static void +transition() +{ + if ((GNUNET_YES == peer1.test_ok) && (GNUNET_YES == peer2.test_ok)) + { + peer1.test_ok = GNUNET_NO; + peer2.test_ok = GNUNET_NO; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "TEST %d SUCCESSFULL\n", current_test); + switch (current_test) + { + case PEER1_WRITE: + current_test = PEER1_WRITE_SHUTDOWN; + /* Peer1 should shutdown writing */ + peer1.shutdown_operation = SHUT_WR; + GNUNET_SCHEDULER_add_now (&stream_shutdown_task, &peer1); + break; + case PEER1_WRITE_SHUTDOWN: + current_test = PEER1_HALFCLOSE_READ; + /* Peer2 should be able to write successfully */ + peer2.bytes_wrote = 0; + GNUNET_SCHEDULER_add_now (&stream_write_task, &peer2); + + /* Peer1 should be able to read successfully */ + peer1.bytes_read = 0; + GNUNET_SCHEDULER_add_now (&stream_read_task, &peer1); + break; + case PEER1_HALFCLOSE_READ: + current_test = PEER1_HALFCLOSE_WRITE_FAIL; + peer1.bytes_wrote = 0; + peer2.bytes_read = 0; + peer2.test_ok = GNUNET_YES; + GNUNET_SCHEDULER_add_now (&stream_write_task, &peer1); + break; + case PEER1_HALFCLOSE_WRITE_FAIL: + current_test = PEER1_READ_SHUTDOWN; + peer1.shutdown_operation = SHUT_RD; + GNUNET_SCHEDULER_add_now (&stream_shutdown_task, &peer1); + break; + case PEER1_READ_SHUTDOWN: + current_test = SUCCESS; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "All tests successful\n"); + GNUNET_SCHEDULER_add_now (&do_close, NULL); + break; + case SUCCESS: + GNUNET_assert (0); /* We shouldn't reach here */ + + } + } +} + +/** + * The write completion function; called upon writing some data to stream or + * upon error + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param size the number of bytes read or written + */ +static void +write_completion (void *cls, + enum GNUNET_STREAM_Status status, + size_t size) +{ + struct PeerData *peer = cls; + + switch (current_test) + { + case PEER1_WRITE: + case PEER1_HALFCLOSE_READ: + + GNUNET_assert (GNUNET_STREAM_OK == status); + GNUNET_assert (size <= strlen (data)); + peer->bytes_wrote += size; + + if (peer->bytes_wrote < strlen(data)) /* Have more data to send */ + { + GNUNET_SCHEDULER_add_now (&stream_write_task, peer); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Writing completed\n"); + + if (&peer1 == peer) + { + peer1.test_ok = GNUNET_YES; + transition (); /* to PEER1_WRITE_SHUTDOWN */ + } + else /* This will happen during PEER1_HALFCLOSE_READ */ + { + peer2.test_ok = GNUNET_YES; + transition (); /* to PEER1_HALFCLOSE_WRITE_FAIL */ + } + } + break; + case PEER1_HALFCLOSE_WRITE_FAIL: + GNUNET_assert (peer == &peer1); + GNUNET_assert (GNUNET_STREAM_SHUTDOWN == status); + GNUNET_assert (0 == size); + peer1.test_ok = GNUNET_YES; + break; + case PEER1_READ_SHUTDOWN: + GNUNET_assert (peer == &peer2); + GNUNET_assert (GNUNET_STREAM_SHUTDOWN == status); + GNUNET_assert (0 == size); + peer2.test_ok = GNUNET_YES; + break; + case PEER1_WRITE_SHUTDOWN: + case SUCCESS: + GNUNET_assert (0); /* We shouldn't reach here */ + } +} + + +/** + * Function executed after stream has been established + * + * @param cls the closure from GNUNET_STREAM_open + * @param socket socket to use to communicate with the other side (read/write) + */ +static void +stream_open_cb (void *cls, + struct GNUNET_STREAM_Socket *socket) +{ + struct PeerData *peer; + + GNUNET_assert (socket == peer1.socket); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s: Stream established from peer1\n", + GNUNET_i2s (&peer1.our_id)); + peer = (struct PeerData *) cls; + peer->bytes_wrote = 0; + GNUNET_assert (socket == peer1.socket); + GNUNET_assert (socket == peer->socket); + peer1.test_ok = GNUNET_NO; + peer2.test_ok = GNUNET_NO; + current_test = PEER1_WRITE; + GNUNET_SCHEDULER_add_now (&stream_write_task, peer); +} + + +/** + * Input processor + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param data traffic from the other side + * @param size the number of bytes available in data read + * @return number of bytes of processed from 'data' (any data remaining should be + * given to the next time the read processor is called). + */ +static size_t +input_processor (void *cls, + enum GNUNET_STREAM_Status status, + const void *input_data, + size_t size) +{ + struct PeerData *peer; + + peer = (struct PeerData *) cls; + + switch (current_test) + { + case PEER1_WRITE: + case PEER1_HALFCLOSE_READ: + if (GNUNET_STREAM_TIMEOUT == status) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Read operation timedout - reading again!\n"); + GNUNET_assert (0 == size); + GNUNET_SCHEDULER_add_now (&stream_read_task, peer); + return 0; + } + + GNUNET_assert (GNUNET_STREAM_OK == status); + GNUNET_assert (size <= strlen (data)); + GNUNET_assert (0 == strncmp ((const char *) data + peer->bytes_read, + (const char *) input_data, + size)); + peer->bytes_read += size; + + if (peer->bytes_read < strlen (data)) + { + GNUNET_SCHEDULER_add_now (&stream_read_task, peer); + } + else + { + if (&peer2 == peer) /* Peer2 has completed reading; should write */ + { + peer2.test_ok = GNUNET_YES; + transition (); /* Transition to PEER1_WRITE_SHUTDOWN */ + } + else /* Peer1 has completed reading. End of tests */ + { + peer1.test_ok = GNUNET_YES; + transition (); /* to PEER1_HALFCLOSE_WRITE_FAIL */ + } + } + break; + case PEER1_WRITE_SHUTDOWN: + GNUNET_assert (GNUNET_STREAM_SHUTDOWN == status); + peer2.test_ok = GNUNET_YES; + break; + case PEER1_HALFCLOSE_WRITE_FAIL: + case PEER1_READ_SHUTDOWN: + case SUCCESS: + GNUNET_assert (0); /* We shouldn't reach here */ + } + + return size; +} + + +/** + * Scheduler call back; to be executed when a new stream is connected + * Called from listen connect for peer2 + */ +static void +stream_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + read_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_assert (NULL != cls); + peer2.bytes_read = 0; + GNUNET_SCHEDULER_add_now (&stream_read_task, &peer2); +} + + +/** + * Functions of this type are called upon new stream connection from other peers + * + * @param cls the closure from GNUNET_STREAM_listen + * @param socket the socket representing the stream + * @param initiator the identity of the peer who wants to establish a stream + * with us + * @return GNUNET_OK to keep the socket open, GNUNET_SYSERR to close the + * stream (the socket will be invalid after the call) + */ +static int +stream_listen_cb (void *cls, + struct GNUNET_STREAM_Socket *socket, + const struct GNUNET_PeerIdentity *initiator) +{ + GNUNET_assert (NULL != socket); + GNUNET_assert (NULL != initiator); + GNUNET_assert (socket != peer1.socket); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s: Peer connected: %s\n", + GNUNET_i2s (&peer2.our_id), + GNUNET_i2s(initiator)); + + peer2.socket = socket; + /* FIXME: reading should be done right now instead of a scheduled call */ + read_task = GNUNET_SCHEDULER_add_now (&stream_read, (void *) socket); + return GNUNET_OK; +} + + +/** + * Callback to be called when testing peer group is ready + * + * @param cls NULL + * @param emsg NULL on success + */ +void +peergroup_ready (void *cls, const char *emsg) +{ + if (NULL != emsg) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Starting peer group failed: %s\n", emsg); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer group is now ready\n"); + + GNUNET_assert (2 == GNUNET_TESTING_daemons_running (pg)); + + d1 = GNUNET_TESTING_daemon_get (pg, 0); + GNUNET_assert (NULL != d1); + + d2 = GNUNET_TESTING_daemon_get (pg, 1); + GNUNET_assert (NULL != d2); + + GNUNET_TESTING_get_peer_identity (d1->cfg, + &peer1.our_id); + GNUNET_TESTING_get_peer_identity (d2->cfg, + &peer2.our_id); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s : %s\n", + GNUNET_i2s (&peer1.our_id), + GNUNET_i2s (&d1->id)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s : %s\n", + GNUNET_i2s (&peer2.our_id), + GNUNET_i2s (&d2->id)); + + peer2_listen_socket = GNUNET_STREAM_listen (d2->cfg, + 10, /* App port */ + &stream_listen_cb, + NULL); + GNUNET_assert (NULL != peer2_listen_socket); + + /* Connect to stream library */ + peer1.socket = GNUNET_STREAM_open (d1->cfg, + &d2->id, /* Null for local peer? */ + 10, /* App port */ + &stream_open_cb, + &peer1, + GNUNET_STREAM_OPTION_END); + GNUNET_assert (NULL != peer1.socket); +} + + +/** + * Initialize framework and start test + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_TESTING_Host *hosts; /* FIXME: free hosts (DLL) */ + + /* GNUNET_log_setup ("test_stream_local", */ + /* "DEBUG", */ + /* NULL); */ + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting test\n"); + /* Duplicate the configuration */ + config = GNUNET_CONFIGURATION_dup (cfg); + + hosts = GNUNET_TESTING_hosts_load (config); + + pg = GNUNET_TESTING_peergroup_start (config, + 2, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 3), + NULL, + &peergroup_ready, + NULL, + hosts); + GNUNET_assert (NULL != pg); + + abort_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 40), &do_abort, + NULL); +} + +/** + * Main function + */ +int main (int argc, char **argv) +{ + int ret; + + char *argv2[] = { "test-stream-2peers-halfclose", + "-L", "DEBUG", + "-c", "test_stream_local.conf", + NULL}; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + ret = + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test-stream-2peers-halfclose", "nohelp", options, &run, NULL); + + if (GNUNET_OK != ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", + ret); + return 1; + } + if (GNUNET_SYSERR == result) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); + return 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test ok\n"); + return 0; +} diff --git a/src/stream/test_stream_local.c b/src/stream/test_stream_local.c index 4da1258..c9fab84 100644 --- a/src/stream/test_stream_local.c +++ b/src/stream/test_stream_local.c @@ -30,6 +30,7 @@ #include "gnunet_util_lib.h" #include "gnunet_mesh_service.h" #include "gnunet_stream_lib.h" +#include "gnunet_testing_lib.h" #define VERBOSE 1 @@ -44,9 +45,14 @@ struct PeerData struct GNUNET_STREAM_Socket *socket; /** - * Peer's io handle + * Peer's io write handle */ - struct GNUNET_STREAM_IOHandle *io_handle; + struct GNUNET_STREAM_IOWriteHandle *io_write_handle; + + /** + * Peer's io read handle + */ + struct GNUNET_STREAM_IOReadHandle *io_read_handle; /** * Bytes the peer has written @@ -63,14 +69,92 @@ static struct GNUNET_OS_Process *arm_pid; static struct PeerData peer1; static struct PeerData peer2; static struct GNUNET_STREAM_ListenSocket *peer2_listen_socket; +static struct GNUNET_CONFIGURATION_Handle *config_peer1; +static struct GNUNET_CONFIGURATION_Handle *config_peer2; static GNUNET_SCHEDULER_TaskIdentifier abort_task; static GNUNET_SCHEDULER_TaskIdentifier test_task; -static GNUNET_SCHEDULER_TaskIdentifier read_task; static char *data = "ABCD"; static int result; +static int writing_success; +static int reading_success; + +/** + * Input processor + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param data traffic from the other side + * @param size the number of bytes available in data read + * @return number of bytes of processed from 'data' (any data remaining should be + * given to the next time the read processor is called). + */ +static size_t +input_processor (void *cls, + enum GNUNET_STREAM_Status status, + const void *input_data, + size_t size); + +/** + * Task for calling STREAM_read + * + * @param cls the peer data entity + * @param tc the task context + */ +static void +stream_read_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerData *peer = cls; + + peer->io_read_handle = GNUNET_STREAM_read (peer->socket, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 5), + &input_processor, + peer); + GNUNET_assert (NULL != peer->io_read_handle); +} + +/** + * The write completion function; called upon writing some data to stream or + * upon error + * + * @param cls the closure from GNUNET_STREAM_write/read + * @param status the status of the stream at the time this function is called + * @param size the number of bytes read or written + */ +static void +write_completion (void *cls, + enum GNUNET_STREAM_Status status, + size_t size); + + +/** + * Task for calling STREAM_write + * + * @param cls the peer data entity + * @param tc the task context + */ +static void +stream_write_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerData *peer = cls; + + peer->io_write_handle = + GNUNET_STREAM_write (peer->socket, + (void *) data, + strlen(data) - peer->bytes_wrote, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 5), + &write_completion, + peer); + + GNUNET_assert (NULL != peer->io_write_handle); + } + /** * Shutdown nicely */ @@ -78,7 +162,10 @@ static void do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_STREAM_close (peer1.socket); - GNUNET_STREAM_close (peer2.socket); + if (NULL != peer2.socket) + GNUNET_STREAM_close (peer2.socket); + if (NULL != peer2_listen_socket) + GNUNET_STREAM_listen_close (peer2_listen_socket); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n"); if (0 != abort_task) { @@ -90,8 +177,11 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n"); + /* Free the duplicated configuration */ + GNUNET_CONFIGURATION_destroy (config_peer1); + GNUNET_CONFIGURATION_destroy (config_peer2); GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid)); - GNUNET_OS_process_close (arm_pid); + GNUNET_OS_process_destroy (arm_pid); } @@ -106,10 +196,7 @@ do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_SCHEDULER_cancel (test_task); } - if (0 != read_task) - { - GNUNET_SCHEDULER_cancel (read_task); - } + result = GNUNET_SYSERR; abort_task = 0; do_shutdown (cls, tc); @@ -129,35 +216,31 @@ write_completion (void *cls, enum GNUNET_STREAM_Status status, size_t size) { - struct PeerData *peer; + struct PeerData *peer=cls; - peer = (struct PeerData *) cls; GNUNET_assert (GNUNET_STREAM_OK == status); - GNUNET_assert (size < strlen (data)); + GNUNET_assert (size <= strlen (data)); peer->bytes_wrote += size; if (peer->bytes_wrote < strlen(data)) /* Have more data to send */ { - peer->io_handle = GNUNET_STREAM_write (peer->socket, - (void *) data, - strlen(data) - peer->bytes_wrote, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), - &write_completion, - cls); - GNUNET_assert (NULL != peer->io_handle); + GNUNET_SCHEDULER_add_now (&stream_write_task, peer); } else { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Writing completed\n"); + if (&peer1 == peer) /* Peer1 has finished writing; should read now */ { - peer->io_handle = GNUNET_STREAM_read ((struct GNUNET_STREAM_Socket *) - peer->socket, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), - &input_processor, - cls); - GNUNET_assert (NULL!=peer->io_handle); + peer->bytes_read = 0; + GNUNET_SCHEDULER_add_now (&stream_read_task, peer); + } + else + { + writing_success = GNUNET_YES; + if (GNUNET_YES == reading_success) + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); } } } @@ -173,20 +256,15 @@ static void stream_open_cb (void *cls, struct GNUNET_STREAM_Socket *socket) { - struct PeerData *peer; + struct PeerData *peer=cls; - peer = (struct PeerData *) cls; - peer->bytes_wrote = 0; + GNUNET_assert (&peer1 == peer); GNUNET_assert (socket == peer1.socket); GNUNET_assert (socket == peer->socket); - peer->io_handle = GNUNET_STREAM_write (peer->socket, /* socket */ - (void *) data, /* data */ - strlen(data), - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), - &write_completion, - cls); - GNUNET_assert (NULL != peer->io_handle); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stream established from peer1\n"); + peer->bytes_wrote = 0; + GNUNET_SCHEDULER_add_now (&stream_write_task, peer); } @@ -206,74 +284,41 @@ input_processor (void *cls, const void *input_data, size_t size) { - struct PeerData *peer; + struct PeerData *peer = cls; - peer = (struct PeerData *) cls; - - GNUNET_assert (GNUNET_STERAM_OK == status); - GNUNET_assert (size < strlen (data)); - GNUNET_assert (strncmp ((const char *) data + peer->bytes_read, - (const char *) input_data, - size)); + GNUNET_assert (GNUNET_STREAM_OK == status); + GNUNET_assert (size <= strlen (data)); + GNUNET_assert (0 == strncmp ((const char *) data + peer->bytes_read, + (const char *) input_data, + size)); peer->bytes_read += size; if (peer->bytes_read < strlen (data)) { - peer->io_handle = GNUNET_STREAM_read ((struct GNUNET_STREAM_Socket *) - peer->socket, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), - &input_processor, - cls); - GNUNET_assert (NULL != peer->io_handle); + GNUNET_SCHEDULER_add_now (&stream_read_task, peer); } else { if (&peer2 == peer) /* Peer2 has completed reading; should write */ { peer->bytes_wrote = 0; - peer->io_handle = GNUNET_STREAM_write ((struct GNUNET_STREAM_Socket *) - peer->socket, - (void *) data, - strlen(data), - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), - &write_completion, - cls); + GNUNET_SCHEDULER_add_now (&stream_write_task, peer); } else /* Peer1 has completed reading. End of tests */ { - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + reading_success = GNUNET_YES; + if (GNUNET_YES == writing_success) + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); } } return size; } -/** - * Scheduler call back; to be executed when a new stream is connected - * Called from listen connect for peer2 - */ -static void -stream_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - read_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_assert (NULL != cls); - peer2.bytes_read = 0; - GNUNET_STREAM_listen_close (peer2_listen_socket); /* Close listen socket */ - peer2.io_handle = GNUNET_STREAM_read ((struct GNUNET_STREAM_Socket *) cls, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), - &input_processor, - (void *) &peer2); - GNUNET_assert (NULL != peer2.io_handle); -} - - /** * Functions of this type are called upon new stream connection from other peers * - * @param cls the closure from GNUNET_STREAM_listen + * @param cls the PeerData of peer2 * @param socket the socket representing the stream * @param initiator the identity of the peer who wants to establish a stream * with us @@ -285,35 +330,60 @@ stream_listen_cb (void *cls, struct GNUNET_STREAM_Socket *socket, const struct GNUNET_PeerIdentity *initiator) { + struct PeerData *peer=cls; + struct GNUNET_PeerIdentity self; + GNUNET_assert (NULL != socket); - GNUNET_assert (NULL == initiator); /* Local peer=NULL? */ GNUNET_assert (socket != peer1.socket); + GNUNET_assert (&peer2 == peer); + + /* Get our identity */ + GNUNET_assert (GNUNET_OK == GNUNET_TESTING_get_peer_identity (config_peer1, + &self)); + GNUNET_assert (0 == memcmp (&self, + initiator, + sizeof (struct GNUNET_PeerIdentity))); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer connected: %s\n", GNUNET_i2s(initiator)); - peer2.socket = socket; - read_task = GNUNET_SCHEDULER_add_now (&stream_read, (void *) socket); + peer->socket = socket; + peer->bytes_read = 0; + GNUNET_SCHEDULER_add_now (&stream_read_task, &peer2); return GNUNET_OK; } /** * Testing function + * + * @param cls NULL + * @param tc the task context */ static void test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + struct GNUNET_PeerIdentity self; + test_task = GNUNET_SCHEDULER_NO_TASK; + /* Get our identity */ + GNUNET_assert (GNUNET_OK == GNUNET_TESTING_get_peer_identity (config_peer1, + &self)); + + peer2_listen_socket = GNUNET_STREAM_listen (config_peer2, + 10, /* App port */ + &stream_listen_cb, + &peer2); + GNUNET_assert (NULL != peer2_listen_socket); /* Connect to stream library */ - peer1.socket = GNUNET_STREAM_open (NULL, /* Null for local peer? */ + peer1.socket = GNUNET_STREAM_open (config_peer1, + &self, /* Null for local peer? */ 10, /* App port */ &stream_open_cb, - (void *) &peer1); + &peer1, + GNUNET_STREAM_OPTION_END); GNUNET_assert (NULL != peer1.socket); - peer2_listen_socket = GNUNET_STREAM_listen (10 /* App port */ - &stream_listen_cb, - NULL); - GNUNET_assert (NULL != peer2_listen_socket); - } /** @@ -330,6 +400,9 @@ run (void *cls, char *const *args, const char *cfgfile, "WARNING", #endif NULL); + /* Duplicate the configuration */ + config_peer1 = GNUNET_CONFIGURATION_dup (cfg); + config_peer2 = GNUNET_CONFIGURATION_dup (cfg); arm_pid = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", @@ -340,11 +413,10 @@ run (void *cls, char *const *args, const char *cfgfile, abort_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort, + (GNUNET_TIME_UNIT_SECONDS, 60), &do_abort, NULL); - - test_task = GNUNET_SCHEDULER_add_now (&test, (void *) cfg); - + + test_task = GNUNET_SCHEDULER_add_now (&test, NULL); } /** @@ -355,7 +427,7 @@ int main (int argc, char **argv) int ret; char *const argv2[] = { "test-stream-local", - "-c", "test_stream.conf", + "-c", "test_stream_local.conf", #if VERBOSE "-L", "DEBUG", #endif @@ -365,7 +437,7 @@ int main (int argc, char **argv) struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; - + ret = GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, "test-stream-local", "nohelp", options, &run, NULL); @@ -381,6 +453,6 @@ int main (int argc, char **argv) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); return 1; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test ok\n"); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test ok\n"); return 0; } diff --git a/src/stream/test_stream_local.conf b/src/stream/test_stream_local.conf index 3d955f0..884ecbc 100644 --- a/src/stream/test_stream_local.conf +++ b/src/stream/test_stream_local.conf @@ -9,7 +9,7 @@ DEBUG = YES AUTOSTART = YES ACCEPT_FROM = 127.0.0.1; HOSTNAME = localhost -PORT = 10511 +PORT = 10700 # PREFIX = valgrind --leak-check=full # PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args @@ -19,7 +19,7 @@ AUTOSTART = YES ACCEPT_FROM6 = ::1; ACCEPT_FROM = 127.0.0.1; HOSTNAME = localhost -PORT = 2100 +PORT = 12100 [block] plugins = dht test @@ -53,14 +53,20 @@ TIMEOUT = 300 s PORT = 12368 [TESTING] +NUM_PEERS = 5 WEAKRANDOM = YES +DEBUG = YES +HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat +MAX_CONCURRENT_SSH = 10 +USE_PROGRESSBARS = YES +PEERGROUP_TIMEOUT = 2400 s [gnunetd] HOSTKEY = $SERVICEHOME/.hostkey [PATHS] -DEFAULTCONFIG = test_mesh.conf -SERVICEHOME = /tmp/test-mesh/ +DEFAULTCONFIG = test_stream_local.conf +SERVICEHOME = /tmp/test-stream/ [dns] AUTOSTART = NO diff --git a/src/template/Makefile.in b/src/template/Makefile.in index de11cdc..8f8c858 100644 --- a/src/template/Makefile.in +++ b/src/template/Makefile.in @@ -195,6 +195,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -228,6 +229,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am new file mode 100644 index 0000000..b7b9360 --- /dev/null +++ b/src/testbed/Makefile.am @@ -0,0 +1,39 @@ +INCLUDES = -I$(top_srcdir)/src/include + +if MINGW + WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +endif + +if USE_COVERAGE + AM_CFLAGS = --coverage -O0 + XLIB = -lgcov +endif + +pkgcfgdir= $(pkgdatadir)/config.d/ + +dist_pkgcfg_DATA = \ + testbed.conf + +lib_LTLIBRARIES = \ + libgnunettestbed.la + +libgnunettestbed_la_SOURCES = \ + testbed_api.c testbed.h \ + testbed_api_hosts.c testbed_api_hosts.h \ + testbed_api_operations.c testbed_api_operations.h \ + testbed_api_peers.c testbed_api_peers.h \ + testbed_api_services.c \ + testbed_api_testbed.c \ + testbed_api_test.c \ + testbed_api_topology.c +libgnunettestbed_la_LIBADD = $(XLIB) \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + -lm \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunettestbed_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + diff --git a/src/testbed/Makefile.in b/src/testbed/Makefile.in new file mode 100644 index 0000000..3b08315 --- /dev/null +++ b/src/testbed/Makefile.in @@ -0,0 +1,713 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/testbed +DIST_COMMON = $(dist_pkgcfg_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ + $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ + $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/gnunet_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgcfgdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libgnunettestbed_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_libgnunettestbed_la_OBJECTS = testbed_api.lo testbed_api_hosts.lo \ + testbed_api_operations.lo testbed_api_peers.lo \ + testbed_api_services.lo testbed_api_testbed.lo \ + testbed_api_test.lo testbed_api_topology.lo +libgnunettestbed_la_OBJECTS = $(am_libgnunettestbed_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libgnunettestbed_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libgnunettestbed_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libgnunettestbed_la_SOURCES) +DIST_SOURCES = $(libgnunettestbed_la_SOURCES) +DATA = $(dist_pkgcfg_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_INTERFACE = @DEFAULT_INTERFACE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLDIR = @DLLDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXT_LIBS = @EXT_LIBS@ +EXT_LIB_PATH = @EXT_LIB_PATH@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ +GN_DAEMON_CONFIG_DIR = @GN_DAEMON_CONFIG_DIR@ +GN_DAEMON_HOME_DIR = @GN_DAEMON_HOME_DIR@ +GN_INTLINCL = @GN_INTLINCL@ +GN_LIBINTL = @GN_LIBINTL@ +GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ +GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ +GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GREP = @GREP@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBPREFIX = @LIBPREFIX@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNISTRING = @LIBUNISTRING@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ +POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CPPFLAGS = @SQLITE_CPPFLAGS@ +SQLITE_LDFLAGS = @SQLITE_LDFLAGS@ +STRIP = @STRIP@ +SUDO_BINARY = @SUDO_BINARY@ +UNIXONLY = @UNIXONLY@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_OBJC = @ac_ct_OBJC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_target = @build_target@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/src/include +@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0 +@USE_COVERAGE_TRUE@XLIB = -lgcov +pkgcfgdir = $(pkgdatadir)/config.d/ +dist_pkgcfg_DATA = \ + testbed.conf + +lib_LTLIBRARIES = \ + libgnunettestbed.la + +libgnunettestbed_la_SOURCES = \ + testbed_api.c testbed.h \ + testbed_api_hosts.c testbed_api_hosts.h \ + testbed_api_operations.c testbed_api_operations.h \ + testbed_api_peers.c testbed_api_peers.h \ + testbed_api_services.c \ + testbed_api_testbed.c \ + testbed_api_test.c \ + testbed_api_topology.c + +libgnunettestbed_la_LIBADD = $(XLIB) \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + -lm \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunettestbed_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/testbed/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/testbed/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgnunettestbed.la: $(libgnunettestbed_la_OBJECTS) $(libgnunettestbed_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunettestbed_la_LINK) -rpath $(libdir) $(libgnunettestbed_la_OBJECTS) $(libgnunettestbed_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbed_api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbed_api_hosts.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbed_api_operations.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbed_api_peers.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbed_api_services.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbed_api_test.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbed_api_testbed.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbed_api_topology.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_pkgcfgDATA: $(dist_pkgcfg_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" + @list='$(dist_pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcfgdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcfgdir)" || exit $$?; \ + done + +uninstall-dist_pkgcfgDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgcfgdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_pkgcfgDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_pkgcfgDATA uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-dist_pkgcfgDATA install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-dist_pkgcfgDATA \ + uninstall-libLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/testbed/testbed.conf b/src/testbed/testbed.conf new file mode 100644 index 0000000..e69de29 diff --git a/src/testbed/testbed.h b/src/testbed/testbed.h new file mode 100644 index 0000000..b7b10ff --- /dev/null +++ b/src/testbed/testbed.h @@ -0,0 +1,535 @@ +/* + This file is part of GNUnet + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed.h + * @brief IPC messages between testing API and service ("controller") + * @author Christian Grothoff + */ + +#ifndef NEW_TESTING_H +#define NEW_TESTING_H + +#include "gnunet_util_lib.h" + + +/** + * Initial message from a client to a testing control service. + */ +struct GNUNET_TESTBED_Message +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Host ID that the controller is either given + * (if this is the dominating client communicating + * via stdin) or assumed to have (for peer-connections + * between controllers). + */ + uint32_t host_id GNUNET_PACKED; + + /** + * Event mask that specifies which events this client + * is interested in. In NBO. + */ + uint64_t event_mask GNUNET_PACKED; + +}; + + +/** + * Notify the service about a host that we intend to use. + */ +struct GNUNET_TESTBED_AddHostMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Unique ID for the host (in NBO). + */ + uint32_t host_id GNUNET_PACKED; + + /** + * SSH port to use, 0 for default (in NBO). + */ + uint16_t ssh_port GNUNET_PACKED; + + /** + * Number of bytes in the user name that follows; + * 0 to use no user name; otherwise 'strlen (username)', + * excluding 0-termination! + */ + uint16_t user_name_length GNUNET_PACKED; + + /* followed by 0-terminated user name */ + + /* followed by 0-terminated host name */ + +}; + + +/** + * Confirmation from the service that adding a host + * worked (or failed). + */ +struct GNUNET_TESTBED_HostConfirmedMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Unique ID for the host (in NBO). + */ + uint32_t host_id GNUNET_PACKED; + + /* followed by the 0-terminated error message (on failure) + (typical errors include failure to login and + host-id already in use) */ + +}; + + +/** + * Message to testing service: configure service sharing + * at a host. + */ +struct GNUNET_TESTBED_ConfigureSharedServiceMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Host that is being configured. + */ + uint32_t host_id GNUNET_PACKED; + + /** + * Number of peers that should share a service instance; + * 1 for no sharing, 0 to forcefully disable the service. + */ + uint32_t num_peers GNUNET_PACKED; + + /* followed by 0-terminated name of the service */ + +}; + + +/** + * Client notifies controller that it should delegate + * requests for a particular client to a particular + * sub-controller. + */ +struct GNUNET_TESTBED_ControllerLinkMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * For which host should requests be delegated? NBO. + */ + uint32_t delegated_host_id GNUNET_PACKED; + + /** + * Which host is responsible for managing the delegation? NBO + */ + uint32_t slave_host_id GNUNET_PACKED; + + /** + * Is the receiving controller the master controller for + * the slave host (and thus responsible for starting it?). NBO. + */ + int32_t is_subordinate GNUNET_PACKED; + + /* followed by serialized slave configuration; + gzip'ed configuration file in INI format */ + +}; + + +/** + * Message sent from client to testing service to + * create (configure, but not start) a peer. + */ +struct GNUNET_TESTBED_PeerCreateMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * On which host should the peer be started? + */ + uint32_t host_id GNUNET_PACKED; + + /** + * Unique ID for the peer. + */ + uint32_t peer_id GNUNET_PACKED; + + /* followed by serialized peer configuration; + gzip'ed configuration file in INI format */ + +}; + + +/** + * Message sent from client to testing service to + * reconfigure a (stopped) a peer. + */ +struct GNUNET_TESTBED_PeerReconfigureMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Unique ID for the peer. + */ + uint32_t peer_id GNUNET_PACKED; + + /** + * Operation ID that is used to identify this operation. + */ + uint64_t operation_id GNUNET_PACKED; + + /* followed by serialized peer configuration; + gzip'ed configuration file in INI format */ + +}; + + +/** + * Message sent from client to testing service to + * start a peer. + */ +struct GNUNET_TESTBED_PeerStartMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Unique ID for the peer. + */ + uint32_t peer_id GNUNET_PACKED; + + /** + * Operation ID that is used to identify this operation. + */ + uint64_t operation_id GNUNET_PACKED; + +}; + + +/** + * Message sent from client to testing service to + * stop a peer. + */ +struct GNUNET_TESTBED_PeerStopMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Unique ID for the peer. + */ + uint32_t peer_id GNUNET_PACKED; + + /** + * Operation ID that is used to identify this operation. + */ + uint64_t operation_id GNUNET_PACKED; + +}; + + +/** + * Message sent from client to testing service to + * destroy a (stopped) peer. + */ +struct GNUNET_TESTBED_PeerDestroyMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Unique ID for the peer. + */ + uint32_t peer_id GNUNET_PACKED; + + /** + * Operation ID that is used to identify this operation. + */ + uint64_t operation_id GNUNET_PACKED; + +}; + + +/** + * Message sent from client to testing service to + * (re)configure a "physical" link between two peers. + */ +struct GNUNET_TESTBED_ConfigureUnderlayLinkMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * 'enum GNUNET_TESTBED_ConnectOption' of the option to change + */ + int32_t connect_option GNUNET_PACKED; + + /** + * Unique ID for the first peer. + */ + uint32_t peer1 GNUNET_PACKED; + + /** + * Unique ID for the second peer. + */ + uint32_t peer2 GNUNET_PACKED; + + /** + * Operation ID that is used to identify this operation. + */ + uint64_t operation_id GNUNET_PACKED; + + /* followed by option-dependent variable-size values */ + +}; + + +/** + * Message sent from client to testing service to + * connect two peers. + */ +struct GNUNET_TESTBED_OverlayConnectMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Unique ID for the first peer. + */ + uint32_t peer1 GNUNET_PACKED; + + /** + * Operation ID that is used to identify this operation. + */ + uint64_t operation_id GNUNET_PACKED; + + /** + * Unique ID for the second peer. + */ + uint32_t peer2 GNUNET_PACKED; + +}; + + +/** + * Event notification from a controller to a client. + */ +struct GNUNET_TESTBED_PeerEventMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * 'enum GNUNET_TESTBED_EventType' (in NBO); + * either GNUNET_TESTBED_ET_PEER_START or GNUNET_TESTBED_ET_PEER_STOP. + */ + int32_t event_type GNUNET_PACKED; + + /** + * Host where the peer is running. + */ + uint32_t host_id GNUNET_PACKED; + + /** + * Peer that was started or stopped. + */ + uint32_t peer_id GNUNET_PACKED; + + /** + * Operation ID that is used to identify this operation. + */ + uint64_t operation_id GNUNET_PACKED; + +}; + + +/** + * Event notification from a controller to a client. + */ +struct GNUNET_TESTBED_ConnectionEventMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * 'enum GNUNET_TESTBED_EventType' (in NBO); + * either GNUNET_TESTBED_ET_PEER_CONNECT or GNUNET_TESTBED_ET_PEER_DISCONNECT. + */ + int32_t event_type GNUNET_PACKED; + + /** + * First peer. + */ + uint32_t peer1 GNUNET_PACKED; + + /** + * Second peer. + */ + uint32_t peer2 GNUNET_PACKED; + + /** + * Operation ID that is used to identify this operation. + */ + uint64_t operation_id GNUNET_PACKED; + +}; + + +/** + * Event notification from a controller to a client. + */ +struct GNUNET_TESTBED_OperationFailureEventMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * 'enum GNUNET_TESTBED_EventType' (in NBO); + * GNUNET_TESTBED_ET_OPERATION_FINISHED. + */ + int32_t event_type GNUNET_PACKED; + + /** + * Operation ID of the operation that created this event. + */ + uint64_t operation_id GNUNET_PACKED; + + /* followed by 0-terminated error message */ + +}; + + +/** + * Event notification from a controller to a client. + */ +struct GNUNET_TESTBED_PeerCreateSuccessEventMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * Peer identity of the peer that was created. + */ + uint32_t peer_id GNUNET_PACKED; + + /** + * Operation ID of the operation that created this event. + */ + uint64_t operation_id GNUNET_PACKED; + + /** + * Identity of the peer. + */ + struct GNUNET_PeerIdentity peer_id; + + /* followed by gzip-compressed configuration of the peer */ + +}; + + +/** + * Event notification from a controller to a client for + * a generic operational success where the operation does + * not return any data. + */ +struct GNUNET_TESTBED_GenericOperationSuccessEventMessage +{ + + /** + * Type is + */ + struct GNUNET_MessageHeader header; + + /** + * 'enum GNUNET_TESTBED_EventType' (in NBO); + * GNUNET_TESTBED_ET_OPERATION_FINISHED. + */ + int32_t event_type GNUNET_PACKED; + + /** + * Operation ID of the operation that created this event. + */ + uint64_t operation_id GNUNET_PACKED; + +}; + +#endif diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c new file mode 100644 index 0000000..5168081 --- /dev/null +++ b/src/testbed/testbed_api.c @@ -0,0 +1,150 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api.c + * @brief API for accessing the GNUnet testing service. + * This library is supposed to make it easier to write + * testcases and script large-scale benchmarks. + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_testbed_service.h" +#include "gnunet_core_service.h" +#include "gnunet_constants.h" +#include "gnunet_transport_service.h" +#include "gnunet_hello_lib.h" + + + + +/** + * Start a controller process using the given configuration at the + * given host. + * + * @param cfg configuration to use + * @param host host to run the controller on, NULL for 'localhost' + * @param event_mask bit mask with set of events to call 'cc' for; + * or-ed values of "1LL" shifted by the + * respective 'enum GNUNET_TESTBED_EventType' + * (i.e. "(1LL << GNUNET_TESTBED_ET_CONNECT) | ...") + * @param cc controller callback to invoke on events + * @param cc_cls closure for cc + * @return handle to the controller + */ +struct GNUNET_TESTBED_Controller * +GNUNET_TESTBED_controller_start (const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTBED_Host *host, + uint64_t event_mask, + GNUNET_TESTBED_ControllerCallback cc, + void *cc_cls) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Configure shared services at a controller. Using this function, + * you can specify that certain services (such as "resolver") + * should not be run for each peer but instead be shared + * across N peers on the specified host. This function + * must be called before any peers are created at the host. + * + * @param controller controller to configure + * @param service_name name of the service to share + * @param num_peers number of peers that should share one instance + * of the specified service (1 for no sharing is the default), + * use 0 to disable the service + */ +void +GNUNET_TESTBED_controller_configure_sharing (struct GNUNET_TESTBED_Controller *controller, + const char *service_name, + uint32_t num_peers) +{ + GNUNET_break (0); +} + + +/** + * Stop the given controller (also will terminate all peers and + * controllers dependent on this controller). This function + * blocks until the testbed has been fully terminated (!). + * + * @param controller handle to controller to stop + */ +void +GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_Controller *controller) +{ + GNUNET_break (0); +} + + +/** + * Create a link from a 'master' controller to a slave controller. + * Whenever the master controller is asked to start a peer at the + * given 'delegated_host', it will delegate the request to the + * specified slave controller. Note that the slave controller runs at + * the 'slave_host', which may or may not be the same host as the + * 'delegated_host' (for hierarchical delegations). The configuration + * of the slave controller is given and to be used to either create + * the slave controller or to connect to an existing slave controller + * process. 'is_subordinate' specifies if the given slave controller + * should be started and managed by the master controller, or if the + * slave already has a master and this is just a secondary master that + * is also allowed to use the existing slave. + * + * @param master handle to the master controller who creates the association + * @param delegated_host requests to which host should be delegated + * @param slave_host which host is used to run the slave controller + * @param slave_cfg configuration to use for the slave controller + * @param is_subordinate GNUNET_YES if the slave should be started (and stopped) + * by the master controller; GNUNET_NO if we are just + * allowed to use the slave via TCP/IP + */ +void +GNUNET_TESTBED_controller_link (struct GNUNET_TESTBED_Controller *master, + struct GNUNET_TESTBED_Host *delegated_host, + struct GNUNET_TESTBED_Host *slave_host, + const struct GNUNET_CONFIGURATION_Handle *slave_cfg, + int is_subordinate) +{ + GNUNET_break (0); +} + + +/** + * Ask the testbed controller to write the current overlay topology to + * a file. Naturally, the file will only contain a snapshot as the + * topology may evolve all the time. + * + * @param controller overlay controller to inspect + * @param filename name of the file the topology should + * be written to. + */ +void +GNUNET_TESTBED_overlay_write_topology_to_file (struct GNUNET_TESTBED_Controller *controller, + const char *filename) +{ +} + + + +/* end of testbed_api.c */ diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c new file mode 100644 index 0000000..1b293b3 --- /dev/null +++ b/src/testbed/testbed_api_hosts.c @@ -0,0 +1,200 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_hosts.c + * @brief API for manipulating 'hosts' controlled by the GNUnet testing service; + * allows parsing hosts files, starting, stopping and communicating (via + * SSH/stdin/stdout) with the remote (or local) processes + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_testbed_service.h" +#include "gnunet_core_service.h" +#include "gnunet_constants.h" +#include "gnunet_transport_service.h" +#include "gnunet_hello_lib.h" + + + +/** + * Opaque handle to a host running experiments managed by the testing framework. + * The master process must be able to SSH to this host without password (via + * ssh-agent). + */ +struct GNUNET_TESTBED_Host +{ + + + const char *hostname; + + const char *username; + + /** + * Global ID we use to refer to a host on the network + */ + uint32_t unique_id; + + uint16_t port; +}; + + +/** + * Lookup a host by ID. + * + * @param id global host ID assigned to the host; 0 is + * reserved to always mean 'localhost' + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Host * +GNUNET_TESTBED_host_lookup_by_id_ (uint32_t id) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Create a host by ID; given this host handle, we could not + * run peers at the host, but we can talk about the host + * internally. + * + * @param id global host ID assigned to the host; 0 is + * reserved to always mean 'localhost' + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Host * +GNUNET_TESTBED_host_create_by_id_ (uint32_t id) +{ + return NULL; +} + + +/** + * Obtain a host's unique global ID. + * + * @param host handle to the host, NULL means 'localhost' + * @return id global host ID assigned to the host (0 is + * 'localhost', but then obviously not globally unique) + */ +uint32_t +GNUNET_TESTBED_host_get_id_ (struct GNUNET_TESTBED_Host *host) +{ + GNUNET_break (0); + return 0; +} + + +/** + * Create a host to run peers and controllers on. + * + * @param id global host ID assigned to the host; 0 is + * reserved to always mean 'localhost' + * @param hostname name of the host, use "NULL" for localhost + * @param username username to use for the login; may be NULL + * @param port port number to use for ssh; use 0 to let ssh decide + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Host * +GNUNET_TESTBED_host_create_with_id_ (uint32_t id, + const char *hostname, + const char *username, + uint16_t port) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Create a host to run peers and controllers on. + * + * @param hostname name of the host, use "NULL" for localhost + * @param username username to use for the login; may be NULL + * @param port port number to use for ssh; use 0 to let ssh decide + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Host * +GNUNET_TESTBED_host_create (const char *hostname, + const char *username, + uint16_t port) +{ + static uint32_t uid_generator; + + return GNUNET_TESTBED_host_create_with_id_ (++uid_generator, + hostname, username, + port); +} + + +/** + * Load a set of hosts from a configuration file. + * + * @param filename file with the host specification + * @param hosts set to the hosts found in the file + * @return number of hosts returned in 'hosts', 0 on error + */ +unsigned int +GNUNET_TESTBED_hosts_load_from_file (const char *filename, + struct GNUNET_TESTBED_Host **hosts) +{ + GNUNET_break (0); + return 0; +} + + +/** + * Destroy a host handle. Must only be called once everything + * running on that host has been stopped. + * + * @param host handle to destroy + */ +void +GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host) +{ + GNUNET_break (0); +} + + +/** + * Run a given helper process at the given host. Communication + * with the helper will be via GNUnet messages on stdin/stdout. + * Runs the process via 'ssh' at the specified host, or locally. + * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API. + * + * @param host host to use, use "NULL" for localhost + * @param binary_argv binary name and command-line arguments to give to the binary + * @param cb function to call for messages received from the binary + * @param cb_cls closure for cb + * @return handle to terminate the command, NULL on error + */ +struct GNUNET_HELPER_Handle * +GNUNET_TESTBED_host_run_ (struct GNUNET_TESTBED_Host *host, + char *const binary_argv[], + GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls) +{ + /* FIXME: decide on the SSH command line, prepend it and + run GNUNET_HELPER_start with the modified binary_name and binary_argv! */ + GNUNET_break (0); + return NULL; +} + + +/* end of testbed_api_hosts.c */ diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h new file mode 100644 index 0000000..401d4e0 --- /dev/null +++ b/src/testbed/testbed_api_hosts.h @@ -0,0 +1,105 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_hosts.h + * @brief internal API to access the 'hosts' subsystem + * @author Christian Grothoff + */ +#ifndef NEW_TESTING_API_HOSTS_H +#define NEW_TESTING_API_HOSTS_H + +#include "gnunet_testbed_service.h" +#include "gnunet_helper_lib.h" + + +/** + * Lookup a host by ID. + * + * @param id global host ID assigned to the host; 0 is + * reserved to always mean 'localhost' + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Host * +GNUNET_TESTBED_host_lookup_by_id_ (uint32_t id); + + +/** + * Create a host by ID; given this host handle, we could not + * run peers at the host, but we can talk about the host + * internally. + * + * @param id global host ID assigned to the host; 0 is + * reserved to always mean 'localhost' + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Host * +GNUNET_TESTBED_host_create_by_id_ (uint32_t id); + + +/** + * Create a host to run peers and controllers on. This function is used + * if a peer learns about a host via IPC between controllers (and thus + * some higher-level controller has already determined the unique IDs). + * + * @param id global host ID assigned to the host; 0 is + * reserved to always mean 'localhost' + * @param hostname name of the host, use "NULL" for localhost + * @param username username to use for the login; may be NULL + * @param port port number to use for ssh; use 0 to let ssh decide + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Host * +GNUNET_TESTBED_host_create_with_id_ (uint32_t id, + const char *hostname, + const char *username, + uint16_t port); + + +/** + * Obtain a host's unique global ID. + * + * @param host handle to the host, NULL means 'localhost' + * @return id global host ID assigned to the host (0 is + * 'localhost', but then obviously not globally unique) + */ +uint32_t +GNUNET_TESTBED_host_get_id_ (struct GNUNET_TESTBED_Host *host); + + +/** + * Run a given helper process at the given host. Communication + * with the helper will be via GNUnet messages on stdin/stdout. + * Runs the process via 'ssh' at the specified host, or locally. + * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API. + * + * @param host host to use, use "NULL" for localhost + * @param binary_argv binary name and command-line arguments to give to the binary + * @param cb function to call for messages received from the binary + * @param cb_cls closure for cb + * @return handle to terminate the command, NULL on error + */ +struct GNUNET_HELPER_Handle * +GNUNET_TESTBED_host_run_ (struct GNUNET_TESTBED_Host *host, + char *const binary_argv[], + GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls); + +#endif +/* end of testbed_api_hosts.h */ diff --git a/src/testbed/testbed_api_operations.c b/src/testbed/testbed_api_operations.c new file mode 100644 index 0000000..c98998b --- /dev/null +++ b/src/testbed/testbed_api_operations.c @@ -0,0 +1,194 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_operations.c + * @brief functions to manage operation queues + * @author Christian Grothoff + */ +#include "platform.h" +#include "testbed_api_operations.h" + + +/** + * Opaque handle to an abstract operation to be executed by the testing framework. + */ +struct GNUNET_TESTBED_Operation +{ + /** + * Function to call when we have the resources to begin the operation. + */ + OperationStart start; + + /** + * Function to call to clean up after the operation (which may or may + * not have been started yet). + */ + OperationRelease release; + + /** + * Closure for callbacks. + */ + void *cb_cls; + + // FIXME! + +}; + + +/** + * Queue of operations where we can only support a certain + * number of concurrent operations of a particular type. + */ +struct OperationQueue +{ + + /** + * Maximum number of operationst that can be concurrently + * active in this queue. + */ + unsigned int max_active; + + // FIXME! + +}; + + +/** + * Create an operation queue. + * + * @param max_active maximum number of operations in this + * queue that can be active in parallel at the same time + * @return handle to the queue + */ +struct OperationQueue * +GNUNET_TESTBED_operation_queue_create_ (unsigned int max_active) +{ + struct OperationQueue *queue; + + queue = GNUNET_malloc (sizeof (struct OperationQueue)); + queue->max_active = max_active; + return queue; +} + + +/** + * Destroy an operation queue. The queue MUST be empty + * at this time. + * + * @param queue queue to destroy + */ +void +GNUNET_TESTBED_operation_queue_destroy_ (struct OperationQueue *queue) +{ + GNUNET_break (0); + GNUNET_free (queue); +} + + +/** + * Add an operation to a queue. An operation can be in multiple + * queues at once. Once all queues permit the operation to become + * active, the operation will be activated. The actual activation + * will occur in a separate task (thus allowing multiple queue + * insertions to be made without having the first one instantly + * trigger the operation if the first queue has sufficient + * resources). + * + * @param queue queue to add the operation to + * @param operation operation to add to the queue + */ +void +GNUNET_TESTBED_operation_queue_insert_ (struct OperationQueue *queue, + struct GNUNET_TESTBED_Operation *operation) +{ + GNUNET_break (0); +} + + +/** + * Remove an operation from a queue. This can be because the + * oeration was active and has completed (and the resources have + * been released), or because the operation was cancelled and + * thus scheduling the operation is no longer required. + * + * @param queue queue to add the operation to + * @param operation operation to add to the queue + */ +void +GNUNET_TESTBED_operation_queue_remove_ (struct OperationQueue *queue, + struct GNUNET_TESTBED_Operation *operation) +{ + GNUNET_break (0); +} + + +/** + * An operation is 'done' (was cancelled or finished); remove + * it from the queues and release associated resources. + * + * @param operation operation that finished + */ +static void +operation_release (struct GNUNET_TESTBED_Operation *operation) +{ + // call operation->release, remove from queues + GNUNET_break (0); +} + + +/** + * Cancel a pending operation. Releases all resources + * of the operation and will ensure that no event + * is generated for the operation. Does NOT guarantee + * that the operation will be fully undone (or that + * nothing ever happened). + * + * @param operation operation to cancel + */ +void +GNUNET_TESTBED_operation_cancel (struct GNUNET_TESTBED_Operation *operation) +{ + // test that operation had not yet generated an event + GNUNET_break (0); + operation_release (operation); +} + + +/** + * Signal that the information from an operation has been fully + * processed. This function MUST be called for each event + * of type 'operation_finished' to fully remove the operation + * from the operation queue. After calling this function, the + * 'op_result' becomes invalid (!). + * + * @param operation operation to signal completion for + */ +void +GNUNET_TESTBED_operation_done (struct GNUNET_TESTBED_Operation *operation) +{ + // test that operation was started and had generated an event + GNUNET_break (0); + operation_release (operation); +} + + + +/* end of testbed_api_operations.c */ diff --git a/src/testbed/testbed_api_operations.h b/src/testbed/testbed_api_operations.h new file mode 100644 index 0000000..4c888d5 --- /dev/null +++ b/src/testbed/testbed_api_operations.h @@ -0,0 +1,132 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_operations.h + * @brief internal API to access the 'operations' subsystem + * @author Christian Grothoff + */ +#ifndef NEW_TESTING_API_OPERATIONS_H +#define NEW_TESTING_API_OPERATIONS_H + +#include "gnunet_testbed_service.h" +#include "gnunet_helper_lib.h" + + +/** + * Queue of operations where we can only support a certain + * number of concurrent operations of a particular type. + */ +struct OperationQueue; + + +/** + * Create an operation queue. + * + * @param max_active maximum number of operations in this + * queue that can be active in parallel at the same time + * @return handle to the queue + */ +struct OperationQueue * +GNUNET_TESTBED_operation_queue_create_ (unsigned int max_active); + + +/** + * Destroy an operation queue. The queue MUST be empty + * at this time. + * + * @param queue queue to destroy + */ +void +GNUNET_TESTBED_operation_queue_destroy_ (struct OperationQueue *queue); + + +/** + * Add an operation to a queue. An operation can be in multiple + * queues at once. Once all queues permit the operation to become + * active, the operation will be activated. The actual activation + * will occur in a separate task (thus allowing multiple queue + * insertions to be made without having the first one instantly + * trigger the operation if the first queue has sufficient + * resources). + * + * @param queue queue to add the operation to + * @param operation operation to add to the queue + */ +void +GNUNET_TESTBED_operation_queue_insert_ (struct OperationQueue *queue, + struct GNUNET_TESTBED_Operation *operation); + + +/** + * Remove an operation from a queue. This can be because the + * oeration was active and has completed (and the resources have + * been released), or because the operation was cancelled and + * thus scheduling the operation is no longer required. + * + * @param queue queue to add the operation to + * @param operation operation to add to the queue + */ +void +GNUNET_TESTBED_operation_queue_remove_ (struct OperationQueue *queue, + struct GNUNET_TESTBED_Operation *operation); + + + +/** + * Function to call to start an operation once all + * queues the operation is part of declare that the + * operation can be activated. + */ +typedef void (*OperationStart)(void *cls); + + +/** + * Function to call to cancel an operation (release all associated + * resources). This can be because of a call to + * "GNUNET_TESTBED_operation_cancel" (before the operation generated + * an event) or AFTER the operation generated an event due to a call + * to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that + * a callback to the 'OperationStart' preceeds the call to + * 'OperationRelease'. Implementations of this function are expected + * to clean up whatever state is in 'cls' and release all resources + * associated with the operation. + */ +typedef void (*OperationRelease)(void *cls); + + +/** + * Create an 'operation' to be performed. + * + * @param cls closure for the callbacks + * @param start function to call to start the operation + * @param release function to call to close down the operation + * @param ... FIXME + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_operation_create_ (void *cls, + OperationStart start, + OperationRelease release, + ...); + + +#endif +/* end of testbed_api_operations.h */ diff --git a/src/testbed/testbed_api_peers.c b/src/testbed/testbed_api_peers.c new file mode 100644 index 0000000..7ee0dd1 --- /dev/null +++ b/src/testbed/testbed_api_peers.c @@ -0,0 +1,297 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_peers.c + * @brief management of the knowledge about peers in this library + * (we know the peer ID, its host, pending operations, etc.) + * @author Christian Grothoff + */ +#include "platform.h" +#include "testbed_api_peers.h" + + +/** + * Details about a peer; kept in a separate struct to avoid bloating + * memory consumption everywhere... + */ +struct PeerDetails +{ + /** + * Configuration of the peer; NULL if we are not sure what the peer's correct + * configuration actually is; non-NULL if this peer is controlled by this + * process. + */ + struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * If this process has started this peer's ARM process, this is the handle + * to the 'gnunet-service-arm' process of the peer. + */ + struct GNUNET_OS_Process *arm; + + // ... + +}; + + +/** + * A peer controlled by the testing framework. A peer runs + * at a particular host. + */ +struct GNUNET_TESTBED_Peer +{ + /** + * Our controller context (not necessarily the controller + * that is responsible for starting/running the peer!). + */ + struct GNUNET_TESTBED_Controller *controller; + + /** + * Which host does this peer run on? + */ + struct GNUENT_TESTING_Host *host; + + /** + * Globally unique ID of the peer. + */ + uint32_t unique_id; + + /** + * Internals of the peer for the controlling process; NULL if + * this process is not controlling this peer. + */ + struct PeerDetails *details; + +}; + + +/** + * Lookup a peer by ID. + * + * @param id global peer ID assigned to the peer + * @return handle to the host, NULL on error + */ +struct GNUNET_TESTBED_Peer * +GNUNET_TESTBED_peer_lookup_by_id_ (uint32_t id) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Create the given peer at the specified host using the given + * controller. If the given controller is not running on the target + * host, it should find or create a controller at the target host and + * delegate creating the peer. Explicit delegation paths can be setup + * using 'GNUNET_TESTBED_controller_link'. If no explicit delegation + * path exists, a direct link with a subordinate controller is setup + * for the first delegated peer to a particular host; the subordinate + * controller is then destroyed once the last peer that was delegated + * to the remote host is stopped. This function is used in particular + * if some other controller has already assigned a unique ID to the + * peer. + * + * Creating the peer only creates the handle to manipulate and further + * configure the peer; use "GNUNET_TESTBED_peer_start" and + * "GNUNET_TESTBED_peer_stop" to actually start/stop the peer's + * processes. + * + * Note that the given configuration will be adjusted by the + * controller to avoid port/path conflicts with other peers. + * The "final" configuration can be obtained using + * 'GNUNET_TESTBED_peer_get_information'. + * + * @param unique_id unique ID for this peer + * @param controller controller process to use + * @param host host to run the peer on + * @param cfg configuration to use for the peer + * @return handle to the peer (actual startup will happen asynchronously) + */ +struct GNUNET_TESTBED_Peer * +GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id, + struct GNUNET_TESTBED_Controller *controller, + struct GNUNET_TESTBED_Host *host, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + // FIXME: create locally or delegate... + GNUNET_break (0); + return NULL; +} + + +/** + * Create the given peer at the specified host using the given + * controller. If the given controller is not running on the target + * host, it should find or create a controller at the target host and + * delegate creating the peer. Explicit delegation paths can be setup + * using 'GNUNET_TESTBED_controller_link'. If no explicit delegation + * path exists, a direct link with a subordinate controller is setup + * for the first delegated peer to a particular host; the subordinate + * controller is then destroyed once the last peer that was delegated + * to the remote host is stopped. + * + * Creating the peer only creates the handle to manipulate and further + * configure the peer; use "GNUNET_TESTBED_peer_start" and + * "GNUNET_TESTBED_peer_stop" to actually start/stop the peer's + * processes. + * + * Note that the given configuration will be adjusted by the + * controller to avoid port/path conflicts with other peers. + * The "final" configuration can be obtained using + * 'GNUNET_TESTBED_peer_get_information'. + * + * @param controller controller process to use + * @param host host to run the peer on + * @param cfg configuration to use for the peer + * @return handle to the peer (actual startup will happen asynchronously) + */ +struct GNUNET_TESTBED_Peer * +GNUNET_TESTBED_peer_create (struct GNUNET_TESTBED_Controller *controller, + struct GNUNET_TESTBED_Host *host, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + static uint32_t id_gen; + + return GNUNET_TESTBED_peer_create_with_id_ (++id_gen, + controller, + host, + cfg); +} + + +/** + * Start the given peer. + * + * @param peer peer to start + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_start (struct GNUNET_TESTBED_Peer *peer) +{ + // FIXME: start locally or delegate... + GNUNET_break (0); + return NULL; +} + + +/** + * Stop the given peer. The handle remains valid (use + * "GNUNET_TESTBED_peer_destroy" to fully clean up the + * state of the peer). + * + * @param peer peer to stop + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_stop (struct GNUNET_TESTBED_Peer *peer) +{ + // FIXME: stop locally or delegate... + GNUNET_break (0); + return NULL; +} + + +/** + * Request information about a peer. + * + * @param peer peer to request information about + * @param pit desired information + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_get_information (struct GNUNET_TESTBED_Peer *peer, + enum GNUNET_TESTBED_PeerInformationType pit) +{ + // FIXME: handle locally or delegate... + GNUNET_break (0); + return NULL; +} + + +/** + * Change peer configuration. Must only be called while the + * peer is stopped. Ports and paths cannot be changed this + * way. + * + * @param peer peer to change configuration for + * @param cfg new configuration (differences to existing + * configuration only) + * @return handle to the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_peer_update_configuration (struct GNUNET_TESTBED_Peer *peer, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + // FIXME: handle locally or delegate... + GNUNET_break (0); + return NULL; +} + + +/** + * Manipulate the P2P underlay topology by configuring a link + * between two peers. + * + * @param op_cls closure argument to give with the operation event + * @param p1 first peer + * @param p2 second peer + * @param co option to change + * @param ... option-specific values + * @return handle to the operation, NULL if configuring the link at this + * time is not allowed + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_underlay_configure_link (void *op_cls, + struct GNUNET_TESTBED_Peer *p1, + struct GNUNET_TESTBED_Peer *p2, + enum GNUNET_TESTBED_ConnectOption co, ...) +{ + GNUNET_break (0); + return NULL; +} + + + +/** + * Both peers must have been started before calling this function. + * This function then obtains a HELLO from 'p1', gives it to 'p2' + * and asks 'p2' to connect to 'p1'. + * + * @param op_cls closure argument to give with the operation event + * @param p1 first peer + * @param p2 second peer + * @return handle to the operation, NULL if connecting these two + * peers is fundamentally not possible at this time (peers + * not running or underlay disallows) + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_overlay_connect (void *op_cls, + struct GNUNET_TESTBED_Peer *p1, + struct GNUNET_TESTBED_Peer *p2) +{ + GNUNET_break (0); + return NULL; +} + + + +/* end of testbed_api_peers.c */ diff --git a/src/testbed/testbed_api_peers.h b/src/testbed/testbed_api_peers.h new file mode 100644 index 0000000..ea42c98 --- /dev/null +++ b/src/testbed/testbed_api_peers.h @@ -0,0 +1,71 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_peers.h + * @brief internal API to access the 'peers' subsystem + * @author Christian Grothoff + */ +#ifndef NEW_TESTING_API_PEERS_H +#define NEW_TESTING_API_PEERS_H + +#include "gnunet_testbed_service.h" +#include "gnunet_helper_lib.h" + + +/** + * Create the given peer at the specified host using the given + * controller. If the given controller is not running on the target + * host, it should find or create a controller at the target host and + * delegate creating the peer. Explicit delegation paths can be setup + * using 'GNUNET_TESTBED_controller_link'. If no explicit delegation + * path exists, a direct link with a subordinate controller is setup + * for the first delegated peer to a particular host; the subordinate + * controller is then destroyed once the last peer that was delegated + * to the remote host is stopped. This function is used in particular + * if some other controller has already assigned a unique ID to the + * peer. + * + * Creating the peer only creates the handle to manipulate and further + * configure the peer; use "GNUNET_TESTBED_peer_start" and + * "GNUNET_TESTBED_peer_stop" to actually start/stop the peer's + * processes. + * + * Note that the given configuration will be adjusted by the + * controller to avoid port/path conflicts with other peers. + * The "final" configuration can be obtained using + * 'GNUNET_TESTBED_peer_get_information'. + * + * @param unique_id unique ID for this peer + * @param controller controller process to use + * @param host host to run the peer on + * @param cfg configuration to use for the peer + * @return handle to the peer (actual startup will happen asynchronously) + */ +struct GNUNET_TESTBED_Peer * +GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id, + struct GNUNET_TESTBED_Controller *controller, + struct GNUNET_TESTBED_Host *host, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + + +#endif +/* end of testbed_api_peers.h */ diff --git a/src/testbed/testbed_api_services.c b/src/testbed/testbed_api_services.c new file mode 100644 index 0000000..34de0fd --- /dev/null +++ b/src/testbed/testbed_api_services.c @@ -0,0 +1,61 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_services.c + * @brief convenience functions for accessing services + * @author Christian Grothoff + */ +#include "platform.h" +#include "testbed_api_peers.h" + + +/** + * Connect to a service offered by the given peer. Will ensure that + * the request is queued to not overwhelm our ability to create and + * maintain connections with other systems. The actual service + * handle is then returned via the 'op_result' member in the event + * callback. The 'ca' callback is used to create the connection + * when the time is right; the 'da' callback will be used to + * destroy the connection (upon 'GNUNET_TESTBED_operation_done'). + * 'GNUNET_TESTBED_operation_cancel' can be used to abort this + * operation until the event callback has been called. + * + * @param op_cls closure to pass in operation event + * @param peer peer that runs the service + * @param service_name name of the service to connect to + * @param ca helper function to establish the connection + * @param da helper function to close the connection + * @param cada_cls closure for ca and da + * @return handle for the operation + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_service_connect (void *op_cls, + struct GNUNET_TESTBED_Peer *peer, + const char *service_name, + GNUNET_TESTBED_ConnectAdapter ca, + GNUNET_TESTBED_DisconnectAdapter da, + void *cada_cls) +{ + GNUNET_break (0); + return NULL; +} + +/* end of testbed_api_services.c */ diff --git a/src/testbed/testbed_api_test.c b/src/testbed/testbed_api_test.c new file mode 100644 index 0000000..38e189b --- /dev/null +++ b/src/testbed/testbed_api_test.c @@ -0,0 +1,67 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_test.c + * @brief high-level test function + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_testbed_service.h" + + + + +/** + * Convenience method for running a "simple" test on the local system + * with a single call from 'main'. Underlay and overlay topology are + * configured using the "UNDERLAY" and "OVERLAY" options in the + * "[testbed]" section of the configuration (with possible options + * given in "UNDERLAY_XXX" and/or "OVERLAY_XXX"). + * + * The test is to be terminated using a call to + * "GNUNET_SCHEDULER_shutdown". If starting the test fails, + * the program is stopped without 'master' ever being run. + * + * NOTE: this function should be called from 'main', NOT from + * within a GNUNET_SCHEDULER-loop. This function will initialze + * the scheduler loop, the testbed and then pass control to + * 'master'. + * + * @param testname name of the testcase (to configure logging, etc.) + * @param cfg_filename configuration filename to use + * (for testbed, controller and peers) + * @param num_peers number of peers to start + * @param test_master task to run once the test is ready + * @param test_master_cls closure for 'task'. + */ +void +GNUNET_TESTBED_test_run (const char *testname, + const char *cfg_filename, + unsigned int num_peers, + GNUNET_TESTBED_TestMaster test_master, + void *test_master_cls) +{ + GNUNET_break (0); +} + + + +/* end of testbed_api_test.c */ diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c new file mode 100644 index 0000000..6311806 --- /dev/null +++ b/src/testbed/testbed_api_testbed.c @@ -0,0 +1,153 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_testbed.c + * @brief high-level testbed management + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_testbed_service.h" + + +/** + * Opaque handle to an abstract operation to be executed by the testing framework. + */ +struct GNUNET_TESTBED_Testbed +{ + // FIXME! +}; + + +/** + * Configure and run a testbed using the given + * master controller on 'num_hosts' starting + * 'num_peers' using the given peer configuration. + * + * @param controller master controller for the testbed + * (must not be destroyed until after the + * testbed is destroyed). + * @param num_hosts number of hosts in 'hosts', 0 to only + * use 'localhost' + * @param hosts list of hosts to use for the testbed + * @param num_peers number of peers to start + * @param peer_cfg peer configuration template to use + * @param underlay_topology underlay topology to create + * @param va topology-specific options + * @return handle to the testbed + */ +struct GNUNET_TESTBED_Testbed * +GNUNET_TESTBED_create_va (struct GNUNET_TESTBED_Controller *controller, + unsigned int num_hosts, + struct GNUNET_TESTBED_Host **hosts, + unsigned int num_peers, + const struct GNUNET_CONFIGURATION_Handle *peer_cfg, + enum GNUNET_TESTBED_TopologyOption underlay_topology, + va_list va) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Configure and run a testbed using the given + * master controller on 'num_hosts' starting + * 'num_peers' using the given peer configuration. + * + * @param controller master controller for the testbed + * (must not be destroyed until after the + * testbed is destroyed). + * @param num_hosts number of hosts in 'hosts', 0 to only + * use 'localhost' + * @param hosts list of hosts to use for the testbed + * @param num_peers number of peers to start + * @param peer_cfg peer configuration template to use + * @param underlay_topology underlay topology to create + * @param ... topology-specific options + */ +struct GNUNET_TESTBED_Testbed * +GNUNET_TESTBED_create (struct GNUNET_TESTBED_Controller *controller, + unsigned int num_hosts, + struct GNUNET_TESTBED_Host **hosts, + unsigned int num_peers, + const struct GNUNET_CONFIGURATION_Handle *peer_cfg, + enum GNUNET_TESTBED_TopologyOption underlay_topology, + ...) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Destroy a testbed. Stops all running peers and then + * destroys all peers. Does NOT destroy the master controller. + * + * @param testbed testbed to destroy + */ +void +GNUNET_TESTBED_destroy (struct GNUNET_TESTBED_Testbed *testbed) +{ + GNUNET_break (0); +} + + + +/** + * Convenience method for running a testbed with + * a single call. Underlay and overlay topology + * are configured using the "UNDERLAY" and "OVERLAY" + * options in the "[testbed]" section of the configuration\ + * (with possible options given in "UNDERLAY_XXX" and/or + * "OVERLAY_XXX"). + * + * The testbed is to be terminated using a call to + * "GNUNET_SCHEDULER_shutdown". + * + * @param host_filename name of the file with the 'hosts', NULL + * to run everything on 'localhost' + * @param cfg configuration to use (for testbed, controller and peers) + * @param num_peers number of peers to start; FIXME: maybe put that ALSO into cfg? + * @param event_mask bit mask with set of events to call 'cc' for; + * or-ed values of "1LL" shifted by the + * respective 'enum GNUNET_TESTBED_EventType' + * (i.e. "(1LL << GNUNET_TESTBED_ET_CONNECT) || ...") + * @param cc controller callback to invoke on events + * @param cc_cls closure for cc + * @param master task to run once the testbed is ready + * @param master_cls closure for 'task'. + */ +void +GNUNET_TESTBED_run (const char *host_filename, + const struct GNUNET_CONFIGURATION_Handle *cfg, + unsigned int num_peers, + uint64_t event_mask, + GNUNET_TESTBED_ControllerCallback cc, + void *cc_cls, + GNUNET_SCHEDULER_Task master, + void *master_cls) +{ + GNUNET_break (0); +} + + + +/* end of testbed_api_testbed.c */ diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c new file mode 100644 index 0000000..c0e9f72 --- /dev/null +++ b/src/testbed/testbed_api_topology.c @@ -0,0 +1,127 @@ +/* + This file is part of GNUnet + (C) 2008--2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testbed/testbed_api_topology.c + * @brief topology-generation functions + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_testbed_service.h" + + +/** + * Configure overall network topology to have a particular shape. + * + * @param op_cls closure argument to give with the operation event + * @param num_peers number of peers in 'peers' + * @param peers array of 'num_peers' with the peers to configure + * @param topo desired underlay topology to use + * @param ap topology-specific options + * @return handle to the operation, NULL if configuring the topology + * is not allowed at this time + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_underlay_configure_topology_va (void *op_cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + enum GNUNET_TESTBED_TopologyOption topo, + va_list ap) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Configure overall network topology to have a particular shape. + * + * @param op_cls closure argument to give with the operation event + * @param num_peers number of peers in 'peers' + * @param peers array of 'num_peers' with the peers to configure + * @param topo desired underlay topology to use + * @param ... topology-specific options + * @return handle to the operation, NULL if configuring the topology + * is not allowed at this time + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_underlay_configure_topology (void *op_cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + enum GNUNET_TESTBED_TopologyOption topo, + ...) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * All peers must have been started before calling this function. + * This function then connects the given peers in the P2P overlay + * using the given topology. + * + * @param op_cls closure argument to give with the operation event + * @param num_peers number of peers in 'peers' + * @param peers array of 'num_peers' with the peers to configure + * @param topo desired underlay topology to use + * @param va topology-specific options + * @return handle to the operation, NULL if connecting these + * peers is fundamentally not possible at this time (peers + * not running or underlay disallows) + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer *peers, + enum GNUNET_TESTBED_TopologyOption topo, + va_list va) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * All peers must have been started before calling this function. + * This function then connects the given peers in the P2P overlay + * using the given topology. + * + * @param op_cls closure argument to give with the operation event + * @param num_peers number of peers in 'peers' + * @param peers array of 'num_peers' with the peers to configure + * @param topo desired underlay topology to use + * @param ... topology-specific options + * @return handle to the operation, NULL if connecting these + * peers is fundamentally not possible at this time (peers + * not running or underlay disallows) + */ +struct GNUNET_TESTBED_Operation * +GNUNET_TESTBED_overlay_configure_topology (void *op_cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer *peers, + enum GNUNET_TESTBED_TopologyOption topo, + ...) +{ + GNUNET_break (0); + return NULL; +} + +/* end of testbed_api_topology.c */ diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 050691d..572c033 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -21,7 +21,7 @@ if HAVE_EXPENSIVE_TESTS test_testing_topology_clique_minimum \ test_testing_topology_clique_dfs \ test_testing_topology_churn \ - test_testing_topology_line + test_testing_topology_line \ test_testing_topology_blacklist \ test_testing_group_remote \ test_testing_topology_ring \ @@ -33,7 +33,9 @@ if HAVE_EXPENSIVE_TESTS test_testing_topology_scale_free endif -lib_LTLIBRARIES = libgnunettesting.la +lib_LTLIBRARIES = \ + libgnunettesting.la \ + libgnunettesting_new.la libgnunettesting_la_SOURCES = \ helper.c \ @@ -51,6 +53,16 @@ libgnunettesting_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ -version-info 0:1:0 + +libgnunettesting_new_la_SOURCES = \ + testing_new.c +libgnunettesting_new_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la +libgnunettesting_new_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:1:0 + + bin_PROGRAMS = \ gnunet-testing @@ -77,7 +89,10 @@ check_PROGRAMS = \ test_testing_topology_erdos_renyi \ test_testing_topology_internat \ test_testing_topology_none \ - test_testing_topology_scale_free + test_testing_topology_scale_free \ + test_testing_new_portreservation \ + test_testing_new_peerstartup \ + test_testing_new_servicestartup if ENABLE_TEST_RUN TESTS = \ @@ -86,8 +101,9 @@ TESTS = \ test_testing_reconnect \ test_testing_group \ test_testing_peergroup \ - test_testing_topology_clique \ - test_testing_2dtorus + test_testing_new_portreservation \ + test_testing_new_peerstartup \ + test_testing_new_servicestartup endif gnunet_testing_SOURCES = \ @@ -253,6 +269,23 @@ test_testing_topology_none_LDADD = \ $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la +test_testing_new_portreservation_SOURCES = \ + test_testing_new_portreservation.c +test_testing_new_portreservation_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_testing_new_peerstartup_SOURCES = \ + test_testing_new_peerstartup.c +test_testing_new_peerstartup_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_testing_new_servicestartup_SOURCES = \ + test_testing_new_servicestartup.c +test_testing_new_servicestartup_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la EXTRA_DIST = \ test_testing_defaults.conf \ diff --git a/src/testing/Makefile.in b/src/testing/Makefile.in index 544d98d..459066f 100644 --- a/src/testing/Makefile.in +++ b/src/testing/Makefile.in @@ -58,14 +58,18 @@ check_PROGRAMS = test_testing$(EXEEXT) test_testing_connect$(EXEEXT) \ test_testing_topology_erdos_renyi$(EXEEXT) \ test_testing_topology_internat$(EXEEXT) \ test_testing_topology_none$(EXEEXT) \ - test_testing_topology_scale_free$(EXEEXT) + test_testing_topology_scale_free$(EXEEXT) \ + test_testing_new_portreservation$(EXEEXT) \ + test_testing_new_peerstartup$(EXEEXT) \ + test_testing_new_servicestartup$(EXEEXT) @ENABLE_TEST_RUN_TRUE@TESTS = test_testing$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_testing_connect$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_testing_reconnect$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_testing_group$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_testing_peergroup$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_topology_clique$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_2dtorus$(EXEEXT) +@ENABLE_TEST_RUN_TRUE@ test_testing_new_portreservation$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_testing_new_peerstartup$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_testing_new_servicestartup$(EXEEXT) subdir = src/testing DIST_COMMON = $(dist_pkgcfg_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in @@ -129,6 +133,15 @@ libgnunettesting_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunettesting_la_LDFLAGS) \ $(LDFLAGS) -o $@ +libgnunettesting_new_la_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la +am_libgnunettesting_new_la_OBJECTS = testing_new.lo +libgnunettesting_new_la_OBJECTS = \ + $(am_libgnunettesting_new_la_OBJECTS) +libgnunettesting_new_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libgnunettesting_new_la_LDFLAGS) \ + $(LDFLAGS) -o $@ PROGRAMS = $(bin_PROGRAMS) am_gnunet_testing_OBJECTS = gnunet-testing.$(OBJEXT) gnunet_testing_OBJECTS = $(am_gnunet_testing_OBJECTS) @@ -159,6 +172,27 @@ test_testing_group_remote_OBJECTS = \ test_testing_group_remote_DEPENDENCIES = \ $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/util/libgnunetutil.la +am_test_testing_new_peerstartup_OBJECTS = \ + test_testing_new_peerstartup.$(OBJEXT) +test_testing_new_peerstartup_OBJECTS = \ + $(am_test_testing_new_peerstartup_OBJECTS) +test_testing_new_peerstartup_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_test_testing_new_portreservation_OBJECTS = \ + test_testing_new_portreservation.$(OBJEXT) +test_testing_new_portreservation_OBJECTS = \ + $(am_test_testing_new_portreservation_OBJECTS) +test_testing_new_portreservation_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_test_testing_new_servicestartup_OBJECTS = \ + test_testing_new_servicestartup.$(OBJEXT) +test_testing_new_servicestartup_OBJECTS = \ + $(am_test_testing_new_servicestartup_OBJECTS) +test_testing_new_servicestartup_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la am_test_testing_peergroup_OBJECTS = test_testing_peergroup.$(OBJEXT) test_testing_peergroup_OBJECTS = $(am_test_testing_peergroup_OBJECTS) test_testing_peergroup_DEPENDENCIES = \ @@ -321,10 +355,14 @@ am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libgnunettesting_la_SOURCES) $(gnunet_testing_SOURCES) \ +SOURCES = $(libgnunettesting_la_SOURCES) \ + $(libgnunettesting_new_la_SOURCES) $(gnunet_testing_SOURCES) \ $(test_testing_SOURCES) $(test_testing_2dtorus_SOURCES) \ $(test_testing_connect_SOURCES) $(test_testing_group_SOURCES) \ $(test_testing_group_remote_SOURCES) \ + $(test_testing_new_peerstartup_SOURCES) \ + $(test_testing_new_portreservation_SOURCES) \ + $(test_testing_new_servicestartup_SOURCES) \ $(test_testing_peergroup_SOURCES) \ $(test_testing_reconnect_SOURCES) \ $(test_testing_topology_2d_torus_SOURCES) \ @@ -344,10 +382,13 @@ SOURCES = $(libgnunettesting_la_SOURCES) $(gnunet_testing_SOURCES) \ $(test_testing_topology_small_world_torus_SOURCES) \ $(test_testing_topology_stability_SOURCES) DIST_SOURCES = $(libgnunettesting_la_SOURCES) \ - $(gnunet_testing_SOURCES) $(test_testing_SOURCES) \ - $(test_testing_2dtorus_SOURCES) \ + $(libgnunettesting_new_la_SOURCES) $(gnunet_testing_SOURCES) \ + $(test_testing_SOURCES) $(test_testing_2dtorus_SOURCES) \ $(test_testing_connect_SOURCES) $(test_testing_group_SOURCES) \ $(test_testing_group_remote_SOURCES) \ + $(test_testing_new_peerstartup_SOURCES) \ + $(test_testing_new_portreservation_SOURCES) \ + $(test_testing_new_servicestartup_SOURCES) \ $(test_testing_peergroup_SOURCES) \ $(test_testing_reconnect_SOURCES) \ $(test_testing_topology_2d_torus_SOURCES) \ @@ -427,6 +468,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -460,6 +502,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -590,9 +633,21 @@ dist_pkgcfg_DATA = \ @HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_clique_minimum \ @HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_clique_dfs \ @HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_churn \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_line +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_line \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_blacklist \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_group_remote \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_ring \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_2d_torus \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_small_world_ring \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_small_world_torus \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_erdos_renyi \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_internat \ +@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_scale_free + +lib_LTLIBRARIES = \ + libgnunettesting.la \ + libgnunettesting_new.la -lib_LTLIBRARIES = libgnunettesting.la libgnunettesting_la_SOURCES = \ helper.c \ testing.c \ @@ -611,6 +666,16 @@ libgnunettesting_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ -version-info 0:1:0 +libgnunettesting_new_la_SOURCES = \ + testing_new.c + +libgnunettesting_new_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la + +libgnunettesting_new_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:1:0 + gnunet_testing_SOURCES = \ gnunet-testing.c @@ -797,6 +862,27 @@ test_testing_topology_none_LDADD = \ $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la +test_testing_new_portreservation_SOURCES = \ + test_testing_new_portreservation.c + +test_testing_new_portreservation_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_testing_new_peerstartup_SOURCES = \ + test_testing_new_peerstartup.c + +test_testing_new_peerstartup_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_testing_new_servicestartup_SOURCES = \ + test_testing_new_servicestartup.c + +test_testing_new_servicestartup_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting_new.la \ + $(top_builddir)/src/util/libgnunetutil.la + EXTRA_DIST = \ test_testing_defaults.conf \ test_testing_data.conf \ @@ -888,6 +974,8 @@ clean-libLTLIBRARIES: done libgnunettesting.la: $(libgnunettesting_la_OBJECTS) $(libgnunettesting_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunettesting_la_LINK) -rpath $(libdir) $(libgnunettesting_la_OBJECTS) $(libgnunettesting_la_LIBADD) $(LIBS) +libgnunettesting_new.la: $(libgnunettesting_new_la_OBJECTS) $(libgnunettesting_new_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgnunettesting_new_la_LINK) -rpath $(libdir) $(libgnunettesting_new_la_OBJECTS) $(libgnunettesting_new_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @@ -958,6 +1046,15 @@ test_testing_group$(EXEEXT): $(test_testing_group_OBJECTS) $(test_testing_group_ test_testing_group_remote$(EXEEXT): $(test_testing_group_remote_OBJECTS) $(test_testing_group_remote_DEPENDENCIES) @rm -f test_testing_group_remote$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_testing_group_remote_OBJECTS) $(test_testing_group_remote_LDADD) $(LIBS) +test_testing_new_peerstartup$(EXEEXT): $(test_testing_new_peerstartup_OBJECTS) $(test_testing_new_peerstartup_DEPENDENCIES) + @rm -f test_testing_new_peerstartup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_testing_new_peerstartup_OBJECTS) $(test_testing_new_peerstartup_LDADD) $(LIBS) +test_testing_new_portreservation$(EXEEXT): $(test_testing_new_portreservation_OBJECTS) $(test_testing_new_portreservation_DEPENDENCIES) + @rm -f test_testing_new_portreservation$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_testing_new_portreservation_OBJECTS) $(test_testing_new_portreservation_LDADD) $(LIBS) +test_testing_new_servicestartup$(EXEEXT): $(test_testing_new_servicestartup_OBJECTS) $(test_testing_new_servicestartup_DEPENDENCIES) + @rm -f test_testing_new_servicestartup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_testing_new_servicestartup_OBJECTS) $(test_testing_new_servicestartup_LDADD) $(LIBS) test_testing_peergroup$(EXEEXT): $(test_testing_peergroup_OBJECTS) $(test_testing_peergroup_DEPENDENCIES) @rm -f test_testing_peergroup$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_testing_peergroup_OBJECTS) $(test_testing_peergroup_LDADD) $(LIBS) @@ -1026,6 +1123,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_connect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_group.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_group_remote.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_new_peerstartup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_new_portreservation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_new_servicestartup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_peergroup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_reconnect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_topology.Po@am__quote@ @@ -1033,6 +1133,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_topology_churn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing_group.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing_new.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing_peergroup.Plo@am__quote@ .c.o: @@ -1386,15 +1487,6 @@ uninstall-am: uninstall-binPROGRAMS uninstall-dist_pkgcfgDATA \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-dist_pkgcfgDATA uninstall-libLTLIBRARIES -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_blacklist \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_group_remote \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_ring \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_2d_torus \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_small_world_ring \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_small_world_torus \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_erdos_renyi \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_internat \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_scale_free # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/testing/gnunet-testing.c b/src/testing/gnunet-testing.c index 0caa28e..bdbb5e8 100644 --- a/src/testing/gnunet-testing.c +++ b/src/testing/gnunet-testing.c @@ -170,7 +170,7 @@ create_hostkeys (const unsigned int no) return 1; } - if (GNUNET_YES != GNUNET_DISK_file_size (hostkey_src_file, &fs, GNUNET_YES)) + if (GNUNET_OK != GNUNET_DISK_file_size (hostkey_src_file, &fs, GNUNET_YES, GNUNET_YES)) fs = 0; if (0 != (fs % HOSTKEYFILESIZE)) diff --git a/src/testing/test_testing_2dtorus.c b/src/testing/test_testing_2dtorus.c index 7b109bc..00a66d6 100644 --- a/src/testing/test_testing_2dtorus.c +++ b/src/testing/test_testing_2dtorus.c @@ -317,7 +317,7 @@ run (void *cls, char *const *args, const char *cfgfile, hosts); GNUNET_assert (pg != NULL); shutdown_handle = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_get_forever (), + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); } diff --git a/src/testing/test_testing_2dtorus.conf b/src/testing/test_testing_2dtorus.conf index ba1db3a..54bb7c5 100644 --- a/src/testing/test_testing_2dtorus.conf +++ b/src/testing/test_testing_2dtorus.conf @@ -1,6 +1,7 @@ +@INLINE@ test_testing_defaults.conf [PATHS] -SERVICEHOME = /tmp/test_testing_small/ -DEFAULTCONFIG = test_testing_small.conf +SERVICEHOME = /tmp/test_testing_2dtorus/ +DEFAULTCONFIG = test_testing_2dtorus.conf [arm] PORT = 10010 @@ -29,6 +30,7 @@ PORT = 10011 [transport] PORT = 10002 AUTOSTART = YES +PLUGINS = tcp [nat] DISABLEV6 = YES diff --git a/src/testing/test_testing_data_topology_2d_torus.conf b/src/testing/test_testing_data_topology_2d_torus.conf index 45fd690..cbdaceb 100644 --- a/src/testing/test_testing_data_topology_2d_torus.conf +++ b/src/testing/test_testing_data_topology_2d_torus.conf @@ -1,8 +1,7 @@ @INLINE@ test_testing_defaults.conf [PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf +DEFAULTCONFIG = test_testing_data_topology_2d_torus.conf [TESTING] NUM_PEERS = 13 TOPOLOGY = 2D_TORUS - diff --git a/src/testing/test_testing_defaults.conf b/src/testing/test_testing_defaults.conf index 7b6c4c4..ba7e269 100644 --- a/src/testing/test_testing_defaults.conf +++ b/src/testing/test_testing_defaults.conf @@ -70,3 +70,9 @@ AUTOSTART = NO [gns] AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[lockmanager] +AUTOSTART = NO diff --git a/src/testing/test_testing_group_remote.c b/src/testing/test_testing_group_remote.c index e300f95..b06655c 100644 --- a/src/testing/test_testing_group_remote.c +++ b/src/testing/test_testing_group_remote.c @@ -171,7 +171,7 @@ run (void *cls, char *const *args, const char *cfgfile, data[count] = '\0'; temphost = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Host)); ret = - sscanf (buf, "%a[a-zA-Z0-9]@%a[a-zA-Z0-9.]:%hd", + SSCANF (buf, "%a[a-zA-Z0-9]@%a[a-zA-Z0-9.]:%hd", &temphost->username, &temphost->hostname, &temphost->port); if (3 == ret) { diff --git a/src/testing/test_testing_new_peerstartup.c b/src/testing/test_testing_new_peerstartup.c new file mode 100644 index 0000000..203df2f --- /dev/null +++ b/src/testing/test_testing_new_peerstartup.c @@ -0,0 +1,161 @@ +/* + This file is part of GNUnet + (C) 2008, 2009, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testing/test_testing_new_peerstartup.c + * @brief test case for testing peer startup and shutdown using new testing + * library + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_configuration_lib.h" +#include "gnunet_os_lib.h" +#include "gnunet_testing_lib-new.h" + +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +#define TIME_REL_SEC(sec) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) + +/** + * The testing context + */ +struct TestingContext +{ + /** + * The testing system + */ + struct GNUNET_TESTING_System *system; + + /** + * The peer which has been started by the testing system + */ + struct GNUNET_TESTING_Peer *peer; + + /** + * The running configuration of the peer + */ + struct GNUNET_CONFIGURATION_Handle *cfg; +}; + + +/** + * Task for shutdown + * + * @param cls the testing context + * @param tc the tast context + */ +static void +do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct TestingContext *test_ctx = cls; + + GNUNET_assert (GNUNET_OK == GNUNET_TESTING_peer_stop (test_ctx->peer)); + GNUNET_TESTING_peer_destroy (test_ctx->peer); + GNUNET_CONFIGURATION_destroy (test_ctx->cfg); + GNUNET_TESTING_hostkeys_unload (test_ctx->system); + GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES); + GNUNET_free (test_ctx); +} + + +/** + * Main point of test execution + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_TESTING_System *system; + struct GNUNET_TESTING_Peer *peer; + struct GNUNET_CONFIGURATION_Handle *new_cfg; + struct TestingContext *test_ctx; + char *data_dir; + char *hostkeys_file; + char *emsg; + char *_tmpdir; + char *tmpdir; +#ifdef MINGW + char *tmpdir_w; +#endif + + struct GNUNET_PeerIdentity id; + + _tmpdir = getenv ("TMP"); + if (NULL == _tmpdir) + _tmpdir = getenv ("TEMP"); + if (NULL == _tmpdir) + _tmpdir = getenv ("TMPDIR"); + if (NULL == _tmpdir) + _tmpdir = "/tmp"; + GNUNET_asprintf (&tmpdir, "%s/%s", _tmpdir, "test-gnunet-testing_new-XXXXXX"); +#ifdef MINGW + tmpdir_w = GNUNET_malloc (MAX_PATH + 1); + GNUNET_assert (ERROR_SUCCESS == plibc_conv_to_win_path (tmpdir, tmpdir_w)); + GNUNET_free (tmpdir); + tmpdir = tmpdir_w; + //GNUNET_assert (0 == _mktemp_s (tmpdir, strlen (tmpdir) + 1)); +#else + GNUNET_assert (mkdtemp (tmpdir) == tmpdir); +#endif + /* LOG (GNUNET_ERROR_TYPE_ERROR, */ + /* "Temporary directory: %s\n", tmpdir); */ + system = GNUNET_TESTING_system_create (tmpdir, + "localhost"); + GNUNET_assert (NULL != system); + GNUNET_free (tmpdir); + data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); + GNUNET_asprintf (&hostkeys_file, "%s/testing_hostkeys.dat", data_dir); + GNUNET_free (data_dir); + GNUNET_assert (GNUNET_OK == + GNUNET_TESTING_hostkeys_load (system, hostkeys_file)); + GNUNET_free (hostkeys_file); + new_cfg = GNUNET_CONFIGURATION_dup (cfg); + emsg = NULL; + peer = GNUNET_TESTING_peer_configure (system, new_cfg, 0, &id, &emsg); + GNUNET_assert (NULL != peer); + GNUNET_assert (NULL == emsg); + GNUNET_assert (GNUNET_OK == GNUNET_TESTING_peer_start (peer)); + test_ctx = GNUNET_malloc (sizeof (struct TestingContext)); + test_ctx->system = system; + test_ctx->peer = peer; + test_ctx->cfg = new_cfg; + GNUNET_SCHEDULER_add_delayed (TIME_REL_SEC (5), + &do_shutdown, test_ctx); + +} + + +int main (int argc, char *argv[]) +{ + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + if (GNUNET_OK != + GNUNET_PROGRAM_run (argc, argv, + "test_testing_new_peerstartup", + "test case for peerstartup using new testing library", + options, &run, NULL)) + return 1; + return 0; +} diff --git a/src/testing/test_testing_new_portreservation.c b/src/testing/test_testing_new_portreservation.c new file mode 100644 index 0000000..4010944 --- /dev/null +++ b/src/testing/test_testing_new_portreservation.c @@ -0,0 +1,90 @@ +/* + This file is part of GNUnet + (C) 2008, 2009, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testing/test_testing_new_portreservation.c + * @brief test case for testing port reservation routines from the new testing + * library API + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testing_lib-new.h" + +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +/** + * Main point of test execution + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_TESTING_System *system; + uint16_t new_port1; + uint16_t new_port2; + uint16_t old_port1; + + system = GNUNET_TESTING_system_create ("/tmp/gnunet-testing-new", + "localhost"); + GNUNET_assert (NULL != system); + new_port1 = GNUNET_TESTING_reserve_port (system, GNUNET_YES); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Reserved TCP port %u\n", new_port1); + GNUNET_assert (0 != new_port1); + new_port2 = GNUNET_TESTING_reserve_port (system, GNUNET_YES); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Reserved TCP port %u\n", new_port2); + GNUNET_assert (0 != new_port2); + GNUNET_assert (new_port1 != new_port2); + GNUNET_TESTING_release_port (system, GNUNET_YES, new_port1); + old_port1 = new_port1; + new_port1 = 0; + new_port1 = GNUNET_TESTING_reserve_port (system, GNUNET_YES); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Reserved TCP port %u\n", new_port1); + GNUNET_assert (0 != new_port1); + GNUNET_assert (old_port1 == new_port1); + GNUNET_TESTING_release_port (system, GNUNET_YES, new_port1); + GNUNET_TESTING_release_port (system, GNUNET_YES, new_port2); + GNUNET_TESTING_system_destroy (system, GNUNET_NO); +} + +int main (int argc, char *argv[]) +{ + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + if (GNUNET_OK != + GNUNET_PROGRAM_run (argc, + argv, + "test_testing_new_portreservation", + "test case for testing port reservation routines" + " from the new testing library API", + options, + &run, + NULL)) + { + return 1; + } + return 0; +} diff --git a/src/testing/test_testing_new_servicestartup.c b/src/testing/test_testing_new_servicestartup.c new file mode 100644 index 0000000..3b98688 --- /dev/null +++ b/src/testing/test_testing_new_servicestartup.c @@ -0,0 +1,110 @@ +/* + This file is part of GNUnet + (C) 2008, 2009, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testing/test_testing_new_servicestartup.c + * @brief test case for testing service startup using new testing API + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_testing_lib-new.h" + + +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +#define TIME_REL_SEC(sec) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) + +/** + * Global test status + */ +static int test_success; + +/** + * The shutdown task. Used to signal that testing is done and service has to be + * stopped + * + * @param cls NULL + */ +static void +shutdown_task(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + test_success = GNUNET_YES; + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * The testing callback function + * + * @param cls NULL + * @param cfg the configuration with which the current testing service is run + */ +static void +test_run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + GNUNET_assert (NULL == cls); + GNUNET_assert (NULL != cfg); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Service arm started successfully\n"); + GNUNET_SCHEDULER_add_delayed (TIME_REL_SEC (3), &shutdown_task, NULL); +} + + +/** + * The main point of execution + */ +int main (int argc, char *argv[]) +{ + char *_tmpdir; + char *tmpdir; +#ifdef MINGW + char *tmpdir_w; +#endif + + GNUNET_log_setup ("test_testing_new_servicestartup", "DEBUG", NULL); + _tmpdir = getenv ("TMP"); + if (NULL == _tmpdir) + _tmpdir = getenv ("TEMP"); + if (NULL == _tmpdir) + _tmpdir = getenv ("TMPDIR"); + if (NULL == _tmpdir) + _tmpdir = "/tmp"; + GNUNET_asprintf (&tmpdir, "%s/%s", _tmpdir, "test-gnunet-testing_new-XXXXXX"); +#ifdef MINGW + tmpdir_w = GNUNET_malloc (MAX_PATH + 1); + GNUNET_assert (ERROR_SUCCESS == plibc_conv_to_win_path (tmpdir, tmpdir_w)); + GNUNET_free (tmpdir); + tmpdir = tmpdir_w; + //GNUNET_assert (0 == _mktemp_s (tmpdir, strlen (tmpdir) + 1)); +#else + GNUNET_assert (mkdtemp (tmpdir) == tmpdir); +#endif + + test_success = GNUNET_NO; + GNUNET_assert (0 == GNUNET_TESTING_service_run (tmpdir, + "arm", + "test_testing_defaults.conf", + &test_run, + NULL)); + GNUNET_free (tmpdir); + return (GNUNET_YES == test_success) ? 0 : 1; +} diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c index ba5e237..b216544 100644 --- a/src/testing/test_testing_topology.c +++ b/src/testing/test_testing_topology.c @@ -26,7 +26,6 @@ #include "gnunet_core_service.h" #include "gnunet_os_lib.h" -#define VERBOSE GNUNET_NO #define PROGRESS_BARS GNUNET_YES @@ -167,25 +166,23 @@ static struct TestMessageContext *test_messages; /** * Check whether peers successfully shut down. */ -void +static void shutdown_callback (void *cls, const char *emsg) { if (emsg != NULL) { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Shutdown of peers failed: %s!\n", + emsg); if (ok == 0) ok = 666; } else { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); -#endif } } + #if DELAY_FOR_LOGGING static void gather_log_data () @@ -200,12 +197,12 @@ gather_log_data () GNUNET_OS_start_process (NULL, NULL, "./memsize.pl", "memsize.pl", "totals.txt", peer_number, connect_number, NULL); GNUNET_OS_process_wait (mem_process); - GNUNET_OS_process_close (mem_process); + GNUNET_OS_process_destroy (mem_process); mem_process = NULL; } - #endif + static void finish_testing () { @@ -213,11 +210,8 @@ finish_testing () struct TestMessageContext *pos; struct TestMessageContext *free_pos; -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called finish testing, stopping daemons.\n"); -#endif - pos = test_messages; while (pos != NULL) { @@ -239,16 +233,11 @@ finish_testing () } GNUNET_free (free_pos); } -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmit_ready's scheduled %d, failed %d, transmit_ready's called %d\n", transmit_ready_scheduled, transmit_ready_failed, transmit_ready_called); -#endif - -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calling daemons_stop\n"); -#endif GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); if (dotOutFile != NULL) @@ -256,7 +245,6 @@ finish_testing () FPRINTF (dotOutFile, "%s", "}"); FCLOSE (dotOutFile); } - ok = 0; } @@ -267,21 +255,20 @@ disconnect_cores (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct TestMessageContext *pos = cls; /* Disconnect from the respective cores */ -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from peer 1 `%4s'\n", GNUNET_i2s (&pos->peer1->id)); -#endif if (pos->peer1handle != NULL) + { GNUNET_CORE_disconnect (pos->peer1handle); -#if VERBOSE > 1 + pos->peer1handle = NULL; + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from peer 2 `%4s'\n", GNUNET_i2s (&pos->peer2->id)); -#endif if (pos->peer2handle != NULL) + { GNUNET_CORE_disconnect (pos->peer2handle); - /* Set handles to NULL so test case can be ended properly */ - pos->peer1handle = NULL; - pos->peer2handle = NULL; + pos->peer2handle = NULL; + } pos->disconnect_task = GNUNET_SCHEDULER_NO_TASK; /* Decrement total connections so new can be established */ total_server_connections -= 2; @@ -316,6 +303,7 @@ stats_print (void *cls, const struct GNUNET_PeerIdentity *peer, } #endif + static void topology_cb (void *cls, const struct GNUNET_PeerIdentity *first, const struct GNUNET_PeerIdentity *second, const char *emsg) @@ -348,6 +336,7 @@ topology_cb (void *cls, const struct GNUNET_PeerIdentity *first, } } + static int process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, @@ -382,14 +371,12 @@ process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer, total_messages_received++; -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message from `%4s', type %d.\n", GNUNET_i2s (peer), ntohs (message->type)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Total messages received %d, expected %d.\n", total_messages_received, expected_messages); -#endif if (total_messages_received == expected_messages) { @@ -416,13 +403,14 @@ process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer, return GNUNET_OK; } + static void end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { char *msg = cls; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "End badly was called (%s)... stopping daemons.\n", msg); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Ending with error: %s\n", msg); struct TestMessageContext *pos; struct TestMessageContext *free_pos; @@ -444,7 +432,6 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_free (free_pos); } -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmit_ready's scheduled %d, failed %d, transmit_ready's called %d\n", transmit_ready_scheduled, transmit_ready_failed, @@ -452,7 +439,6 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Total messages received %d, expected %d.\n", total_messages_received, expected_messages); -#endif if (pg != NULL) { @@ -469,6 +455,7 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } } + static size_t transmit_ready (void *cls, size_t size, void *buf) { @@ -481,12 +468,10 @@ transmit_ready (void *cls, size_t size, void *buf) m->header.size = htons (sizeof (struct GNUNET_TestMessage)); m->uid = htonl (pos->uid); transmit_ready_called++; -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "transmit ready for peer %s\ntransmit_ready's scheduled %d, transmit_ready's called %d\n", GNUNET_i2s (&pos->peer1->id), transmit_ready_scheduled, transmit_ready_called); -#endif return sizeof (struct GNUNET_TestMessage); } @@ -495,11 +480,13 @@ static struct GNUNET_CORE_MessageHandler no_handlers[] = { {NULL, 0, 0} }; + static struct GNUNET_CORE_MessageHandler handlers[] = { {&process_mtype, MTYPE, sizeof (struct GNUNET_TestMessage)}, {NULL, 0, 0} }; + static void init_notify_peer2 (void *cls, struct GNUNET_CORE_Handle *server, const struct GNUNET_PeerIdentity *my_identity) @@ -511,12 +498,10 @@ init_notify_peer2 (void *cls, struct GNUNET_CORE_Handle *server, pos->peer2connected = GNUNET_YES; if (pos->peer1notified == GNUNET_YES) /* Peer 1 has been notified of connection to peer 2 */ { -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduling message send to peer `%s' from peer `%s' (init_notify_peer2)\n", GNUNET_i2s (my_identity), GNUNET_h2s (&pos->peer1->id.hashPubKey)); -#endif if (NULL == GNUNET_CORE_notify_transmit_ready (pos->peer1handle, GNUNET_YES, 0, TIMEOUT, &pos->peer2->id, @@ -535,6 +520,7 @@ init_notify_peer2 (void *cls, struct GNUNET_CORE_Handle *server, } } + /** * Method called whenever a given peer connects. * @@ -553,23 +539,19 @@ connect_notify_peers (void *cls, const struct GNUNET_PeerIdentity *peer, if (0 == memcmp (peer, &pos->peer2->id, sizeof (struct GNUNET_PeerIdentity))) { pos->peer1notified = GNUNET_YES; -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s' notified of connection to peer `%s'\n", GNUNET_i2s (&pos->peer1->id), GNUNET_h2s (&peer->hashPubKey)); -#endif } else return; if (pos->peer2connected == GNUNET_YES) /* Already connected and notified of connection, send message! */ { -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduling message send to peer `%s' from peer `%s' (init_notify_peer2)\n", GNUNET_i2s (&pos->peer2->id), GNUNET_h2s (&pos->peer1->id.hashPubKey)); -#endif if (NULL == GNUNET_CORE_notify_transmit_ready (pos->peer1handle, GNUNET_YES, 0, TIMEOUT, &pos->peer2->id, @@ -588,6 +570,7 @@ connect_notify_peers (void *cls, const struct GNUNET_PeerIdentity *peer, } } + static void init_notify_peer1 (void *cls, struct GNUNET_CORE_Handle *server, const struct GNUNET_PeerIdentity *my_identity) @@ -595,13 +578,9 @@ init_notify_peer1 (void *cls, struct GNUNET_CORE_Handle *server, struct TestMessageContext *pos = cls; total_server_connections++; - -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core connection to `%4s' established, setting up handles\n", GNUNET_i2s (my_identity)); -#endif - /* * Connect to the receiving peer */ @@ -663,7 +642,7 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } -void +static void topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, const struct GNUNET_PeerIdentity *second, uint32_t distance, const struct GNUNET_CONFIGURATION_Handle *first_cfg, @@ -694,10 +673,8 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, fflush (stdout); #endif total_connections++; -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "connected peer %s to peer %s\n", first_daemon->shortname, second_daemon->shortname); -#endif temp_context = GNUNET_malloc (sizeof (struct TestMessageContext)); temp_context->peer1 = first_daemon; temp_context->peer2 = second_daemon; @@ -711,26 +688,22 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, FPRINTF (dotOutFile, "\tn%s -- n%s;\n", first_daemon->shortname, second_daemon->shortname); } -#if VERBOSE else { failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to connect peer %s to peer %s with error :\n%s\n", first_daemon->shortname, second_daemon->shortname, emsg); } -#endif if (total_connections == expected_connections) { #if PROGRESS_BARS FPRINTF (stdout, "%s", "100%%]\n"); #endif -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created %d total connections, which is our target number! Calling send messages.\n", total_connections); -#endif modnum = expected_messages / 4; dotnum = (expected_messages / 50) + 1; if (modnum == 0) @@ -777,26 +750,24 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, } else { -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have %d total connections, %d failed connections, Want %d (at least %d)\n", total_connections, failed_connections, expected_connections, expected_connections - (unsigned int) (fail_percentage * expected_connections)); -#endif } } + static void topology_creation_finished (void *cls, const char *emsg) { -#if VERBOSE if (emsg == NULL) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All topology connections created successfully!\n"); -#endif } + static void connect_topology () { @@ -810,7 +781,7 @@ connect_topology () connect_timeout, connect_attempts, &topology_creation_finished, NULL); #if PROGRESS_BARS - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Have %d expected connections\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have %d expected connections\n", expected_connections); #endif } @@ -884,10 +855,8 @@ peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, return; } GNUNET_assert (id != NULL); -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n", (num_peers - peers_left) + 1, num_peers); -#endif #if PROGRESS_BARS if ((num_peers - peers_left) % modnum == 0) { @@ -910,10 +879,8 @@ peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, #if PROGRESS_BARS FPRINTF (stdout, "%s", "100%%]\n"); #endif -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All %d daemons started, now connecting peers!\n", num_peers); -#endif GNUNET_SCHEDULER_cancel (die_task); /* Set up task in case topology creation doesn't finish * within a reasonable amount of time */ @@ -952,12 +919,9 @@ hostkey_callback (void *cls, const struct GNUNET_PeerIdentity *id, "Hostkey callback received error: %s\n", emsg); } -#if VERBOSE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostkey (%d/%d) created for peer `%s'\n", num_peers - peers_left, num_peers, GNUNET_i2s (id)); -#endif - #if PROGRESS_BARS if ((num_peers - peers_left) % modnum == 0) { @@ -993,6 +957,7 @@ hostkey_callback (void *cls, const struct GNUNET_PeerIdentity *id, } } + static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) @@ -1012,11 +977,8 @@ run (void *cls, char *const *args, const char *cfgfile, FPRINTF (dotOutFile, "%s", "strict graph G {\n"); } -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons based on config file %s\n", cfgfile); -#endif - if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", &test_directory)) @@ -1069,7 +1031,7 @@ run (void *cls, char *const *args, const char *cfgfile, "connect_topology_option_modifier", &connect_topology_option_modifier_string)) { - if (sscanf + if (SSCANF (connect_topology_option_modifier_string, "%lf", &connect_topology_option_modifier) != 1) { @@ -1178,6 +1140,7 @@ run (void *cls, char *const *args, const char *cfgfile, } + static int check () { @@ -1192,9 +1155,6 @@ check () char *const argv[] = { binary_name, "-c", config_file_name, -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -1214,6 +1174,7 @@ check () return ok; } + int main (int argc, char *argv[]) { @@ -1238,11 +1199,7 @@ main (int argc, char *argv[]) GNUNET_asprintf (&dotOutFileName, "topology_%s.dot", topology_string); GNUNET_log_setup (our_binary_name, -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); GNUNET_free (topology_string); diff --git a/src/testing/test_testing_topology_blacklist.c b/src/testing/test_testing_topology_blacklist.c index ad39f7d..c90f48d 100644 --- a/src/testing/test_testing_topology_blacklist.c +++ b/src/testing/test_testing_topology_blacklist.c @@ -440,7 +440,7 @@ run (void *cls, char *const *args, const char *cfgfile, "connect_topology_option_modifier", &connect_topology_option_modifier_string)) { - if (sscanf + if (SSCANF (connect_topology_option_modifier_string, "%lf", &connect_topology_option_modifier) != 1) { diff --git a/src/testing/test_testing_topology_churn.c b/src/testing/test_testing_topology_churn.c index 3612089..9c0bbf2 100644 --- a/src/testing/test_testing_topology_churn.c +++ b/src/testing/test_testing_topology_churn.c @@ -25,7 +25,6 @@ #include "gnunet_testing_lib.h" #include "gnunet_core_service.h" -#define VERBOSE GNUNET_YES /** * How long until we fail the whole testcase? @@ -83,17 +82,13 @@ shutdown_callback (void *cls, const char *emsg) { if (emsg != NULL) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); -#endif if (ok == 0) ok = 666; } else { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); -#endif } } @@ -104,20 +99,11 @@ finish_testing () if (die_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (die_task); - -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called finish testing, stopping daemons.\n"); -#endif - -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calling daemons_stop\n"); -#endif GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "daemons_stop finished\n"); -#endif - ok = 0; } @@ -212,17 +198,13 @@ peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, return; } GNUNET_assert (id != NULL); -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n", (num_peers - peers_left) + 1, num_peers); -#endif peers_left--; if (peers_left == 0) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All %d daemons started, now testing churn!\n", num_peers); -#endif GNUNET_SCHEDULER_cancel (die_task); /* Set up task in case topology creation doesn't finish * within a reasonable amount of time */ @@ -242,11 +224,8 @@ run (void *cls, char *const *args, const char *cfgfile, { ok = 1; -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons based on config file %s\n", cfgfile); -#endif - if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", &test_directory)) @@ -295,9 +274,6 @@ check () char *const argv[] = { "test-testing-topology-churn", "-c", "test_testing_data_topology_churn.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -323,11 +299,7 @@ main (int argc, char *argv[]) int ret; GNUNET_log_setup ("test_testing_topology_churn", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); diff --git a/src/testing/testing.c b/src/testing/testing.c index 16cee90..31bea06 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c @@ -37,10 +37,6 @@ #include "gnunet_transport_service.h" #include "gnunet_hello_lib.h" -#define DEBUG_TESTING GNUNET_EXTRA_LOGGING - -#define DEBUG_TESTING_RECONNECT GNUNET_EXTRA_LOGGING - /** * Hack to deal with initial HELLO's being often devoid of addresses. * This hack causes 'process_hello' to ignore HELLOs without addresses. @@ -192,7 +188,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { case SP_COPYING: /* confirm copying complete */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code)) + if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_copying, &type, &code)) { if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) { @@ -218,7 +214,8 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) cb (d->cb_cls, NULL, d->cfg, d, _("`scp' did not complete cleanly.\n")); return; } - GNUNET_OS_process_close (d->proc); + GNUNET_OS_process_destroy (d->proc_arm_copying); + d->proc_arm_copying = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully copied configuration file.\n"); d->phase = SP_COPIED; @@ -227,6 +224,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) /* Start create hostkey process if we don't already know the peer identity! */ if (GNUNET_NO == d->have_hostkey) { + GNUNET_assert (NULL == d->proc_arm_peerinfo); d->pipe_stdout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_YES); if (d->pipe_stdout == NULL) { @@ -246,7 +244,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) "Starting `%s', with command `%s %s %s %s'.\n", "gnunet-peerinfo", "gnunet-peerinfo", "-c", d->cfgfile, "-sq"); - d->proc = + d->proc_arm_peerinfo = GNUNET_OS_start_process (GNUNET_YES, NULL, d->pipe_stdout, "gnunet-peerinfo", "gnunet-peerinfo", "-c", d->cfgfile, "-sq", NULL); @@ -265,28 +263,24 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) d->cfgfile, "-sq"); if (d->ssh_port_str == NULL) { - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, d->pipe_stdout, "ssh", "ssh", -#if !DEBUG_TESTING + d->proc_arm_peerinfo = GNUNET_OS_start_process (GNUNET_NO, NULL, d->pipe_stdout, "ssh", "ssh", "-q", -#endif dst, "gnunet-peerinfo", "-c", d->cfgfile, "-sq", NULL); } else { - d->proc = + d->proc_arm_peerinfo = GNUNET_OS_start_process (GNUNET_NO, NULL, d->pipe_stdout, "ssh", "ssh", "-p", d->ssh_port_str, -#if !DEBUG_TESTING "-q", -#endif dst, "gnunet-peerinfo", "-c", d->cfgfile, "-sq", NULL); } GNUNET_DISK_pipe_close_end (d->pipe_stdout, GNUNET_DISK_PIPE_END_WRITE); GNUNET_free (dst); } - if (NULL == d->proc) + if (NULL == d->proc_arm_peerinfo) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not start `%s' process to create hostkey.\n"), @@ -366,10 +360,10 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) d->cb = NULL; GNUNET_DISK_pipe_close (d->pipe_stdout); d->pipe_stdout = NULL; - (void) GNUNET_OS_process_kill (d->proc, SIGKILL); - GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc)); - GNUNET_OS_process_close (d->proc); - d->proc = NULL; + (void) GNUNET_OS_process_kill (d->proc_arm_peerinfo, SIGKILL); + GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc_arm_peerinfo)); + GNUNET_OS_process_destroy (d->proc_arm_peerinfo); + d->proc_arm_peerinfo = NULL; if (NULL != cb) cb (d->cb_cls, NULL, d->cfg, d, _("Failed to get hostkey!\n")); return; @@ -377,10 +371,10 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) d->shortname = GNUNET_strdup (GNUNET_i2s (&d->id)); GNUNET_DISK_pipe_close (d->pipe_stdout); d->pipe_stdout = NULL; - (void) GNUNET_OS_process_kill (d->proc, SIGKILL); - GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc)); - GNUNET_OS_process_close (d->proc); - d->proc = NULL; + (void) GNUNET_OS_process_kill (d->proc_arm_peerinfo, SIGKILL); + GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc_arm_peerinfo)); + GNUNET_OS_process_destroy (d->proc_arm_peerinfo); + d->proc_arm_peerinfo = NULL; d->have_hostkey = GNUNET_YES; if (d->hostkey_callback != NULL) { @@ -416,13 +410,12 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (NULL == d->hostname) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting `%s', with command `%s %s %s %s %s %s'.\n", - "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, "-L", "DEBUG", + "Starting `%s', with command `%s %s %s %s'.\n", + "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, "-s"); - d->proc = + d->proc_arm_start = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, - "-L", "DEBUG", "-s", "-q", "-T", GNUNET_TIME_relative_to_string (GNUNET_TIME_absolute_get_remaining @@ -436,19 +429,14 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) dst = GNUNET_strdup (d->hostname); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Starting `%s', with command `%s %s %s %s %s %s %s %s'.\n", + "Starting `%s', with command `%s %s %s %s %s %s %s'.\n", "gnunet-arm", "ssh", dst, "gnunet-arm", "-c", d->cfgfile, - "-L", "DEBUG", "-s", "-q"); + "-s", "-q"); if (d->ssh_port_str == NULL) { - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", -#if !DEBUG_TESTING + d->proc_arm_start = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-q", -#endif dst, "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif "-c", d->cfgfile, "-s", "-q", "-T", GNUNET_TIME_relative_to_string (GNUNET_TIME_absolute_get_remaining @@ -457,16 +445,11 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) else { - d->proc = + d->proc_arm_start = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-p", d->ssh_port_str, -#if !DEBUG_TESTING "-q", -#endif dst, "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif "-c", d->cfgfile, "-s", "-q", "-T", GNUNET_TIME_relative_to_string (GNUNET_TIME_absolute_get_remaining @@ -474,7 +457,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } GNUNET_free (dst); } - if (NULL == d->proc) + if (NULL == d->proc_arm_start) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not start `%s' process to start GNUnet.\n"), @@ -495,9 +478,10 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) d->task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, d); + // FIXME: busy wait? break; case SP_START_ARMING: - if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code)) + if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_start, &type, &code)) { if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) { @@ -520,10 +504,12 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } GNUNET_free_non_null (d->hostname); GNUNET_free_non_null (d->username); - GNUNET_free (d->proc); -// GNUNET_free (d); // FIXME (could this leak) + GNUNET_OS_process_destroy (d->proc_arm_start); + d->proc_arm_start = NULL; + d->username = NULL; d->hostname = NULL; // Quick hack to avoid crashing (testing need to be d->cfg = NULL; // overhauled anyway, and the error managing is + // GNUNET_free (d); // FIXME (could this leak) // pretty broken anyway. return; } @@ -531,11 +517,13 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) d->task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, d); + // FIXME: busy wait? return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully started `%s'.\n", "gnunet-arm"); - GNUNET_free (d->proc); + GNUNET_OS_process_destroy (d->proc_arm_start); + d->proc_arm_start = NULL; d->phase = SP_START_CORE; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calling CORE_connect\n"); /* Fall through */ @@ -600,7 +588,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) break; case SP_SERVICE_START: /* confirm gnunet-arm exited */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code)) + if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_srv_start, &type, &code)) { if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) { @@ -640,10 +628,12 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) d->phase = SP_START_DONE; if (NULL != cb) cb (d->cb_cls, &d->id, d->cfg, d, NULL); + GNUNET_OS_process_destroy (d->proc_arm_srv_start); + d->proc_arm_srv_start = NULL; break; case SP_SERVICE_SHUTDOWN_START: /* confirm copying complete */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code)) + if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_srv_stop, &type, &code)) { if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) { @@ -674,8 +664,8 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) d->dead_cb (d->dead_cb_cls, NULL); break; case SP_SHUTDOWN_START: - /* confirm copying complete */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code)) + /* confirm copying complete !??? */ + if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_stop, &type, &code)) { if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) { @@ -704,8 +694,8 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_free_non_null (d->hostname); GNUNET_free_non_null (d->username); GNUNET_free_non_null (d->shortname); - GNUNET_free_non_null (d->proc); - d->proc = NULL; + GNUNET_OS_process_destroy (d->proc_arm_stop); + d->proc_arm_stop = NULL; GNUNET_free (d); return; } @@ -740,8 +730,8 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_free_non_null (d->hostname); GNUNET_free_non_null (d->username); GNUNET_free_non_null (d->shortname); - GNUNET_free_non_null (d->proc); - d->proc = NULL; + GNUNET_OS_process_destroy (d->proc_arm_stop); + d->proc_arm_stop = NULL; GNUNET_free (d); return; } @@ -776,8 +766,8 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_free_non_null (d->hello); d->hello = NULL; GNUNET_free_non_null (d->shortname); - GNUNET_free_non_null (d->proc); - d->proc = NULL; + GNUNET_OS_process_destroy (d->proc_arm_stop); + d->proc_arm_stop = NULL; d->shortname = NULL; if (d->churn == GNUNET_NO) GNUNET_free (d); @@ -785,7 +775,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) break; case SP_CONFIG_UPDATE: /* confirm copying complete */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code)) + if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_copying, &type, &code)) { if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) /* FIXME: config update should take timeout parameter! */ { @@ -902,14 +892,9 @@ GNUNET_TESTING_daemon_start_stopped_service (struct GNUNET_TESTING_Daemon *d, else arg = GNUNET_strdup (d->hostname); - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", -#if !DEBUG_TESTING + d->proc_arm_srv_start = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-q", -#endif arg, "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif "-c", d->cfgfile, "-i", service, "-q", "-T", GNUNET_TIME_relative_to_string (timeout), @@ -923,10 +908,7 @@ GNUNET_TESTING_daemon_start_stopped_service (struct GNUNET_TESTING_Daemon *d, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif + d->proc_arm_srv_start = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, "-i", service, "-q", "-T", GNUNET_TIME_relative_to_string (timeout), @@ -978,14 +960,9 @@ GNUNET_TESTING_daemon_start_service (struct GNUNET_TESTING_Daemon *d, else arg = GNUNET_strdup (d->hostname); - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", -#if !DEBUG_TESTING + d->proc_arm_srv_start = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-q", -#endif arg, "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif "-c", d->cfgfile, "-i", service, "-q", "-T", GNUNET_TIME_relative_to_string (timeout), @@ -1000,10 +977,7 @@ GNUNET_TESTING_daemon_start_service (struct GNUNET_TESTING_Daemon *d, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif + d->proc_arm_srv_start = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, "-i", service, "-q", "-T", GNUNET_TIME_relative_to_string (timeout), @@ -1210,10 +1184,8 @@ GNUNET_TESTING_daemon_start (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_free (baseservicehome); if (ret->ssh_port_str == NULL) { - ret->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", "-r", -#if !DEBUG_TESTING + ret->proc_arm_copying = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", "-r", "-q", -#endif servicehome, arg, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "copying directory with command scp -r %s %s\n", @@ -1221,16 +1193,14 @@ GNUNET_TESTING_daemon_start (const struct GNUNET_CONFIGURATION_Handle *cfg, } else { - ret->proc = + ret->proc_arm_copying = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", "-r", "-P", ret->ssh_port_str, -#if !DEBUG_TESTING "-q", -#endif servicehome, arg, NULL); } GNUNET_free (arg); - if (NULL == ret->proc) + if (NULL == ret->proc_arm_copying) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ @@ -1334,14 +1304,9 @@ GNUNET_TESTING_daemon_restart (struct GNUNET_TESTING_Daemon *d, else arg = GNUNET_strdup (d->hostname); - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", -#if !DEBUG_TESTING + d->proc_arm_stop = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-q", -#endif arg, "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif "-c", d->cfgfile, "-e", "-r", NULL); /* Use -r to restart arm and all services */ @@ -1351,10 +1316,7 @@ GNUNET_TESTING_daemon_restart (struct GNUNET_TESTING_Daemon *d, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif + d->proc_arm_stop = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, "-e", "-r", NULL); } @@ -1414,15 +1376,10 @@ GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d, GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname); else arg = GNUNET_strdup (d->hostname); - - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", -#if !DEBUG_TESTING + + d->proc_arm_srv_stop = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-q", -#endif arg, "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif "-c", d->cfgfile, "-k", service, "-q", "-T", GNUNET_TIME_relative_to_string (timeout), @@ -1436,10 +1393,7 @@ GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif + d->proc_arm_srv_stop = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, "-k", service, "-q", "-T", GNUNET_TIME_relative_to_string (timeout), @@ -1451,6 +1405,20 @@ GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d, } +/** + * Forcefully terminate a process and clean up the child. + * + * @param proc handle to process to kill + */ +static void +kill_and_close_process (struct GNUNET_OS_Process *proc) +{ + (void) GNUNET_OS_process_kill (proc, SIGKILL); + GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (proc)); + GNUNET_OS_process_destroy (proc); +} + + /** * Stops a GNUnet daemon. * @@ -1482,10 +1450,35 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d, d->dead = GNUNET_YES; return; } - - if ((d->running == GNUNET_NO) && (d->churn == GNUNET_YES)) /* Peer has already been stopped in churn context! */ + if (NULL != d->proc_arm_start) + { + kill_and_close_process (d->proc_arm_start); + d->proc_arm_start = NULL; + } + if (NULL != d->proc_arm_srv_start) { - /* Free what was left from churning! */ + kill_and_close_process (d->proc_arm_srv_start); + d->proc_arm_srv_start = NULL; + } + if (NULL != d->proc_arm_srv_stop) + { + kill_and_close_process (d->proc_arm_srv_stop); + d->proc_arm_srv_stop = NULL; + } + if (NULL != d->proc_arm_copying) + { + kill_and_close_process (d->proc_arm_copying); + d->proc_arm_copying = NULL; + } + if (NULL != d->proc_arm_peerinfo) + { + kill_and_close_process (d->proc_arm_peerinfo); + d->proc_arm_peerinfo = NULL; + } + if ((d->running == GNUNET_NO) && (d->churn == GNUNET_YES)) + { + /* Peer has already been stopped in churn context! + * Free what was left from churning! */ GNUNET_assert (d->cfg != NULL); GNUNET_CONFIGURATION_destroy (d->cfg); if (delete_files == GNUNET_YES) @@ -1500,6 +1493,10 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d, GNUNET_free_non_null (d->username); if (NULL != d->dead_cb) d->dead_cb (d->dead_cb_cls, NULL); + /* FIXME: this should be an assert and the test below + should not be required, but testing is broken... */ + GNUNET_break (NULL == d->proc_arm_stop); + if (NULL == d->proc_arm_stop) GNUNET_free (d); return; } @@ -1537,6 +1534,8 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d, d->th = NULL; } /* Check if this is a local or remote process */ + + if (NULL != d->hostname) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1547,14 +1546,9 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d, else arg = GNUNET_strdup (d->hostname); - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", -#if !DEBUG_TESTING + d->proc_arm_stop = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-q", -#endif arg, "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif "-c", d->cfgfile, "-e", "-q", "-T", GNUNET_TIME_relative_to_string (timeout), del_arg, NULL); @@ -1568,14 +1562,11 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "gnunet-arm", "gnunet-arm", -#if DEBUG_TESTING - "-L", "DEBUG", -#endif + d->proc_arm_stop = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, "-e", "-q", "-T", GNUNET_TIME_relative_to_string (timeout), del_arg, NULL); - GNUNET_assert (NULL != d->proc); + GNUNET_assert (NULL != d->proc_arm_stop); } GNUNET_free_non_null (del_arg); @@ -1635,13 +1626,11 @@ GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d, GNUNET_asprintf (&arg, "%s@%s:%s", d->username, d->hostname, d->cfgfile); else GNUNET_asprintf (&arg, "%s:%s", d->hostname, d->cfgfile); - d->proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", -#if !DEBUG_TESTING + d->proc_arm_copying = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", "-q", -#endif d->cfgfile, arg, NULL); GNUNET_free (arg); - if (NULL == d->proc) + if (NULL == d->proc_arm_copying) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not start `%s' process to copy configuration file.\n"), @@ -2173,7 +2162,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asked to connect peer %s to peer %s\n", d1->shortname, d2->shortname); /* Core is up! Iterate over all _known_ peers first to check if we are already connected to the peer! */ - GNUNET_assert (GNUNET_OK == + GNUNET_assert (NULL != GNUNET_CORE_is_peer_connected (ctx->d1->cfg, &ctx->d2->id, &core_initial_iteration, ctx)); return ctx; diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c index 2d0e9ef..75c0e61 100644 --- a/src/testing/testing_group.c +++ b/src/testing/testing_group.c @@ -30,12 +30,6 @@ #include "gnunet_testing_lib.h" #include "gnunet_core_service.h" -#define VERBOSE_TESTING GNUNET_NO - -#define VERBOSE_TOPOLOGY GNUNET_NO - -#define DEBUG_CHURN GNUNET_EXTRA_LOGGING - #define USE_START_HELPER GNUNET_YES #define OLD 1 @@ -1357,7 +1351,7 @@ update_config (void *cls, const char *section, const char *option, GNUNET_asprintf (&single_variable, "single_%s_per_host", section); GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section); - if ((0 == strcmp (option, "PORT")) && (1 == sscanf (value, "%u", &ival))) + if ((0 == strcmp (option, "PORT")) && (1 == SSCANF (value, "%u", &ival))) { if ((ival != 0) && (GNUNET_YES != @@ -1510,9 +1504,7 @@ GNUNET_TESTING_create_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, uint32 ""); GNUNET_CONFIGURATION_set_value_string (uc.ret, "nse", "UNIXPATH", ""); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "transport-tcp", - "USE_LOCALADDR", "YES"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "transport-udp", + GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "USE_LOCALADDR", "YES"); GNUNET_free_non_null (control_host); GNUNET_free (allowed_hosts); @@ -1540,10 +1532,7 @@ GNUNET_TESTING_create_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, uint32 } else { - - GNUNET_CONFIGURATION_set_value_string (uc.ret, "transport-tcp", - "USE_LOCALADDR", "YES"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "transport-udp", + GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "USE_LOCALADDR", "YES"); GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "BINDTO", "127.0.0.1"); @@ -1835,17 +1824,13 @@ create_scale_free (struct GNUNET_TESTING_PeerGroup *pg, ((double) GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX)) / ((double) UINT64_MAX); -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Considering connecting peer %d to peer %d\n", outer_count, i); -#endif if (random < probability) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", outer_count, i); -#endif total_connections += proc (pg, outer_count, i, list, GNUNET_YES); } } @@ -1904,7 +1889,7 @@ create_small_world_ring (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PERCENTAGE", &p_string)) { - if (sscanf (p_string, "%lf", &logNModifier) != 1) + if (SSCANF (p_string, "%lf", &logNModifier) != 1) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), @@ -1916,7 +1901,7 @@ create_small_world_ring (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PROBABILITY", &p_string)) { - if (sscanf (p_string, "%lf", &probability) != 1) + if (SSCANF (p_string, "%lf", &probability) != 1) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), @@ -1929,7 +1914,7 @@ create_small_world_ring (struct GNUNET_TESTING_PeerGroup *pg, if (connsPerPeer % 2 == 1) connsPerPeer += 1; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Target is %d connections per peer."), + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Target is %d connections per peer.", connsPerPeer); smallWorldConnections = 0; @@ -2017,7 +2002,7 @@ create_nated_internet (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PERCENTAGE", &p_string)) { - if (sscanf (p_string, "%lf", &nat_percentage) != 1) + if (SSCANF (p_string, "%lf", &nat_percentage) != 1) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), @@ -2033,10 +2018,8 @@ create_nated_internet (struct GNUNET_TESTING_PeerGroup *pg, { if ((outer_count > cutoff) || (inner_count > cutoff)) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", outer_count, inner_count); -#endif connect_attempts += proc (pg, outer_count, inner_count, list, GNUNET_YES); } @@ -2076,7 +2059,7 @@ create_nated_internet_copy (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PERCENTAGE", &p_string)) { - if (sscanf (p_string, "%lf", &nat_percentage) != 1) + if (SSCANF (p_string, "%lf", &nat_percentage) != 1) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), @@ -2104,10 +2087,8 @@ create_nated_internet_copy (struct GNUNET_TESTING_PeerGroup *pg, { if ((outer_count > cutoff) || (inner_count > cutoff)) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", outer_count, inner_count); -#endif connect_attempts += proc (pg, outer_count, inner_count, list, GNUNET_YES); add_connections (pg, outer_count, inner_count, ALLOWED, GNUNET_NO); @@ -2165,7 +2146,7 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PERCENTAGE", &p_string)) { - if (sscanf (p_string, "%lf", &percentage) != 1) + if (SSCANF (p_string, "%lf", &percentage) != 1) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), @@ -2185,7 +2166,7 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PROBABILITY", &p_string)) { - if (sscanf (p_string, "%lf", &probability) != 1) + if (SSCANF (p_string, "%lf", &probability) != 1) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), @@ -2204,12 +2185,9 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg, toggle++; } } -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Connecting nodes in 2d torus topology: %u rows %u columns\n"), + "Connecting nodes in 2d torus topology: %u rows %u columns\n", rows, cols); -#endif - connect_attempts = 0; /* Rows and columns are all sorted out, now iterate over all nodes and connect each * to the node to its right and above. Once this is over, we'll have our torus! @@ -2241,13 +2219,11 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg, connect_attempts += proc (pg, i, nodeToConnect, list, GNUNET_YES); } natLog = log (pg->total); -#if VERBOSE_TESTING > 2 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("natural log of %d is %d, will run %d iterations\n"), pg->total, + "natural log of %d is %d, will run %d iterations\n", pg->total, natLog, (int) (natLog * percentage)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Total connections added thus far: %u!\n"), connect_attempts); -#endif + "Total connections added thus far: %u!\n", connect_attempts); smallWorldConnections = 0; small_world_it = (unsigned int) (natLog * percentage); if (small_world_it < 1) @@ -2285,11 +2261,9 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg, } } connect_attempts += smallWorldConnections; -#if VERBOSE_TESTING > 2 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Total connections added for small world: %d!\n"), + "Total connections added for small world: %d!\n", smallWorldConnections); -#endif return connect_attempts; } @@ -2322,7 +2296,7 @@ create_erdos_renyi (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PROBABILITY", &p_string)) { - if (sscanf (p_string, "%lf", &probability) != 1) + if (SSCANF (p_string, "%lf", &probability) != 1) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), @@ -2338,10 +2312,8 @@ create_erdos_renyi (struct GNUNET_TESTING_PeerGroup *pg, ((double) GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX)) / ((double) UINT64_MAX); -#if VERBOSE_TESTING - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("rand is %f probability is %f\n"), + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "rand is %f probability is %f\n", temp_rand, probability); -#endif if (temp_rand < probability) { connect_attempts += @@ -2397,11 +2369,9 @@ create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg, toggle++; } } -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Connecting nodes in 2d torus topology: %u rows %u columns\n"), + "Connecting nodes in 2d torus topology: %u rows %u columns\n", rows, cols); -#endif /* Rows and columns are all sorted out, now iterate over all nodes and connect each * to the node to its right and above. Once this is over, we'll have our torus! * Special case for the last node (if the rows and columns are not equal), connect @@ -2416,10 +2386,8 @@ create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg, nodeToConnect = rows * cols - cols; else nodeToConnect = i - cols + 1; -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", i, nodeToConnect); -#endif connect_attempts += proc (pg, i, nodeToConnect, list, GNUNET_YES); /* Second connect to the node immediately above */ @@ -2434,10 +2402,8 @@ create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg, if (nodeToConnect < pg->total) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", i, nodeToConnect); -#endif connect_attempts += proc (pg, i, nodeToConnect, list, GNUNET_YES); } @@ -2479,10 +2445,8 @@ create_clique (struct GNUNET_TESTING_PeerGroup *pg, { for (inner_count = outer_count + 1; inner_count < pg->total; inner_count++) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", outer_count, inner_count); -#endif connect_attempts += proc (pg, outer_count, inner_count, list, check); update_meter (conn_meter); } @@ -2590,10 +2554,8 @@ create_line (struct GNUNET_TESTING_PeerGroup *pg, /* Connect each peer to the next highest numbered peer */ for (count = 0; count < pg->total - 1; count++) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", count, count + 1); -#endif connect_attempts += proc (pg, count, count + 1, list, GNUNET_YES); } @@ -2675,10 +2637,8 @@ create_from_file (struct GNUNET_TESTING_PeerGroup *pg, char *filename, GNUNET_free (data); return connect_attempts; } -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u total peers in topology\n", total_peers); -#endif GNUNET_assert (total_peers == pg->total); curr_state = PEER_INDEX; while ((buf[count] != '\n') && (count < frstat.st_size - 1)) @@ -2769,10 +2729,8 @@ create_ring (struct GNUNET_TESTING_PeerGroup *pg, /* Connect each peer to the next highest numbered peer */ for (count = 0; count < pg->total - 1; count++) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", count, count + 1); -#endif connect_attempts += proc (pg, count, count + 1, list, GNUNET_YES); } @@ -2927,15 +2885,10 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg) if (pg->peers[pg_iter].daemon->hostname == NULL) /* Local, just copy the file */ { GNUNET_asprintf (&arg, "%s/friends", temp_service_path); - procarr[pg_iter] = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "mv", "mv", mytemp, arg, NULL); - GNUNET_assert (procarr[pg_iter] != NULL); -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Copying file with command cp %s %s\n", mytemp, arg); -#endif - ret = GNUNET_OS_process_wait (procarr[pg_iter]); /* FIXME: schedule this, throttle! */ - GNUNET_OS_process_close (procarr[pg_iter]); + "Copying file with RENAME(%s,%s)\n", mytemp, arg); + RENAME (mytemp, arg); + procarr[pg_iter] = NULL; GNUNET_free (arg); } else /* Remote, scp the file to the correct place */ @@ -2953,7 +2906,7 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg) GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", mytemp, arg, NULL); GNUNET_assert (procarr[pg_iter] != NULL); ret = GNUNET_OS_process_wait (procarr[pg_iter]); /* FIXME: schedule this, throttle! */ - GNUNET_OS_process_close (procarr[pg_iter]); + GNUNET_OS_process_destroy (procarr[pg_iter]); if (ret != GNUNET_OK) { /* FIXME: free contents of 'procarr' array */ @@ -2964,10 +2917,8 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg) return ret; } procarr[pg_iter] = NULL; -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Copying file with command scp %s %s\n", mytemp, arg); -#endif GNUNET_free (arg); } GNUNET_free (temp_service_path); @@ -2982,10 +2933,8 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg) ret = GNUNET_OK; for (pg_iter = 0; pg_iter < pg->total; pg_iter++) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking copy status of file %d\n", pg_iter); -#endif if (procarr[pg_iter] != NULL) /* Check for already completed! */ { if (GNUNET_OS_process_status (procarr[pg_iter], &type, &return_code) != @@ -2999,11 +2948,9 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg) } else { - GNUNET_OS_process_close (procarr[pg_iter]); + GNUNET_OS_process_destroy (procarr[pg_iter]); procarr[pg_iter] = NULL; -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "File %d copied\n", pg_iter); -#endif } } } @@ -3015,10 +2962,8 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg) } } -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Finished copying all friend files!\n")); -#endif + "Finished copying all friend files!\n"); #endif GNUNET_free (procarr); return ret; @@ -3126,13 +3071,10 @@ create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg, if (pg->peers[pg_iter].daemon->hostname == NULL) /* Local, just copy the file */ { GNUNET_asprintf (&arg, "%s/blacklist", temp_service_path); - procarr[pg_iter] = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "mv", "mv", mytemp, arg, NULL); -#if VERBOSE_TESTING + RENAME (mytemp, arg); + procarr[pg_iter] = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Copying file with command cp %s %s\n"), mytemp, arg); -#endif - + "Copying file with RENAME (%s,%s)\n", mytemp, arg); GNUNET_free (arg); } else /* Remote, scp the file to the correct place */ @@ -3151,10 +3093,8 @@ create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_assert (procarr[pg_iter] != NULL); GNUNET_OS_process_wait (procarr[pg_iter]); /* FIXME: add scheduled blacklist file copy that parallelizes file copying! */ -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Copying file with command scp %s %s\n"), mytemp, arg); -#endif + "Copying file with command scp %s %s\n", mytemp, arg); GNUNET_free (arg); } GNUNET_free (temp_service_path); @@ -3168,10 +3108,8 @@ create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg, ret = GNUNET_OK; for (pg_iter = 0; pg_iter < pg->total; pg_iter++) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Checking copy status of file %d\n"), pg_iter); -#endif + "Checking copy status of file %d\n", pg_iter); if (procarr[pg_iter] != NULL) /* Check for already completed! */ { if (GNUNET_OS_process_status (procarr[pg_iter], &type, &return_code) != @@ -3185,11 +3123,9 @@ create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg, } else { - GNUNET_OS_process_close (procarr[pg_iter]); + GNUNET_OS_process_destroy (procarr[pg_iter]); procarr[pg_iter] = NULL; -#if VERBOSE_TESTING - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("File %d copied\n"), pg_iter); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "File %d copied\n", pg_iter); } } } @@ -3201,10 +3137,8 @@ create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg, } } -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Finished copying all blacklist files!\n")); -#endif + "Finished copying all blacklist files!\n"); GNUNET_free (procarr); return ret; } @@ -3401,11 +3335,8 @@ core_connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, #if BAD struct PeerData *other_peer; #endif -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected peer %s to peer %s\n", ctx->d1->shortname, GNUNET_i2s (peer)); -#endif - if (0 == memcmp (&send_hello_context->peer->daemon->id, peer, sizeof (struct GNUNET_PeerIdentity))) @@ -3523,16 +3454,12 @@ hello_sent_callback (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } send_hello_context->pg->remaining_hellos--; -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent HELLO, have %d remaining!\n", send_hello_context->pg->remaining_hellos); -#endif if (send_hello_context->peer_pos == NULL) /* All HELLOs (for this peer!) have been transmitted! */ { -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All hellos for this peer sent, disconnecting transport!\n"); -#endif GNUNET_assert (send_hello_context->peer->daemon->th != NULL); GNUNET_TRANSPORT_disconnect (send_hello_context->peer->daemon->th); send_hello_context->peer->daemon->th = NULL; @@ -3580,22 +3507,17 @@ schedule_send_hellos (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) (pg->outstanding_connects > pg->max_outstanding_connections)) || (pg->stop_connects == GNUNET_YES)) { -#if VERBOSE_TESTING > 2 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Delaying connect, we have too many outstanding connections!\n")); -#endif + "Delaying connect, we have too many outstanding connections!\n"); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100), &schedule_send_hellos, send_hello_context); } else { -#if VERBOSE_TESTING > 2 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating connection, outstanding_connections is %d\n"), + "Creating connection, outstanding_connections is %d\n", outstanding_connects); -#endif if (send_hello_context->peer->daemon->th == NULL) { pg->outstanding_connects++; /* Actual TRANSPORT, CORE connections! */ @@ -3603,13 +3525,11 @@ schedule_send_hellos (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_TRANSPORT_connect (send_hello_context->peer->cfg, NULL, send_hello_context, NULL, NULL, NULL); } -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Offering HELLO of peer %s to peer %s\n"), + "Offering HELLO of peer %s to peer %s\n", send_hello_context->peer->daemon->shortname, pg->peers[send_hello_context->peer_pos->index]. daemon->shortname); -#endif GNUNET_TRANSPORT_offer_hello (send_hello_context->peer->daemon->th, (const struct GNUNET_MessageHeader *) pg->peers[send_hello_context->peer_pos-> @@ -3717,23 +3637,17 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if ((pg->outstanding_connects > pg->max_outstanding_connections) || (pg->stop_connects == GNUNET_YES)) { -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Delaying connect, we have too many outstanding connections!\n")); -#endif + "Delaying connect, we have too many outstanding connections!\n"); connect_context->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100), &schedule_connect, connect_context); return; } -#if VERBOSE_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Creating connection, outstanding_connections is %d (max %d)\n"), + "Creating connection, outstanding_connections is %d (max %d)\n", pg->outstanding_connects, pg->max_outstanding_connections); -#endif pg->outstanding_connects++; pg->total_connects_scheduled++; GNUNET_assert (NULL == connect_context->cc); @@ -3985,46 +3899,46 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, switch (topology) { case GNUNET_TESTING_TOPOLOGY_CLIQUE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating clique topology\n")); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating clique topology\n"); num_connections = create_clique (pg, &add_connections, ALLOWED, GNUNET_NO); break; case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating small world (ring) topology\n")); + "Creating small world (ring) topology\n"); num_connections = create_small_world_ring (pg, &add_connections, ALLOWED); break; case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating small world (2d-torus) topology\n")); + "Creating small world (2d-torus) topology\n"); num_connections = create_small_world (pg, &add_connections, ALLOWED); break; case GNUNET_TESTING_TOPOLOGY_RING: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating ring topology\n")); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating ring topology\n"); num_connections = create_ring (pg, &add_connections, ALLOWED); break; case GNUNET_TESTING_TOPOLOGY_2D_TORUS: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating 2d torus topology\n")); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating 2d torus topology\n"); num_connections = create_2d_torus (pg, &add_connections, ALLOWED); break; case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating Erdos-Renyi topology\n")); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating Erdos-Renyi topology\n"); num_connections = create_erdos_renyi (pg, &add_connections, ALLOWED); break; case GNUNET_TESTING_TOPOLOGY_INTERNAT: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating InterNAT topology\n")); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating InterNAT topology\n"); num_connections = create_nated_internet (pg, &add_connections, ALLOWED); break; case GNUNET_TESTING_TOPOLOGY_SCALE_FREE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating Scale Free topology\n")); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating Scale Free topology\n"); num_connections = create_scale_free (pg, &add_connections, ALLOWED); break; case GNUNET_TESTING_TOPOLOGY_LINE: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating straight line topology\n")); + "Creating straight line topology\n"); num_connections = create_line (pg, &add_connections, ALLOWED); break; case GNUNET_TESTING_TOPOLOGY_FROM_FILE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating topology from file!\n")); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating topology from file!\n"); if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (pg->cfg, "testing", "topology_file", &filename)) @@ -4055,13 +3969,13 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, if (ret != GNUNET_OK) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Failed during friend file copying!\n")); + "Failed during friend file copying!\n"); return GNUNET_SYSERR; } else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Friend files created/copied successfully!\n")); + "Friend files created/copied successfully!\n"); } } @@ -4078,43 +3992,43 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, { case GNUNET_TESTING_TOPOLOGY_CLIQUE: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but clique topology\n")); + "Blacklisting all but clique topology\n"); unblacklisted_connections = create_clique (pg, &remove_connections, BLACKLIST, GNUNET_NO); break; case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but small world (ring) topology\n")); + "Blacklisting all but small world (ring) topology\n"); unblacklisted_connections = create_small_world_ring (pg, &remove_connections, BLACKLIST); break; case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but small world (2d-torus) topology\n")); + "Blacklisting all but small world (2d-torus) topology\n"); unblacklisted_connections = create_small_world (pg, &remove_connections, BLACKLIST); break; case GNUNET_TESTING_TOPOLOGY_RING: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but ring topology\n")); + "Blacklisting all but ring topology\n"); unblacklisted_connections = create_ring (pg, &remove_connections, BLACKLIST); break; case GNUNET_TESTING_TOPOLOGY_2D_TORUS: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but 2d torus topology\n")); + "Blacklisting all but 2d torus topology\n"); unblacklisted_connections = create_2d_torus (pg, &remove_connections, BLACKLIST); break; case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but Erdos-Renyi topology\n")); + "Blacklisting all but Erdos-Renyi topology\n"); unblacklisted_connections = create_erdos_renyi (pg, &remove_connections, BLACKLIST); break; case GNUNET_TESTING_TOPOLOGY_INTERNAT: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but InterNAT topology\n")); + "Blacklisting all but InterNAT topology\n"); #if TOPOLOGY_HACK for (off = 0; off < pg->total; off++) @@ -4149,13 +4063,13 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, break; case GNUNET_TESTING_TOPOLOGY_SCALE_FREE: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but Scale Free topology\n")); + "Blacklisting all but Scale Free topology\n"); unblacklisted_connections = create_scale_free (pg, &remove_connections, BLACKLIST); break; case GNUNET_TESTING_TOPOLOGY_LINE: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklisting all but straight line topology\n")); + "Blacklisting all but straight line topology\n"); unblacklisted_connections = create_line (pg, &remove_connections, BLACKLIST); default: @@ -4170,13 +4084,13 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, if (ret != GNUNET_OK) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Failed during blacklist file copying!\n")); + "Failed during blacklist file copying!\n"); return 0; } else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklist files created/copied successfully!\n")); + "Blacklist files created/copied successfully!\n"); } } return num_connections; @@ -4878,22 +4792,14 @@ schedule_get_topology (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (topology_context->connected > topology_context->pg->max_outstanding_connections) { -#if VERBOSE_TESTING > 2 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Delaying connect, we have too many outstanding connections!\n")); -#endif + "Delaying connect, we have too many outstanding connections!\n"); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100), &schedule_get_topology, core_context); } else { -#if VERBOSE_TESTING > 2 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating connection, outstanding_connections is %d\n"), - outstanding_connects); -#endif topology_context->connected++; if (GNUNET_OK != @@ -4973,6 +4879,23 @@ internal_stats_callback (void *cls, const char *subsystem, const char *name, subsystem, name, value, is_persistent); } + +/** + * We don't need the statistics handle anymore, destroy it. + * + * @param cls Closure (the statistics handle to destroy) + * @param tc Task Context + */ +static void +internal_destroy_statistics (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_STATISTICS_Handle *h = cls; + + GNUNET_STATISTICS_destroy (h, GNUNET_NO); +} + + /** * Internal continuation call for statistics iteration. * @@ -4997,7 +4920,9 @@ internal_stats_cont (void *cls, int success) } if (core_context->stats_handle != NULL) - GNUNET_STATISTICS_destroy (core_context->stats_handle, GNUNET_NO); + /* Cannot destroy handle inside the continuation */ + GNUNET_SCHEDULER_add_now (&internal_destroy_statistics, + core_context->stats_handle); GNUNET_free (core_context); } @@ -5019,23 +4944,14 @@ schedule_get_statistics (void *cls, if (stats_context->connected > stats_context->pg->max_outstanding_connections) { -#if VERBOSE_TESTING > 2 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Delaying connect, we have too many outstanding connections!\n")); -#endif + "Delaying connect, we have too many outstanding connections!\n"); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100), &schedule_get_statistics, core_context); } else { -#if VERBOSE_TESTING > 2 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating connection, outstanding_connections is %d\n"), - outstanding_connects); -#endif - stats_context->connected++; core_context->stats_handle = GNUNET_STATISTICS_create ("testing", core_context->daemon->cfg); @@ -5047,7 +4963,7 @@ schedule_get_statistics (void *cls, core_context->stats_get_handle = GNUNET_STATISTICS_get (core_context->stats_handle, NULL, NULL, - GNUNET_TIME_relative_get_forever (), + GNUNET_TIME_UNIT_FOREVER_REL, &internal_stats_cont, &internal_stats_callback, core_context); if (core_context->stats_get_handle == NULL) @@ -5258,71 +5174,51 @@ GNUNET_TESTING_connect_topology (struct GNUNET_TESTING_PeerGroup *pg, switch (topology) { case GNUNET_TESTING_TOPOLOGY_CLIQUE: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating clique CONNECT topology\n")); -#endif + "Creating clique CONNECT topology\n"); create_clique (pg, &add_connections, CONNECT, GNUNET_NO); break; case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating small world (ring) CONNECT topology\n")); -#endif + "Creating small world (ring) CONNECT topology\n"); create_small_world_ring (pg, &add_connections, CONNECT); break; case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating small world (2d-torus) CONNECT topology\n")); -#endif + "Creating small world (2d-torus) CONNECT topology\n"); create_small_world (pg, &add_connections, CONNECT); break; case GNUNET_TESTING_TOPOLOGY_RING: -#if VERBOSE_TOPOLOGY - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating ring CONNECT topology\n")); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating ring CONNECT topology\n"); create_ring (pg, &add_connections, CONNECT); break; case GNUNET_TESTING_TOPOLOGY_2D_TORUS: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating 2d torus CONNECT topology\n")); -#endif + "Creating 2d torus CONNECT topology\n"); create_2d_torus (pg, &add_connections, CONNECT); break; case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating Erdos-Renyi CONNECT topology\n")); -#endif + "Creating Erdos-Renyi CONNECT topology\n"); create_erdos_renyi (pg, &add_connections, CONNECT); break; case GNUNET_TESTING_TOPOLOGY_INTERNAT: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating InterNAT CONNECT topology\n")); -#endif + "Creating InterNAT CONNECT topology\n"); create_nated_internet (pg, &add_connections, CONNECT); break; case GNUNET_TESTING_TOPOLOGY_SCALE_FREE: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating Scale Free CONNECT topology\n")); -#endif + "Creating Scale Free CONNECT topology\n"); create_scale_free (pg, &add_connections, CONNECT); break; case GNUNET_TESTING_TOPOLOGY_LINE: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Creating straight line CONNECT topology\n")); -#endif + "Creating straight line CONNECT topology\n"); create_line (pg, &add_connections, CONNECT); break; case GNUNET_TESTING_TOPOLOGY_NONE: -#if VERBOSE_TOPOLOGY - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Creating no CONNECT topology\n")); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating no CONNECT topology\n"); copy_allowed_topology (pg); break; default: @@ -5334,39 +5230,29 @@ GNUNET_TESTING_connect_topology (struct GNUNET_TESTING_PeerGroup *pg, switch (options) { case GNUNET_TESTING_TOPOLOGY_OPTION_RANDOM: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Connecting random subset (%'.2f percent) of possible peers\n"), + "Connecting random subset (%'.2f percent) of possible peers\n", 100 * option_modifier); -#endif choose_random_connections (pg, option_modifier); break; case GNUNET_TESTING_TOPOLOGY_OPTION_MINIMUM: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Connecting a minimum of %u peers each (if possible)\n"), + "Connecting a minimum of %u peers each (if possible)\n", (unsigned int) option_modifier); -#endif choose_minimum (pg, (unsigned int) option_modifier); break; case GNUNET_TESTING_TOPOLOGY_OPTION_DFS: -#if VERBOSE_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Using DFS to connect a minimum of %u peers each (if possible)\n"), + "Using DFS to connect a minimum of %u peers each (if possible)\n", (unsigned int) option_modifier); -#endif #if FIXME perform_dfs (pg, (int) option_modifier); #endif break; case GNUNET_TESTING_TOPOLOGY_OPTION_ADD_CLOSEST: -#if VERBOSE_TOPOLOGY - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Finding additional %u closest peers each (if possible)\n"), + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Finding additional %u closest peers each (if possible)\n", (unsigned int) option_modifier); -#endif #if FIXME add_closest (pg, (unsigned int) option_modifier, &add_connections, CONNECT); #endif @@ -5418,9 +5304,9 @@ increment_outstanding_at_host (const char *hostname, struct OutstandingSSH *pos; pos = pg->ssh_head; - while ((pos != NULL) && (strcmp (pos->hostname, hostname) != 0)) + while ((NULL != pos) && (strcmp (pos->hostname, hostname) != 0)) pos = pos->next; - GNUNET_assert (pos != NULL); + GNUNET_assert (NULL != pos); pos->outstanding++; } @@ -5781,7 +5667,7 @@ check_peers_started (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } } - GNUNET_OS_process_close (helper->proc); + GNUNET_OS_process_destroy (helper->proc); } static void @@ -5809,10 +5695,8 @@ start_peer_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", arg, "peerStartHelper.pl", tempdir, NULL); GNUNET_assert (helper->proc != NULL); -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting peers with cmd ssh %s %s %s\n", arg, "peerStartHelper.pl", tempdir); -#endif GNUNET_SCHEDULER_add_now (&check_peers_started, helper); GNUNET_free (tempdir); GNUNET_free (baseservicehome); @@ -6032,9 +5916,7 @@ GNUNET_TESTING_daemons_start (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_asprintf (&ssh_port_str, "%d", pg->hosts[i].sshport); proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-P", ssh_port_str, -#if !DEBUG_TESTING "-q", -#endif arg, "mkdir -p", tmpdir, NULL); } else @@ -6048,7 +5930,7 @@ GNUNET_TESTING_daemons_start (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_free (tmpdir); GNUNET_free (arg); GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); } GNUNET_free (baseservicehome); baseservicehome = NULL; @@ -6081,12 +5963,10 @@ GNUNET_TESTING_daemons_start (const struct GNUNET_CONFIGURATION_Handle *cfg, return NULL; } - if (GNUNET_YES != GNUNET_DISK_file_size (hostkeys_file, &fs, GNUNET_YES)) + if (GNUNET_OK != GNUNET_DISK_file_size (hostkeys_file, &fs, GNUNET_YES, GNUNET_YES)) fs = 0; -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found file size %llu for hostkeys\n", fs); -#endif if (0 != (fs % HOSTKEYFILESIZE)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -6229,10 +6109,8 @@ GNUNET_TESTING_daemons_start (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "SERVICEHOME", &baseservicehome)) { -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "baseservice home is %s\n", baseservicehome); -#endif if (hostname != NULL) GNUNET_asprintf (&newservicehome, "%s/%s/", baseservicehome, hostname); @@ -6264,11 +6142,9 @@ GNUNET_TESTING_daemons_start (const struct GNUNET_CONFIGURATION_Handle *cfg, proc = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "rsync", "rsync", "-r", newservicehome, arg, NULL); -#if DEBUG_TESTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "copying directory with command rsync -r %s %s\n", newservicehome, arg); -#endif GNUNET_free (newservicehome); GNUNET_free (arg); if (NULL == proc) @@ -6280,7 +6156,7 @@ GNUNET_TESTING_daemons_start (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_assert (0); } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); } /* Now all the configuration files and hostkeys are copied to the remote host. Call the hostkey callback for each peer! */ GNUNET_SCHEDULER_add_now (&call_hostkey_callbacks, pg); @@ -6684,10 +6560,8 @@ GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg, for (i = 0; i < voff; i++) { -#if DEBUG_CHURN GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peer %d!\n", running_arr[running_permute[i]]); -#endif GNUNET_assert (running_arr != NULL); peer_shutdown_ctx = GNUNET_malloc (sizeof (struct PeerShutdownContext)); peer_shutdown_ctx->daemon = @@ -6706,10 +6580,8 @@ GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg, } for (i = 0; i < von; i++) { -#if DEBUG_CHURN GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting up peer %d!\n", stopped_arr[stopped_permute[i]]); -#endif GNUNET_assert (stopped_arr != NULL); peer_restart_ctx = GNUNET_malloc (sizeof (struct PeerRestartContext)); peer_restart_ctx->churn_restart_ctx = churn_startup_ctx; @@ -6758,10 +6630,6 @@ GNUNET_TESTING_daemons_start_service (struct GNUNET_TESTING_PeerGroup *pg, for (i = 0; i < pg->total; i++) { -#if DEBUG_START - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting up service %s on peer %d!\n", - service, stopped_arr[stopped_permute[i]]); -#endif peer_start_ctx = GNUNET_malloc (sizeof (struct PeerServiceStartContext)); peer_start_ctx->start_ctx = start_ctx; peer_start_ctx->daemon = pg->peers[i].daemon; @@ -6883,10 +6751,8 @@ internal_shutdown_callback (void *cls, const char *emsg) } else { -#if VERBOSE_TESTING GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "internal_shutdown_callback", "Failed to stop a peer: %s\n", emsg); -#endif shutdown_ctx->peers_failed++; } @@ -6939,22 +6805,24 @@ schedule_shutdown_task (void *cls, { struct PeerShutdownContext *peer_shutdown_ctx = cls; struct ShutdownContext *shutdown_ctx; + struct GNUNET_TESTING_Daemon *d; GNUNET_assert (peer_shutdown_ctx != NULL); + d = peer_shutdown_ctx->daemon; shutdown_ctx = peer_shutdown_ctx->shutdown_ctx; GNUNET_assert (shutdown_ctx != NULL); if ((shutdown_ctx->outstanding < shutdown_ctx->pg->max_concurrent_ssh) || - ((peer_shutdown_ctx->daemon->hostname != NULL) && + ((d->hostname != NULL) && (count_outstanding_at_host - (peer_shutdown_ctx->daemon->hostname, + (d->hostname, shutdown_ctx->pg) < shutdown_ctx->pg->max_concurrent_ssh))) { - if (peer_shutdown_ctx->daemon->hostname != NULL) - increment_outstanding_at_host (peer_shutdown_ctx->daemon->hostname, + if (d->hostname != NULL) + increment_outstanding_at_host (d->hostname, shutdown_ctx->pg); shutdown_ctx->outstanding++; - GNUNET_TESTING_daemon_stop (peer_shutdown_ctx->daemon, + GNUNET_TESTING_daemon_stop (d, shutdown_ctx->timeout, &internal_shutdown_callback, peer_shutdown_ctx, shutdown_ctx->delete_files, GNUNET_NO); @@ -7034,7 +6902,7 @@ GNUNET_TESTING_hosts_load (const struct GNUNET_CONFIGURATION_Handle *cfg) data[count] = '\0'; temphost = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Host)); ret = - sscanf (buf, "%a[a-zA-Z0-9_]@%a[a-zA-Z0-9.]:%hd", + SSCANF (buf, "%a[a-zA-Z0-9_]@%a[a-zA-Z0-9.]:%hd", &temphost->username, &temphost->hostname, &temphost->port); if (3 == ret) { diff --git a/src/testing/testing_new.c b/src/testing/testing_new.c new file mode 100644 index 0000000..c45b89e --- /dev/null +++ b/src/testing/testing_new.c @@ -0,0 +1,1000 @@ +/* + This file is part of GNUnet + (C) 2008, 2009, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file testing/testing_new.c + * @brief convenience API for writing testcases for GNUnet + * Many testcases need to start and stop a peer/service + * and this library is supposed to make that easier + * for TESTCASES. Normal programs should always + * use functions from gnunet_{util,arm}_lib.h. This API is + * ONLY for writing testcases (or internal use of the testbed). + * @author Christian Grothoff + * + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testing_lib-new.h" + +#define LOG(kind,...) \ + GNUNET_log_from (kind, "gnunettestingnew", __VA_ARGS__) + + +/** + * Size of a hostkey when written to a file + */ +#define HOSTKEYFILESIZE 914 + + +/** + * Handle for a system on which GNUnet peers are executed; + * a system is used for reserving unique paths and ports. + */ +struct GNUNET_TESTING_System +{ + /** + * Prefix (i.e. "/tmp/gnunet-testing/") we prepend to each + * SERVICEHOME. + */ + char *tmppath; + + /** + * The hostname of the controller + */ + char *controller; + + /** + * Hostkeys data, contains "HOSTKEYFILESIZE * total_hostkeys" bytes. + */ + char *hostkeys_data; + + /** + * Bitmap where each TCP port that has already been reserved for + * some GNUnet peer is recorded. Note that we additionally need to + * test if a port is already in use by non-GNUnet components before + * assigning it to a peer/service. If we detect that a port is + * already in use, we also mark it in this bitmap. So all the bits + * that are zero merely indicate ports that MIGHT be available for + * peers. + */ + uint32_t reserved_tcp_ports[65536 / 32]; + + /** + * Bitmap where each UDP port that has already been reserved for + * some GNUnet peer is recorded. Note that we additionally need to + * test if a port is already in use by non-GNUnet components before + * assigning it to a peer/service. If we detect that a port is + * already in use, we also mark it in this bitmap. So all the bits + * that are zero merely indicate ports that MIGHT be available for + * peers. + */ + uint32_t reserved_udp_ports[65536 / 32]; + + /** + * Counter we use to make service home paths unique on this system; + * the full path consists of the tmppath and this number. Each + * UNIXPATH for a peer is also modified to include the respective + * path counter to ensure uniqueness. This field is incremented + * by one for each configured peer. Even if peers are destroyed, + * we never re-use path counters. + */ + uint32_t path_counter; + + /** + * The number of hostkeys + */ + uint32_t total_hostkeys; +}; + + +/** + * Handle for a GNUnet peer controlled by testing. + */ +struct GNUNET_TESTING_Peer +{ + + /** + * Path to the configuration file for this peer. + */ + char *cfgfile; + + /** + * Binary to be executed during 'GNUNET_TESTING_peer_start'. + * Typically 'gnunet-service-arm' (but can be set to a + * specific service by 'GNUNET_TESTING_service_run' if + * necessary). + */ + char *main_binary; + + /** + * Handle to the running binary of the service, NULL if the + * peer/service is currently not running. + */ + struct GNUNET_OS_Process *main_process; +}; + + +/** + * Lowest port used for GNUnet testing. Should be high enough to not + * conflict with other applications running on the hosts but be low + * enough to not conflict with client-ports (typically starting around + * 32k). + */ +#define LOW_PORT 12000 + + +/** + * Highest port used for GNUnet testing. Should be low enough to not + * conflict with the port range for "local" ports (client apps; see + * /proc/sys/net/ipv4/ip_local_port_range on Linux for example). + */ +#define HIGH_PORT 56000 + + +/** + * Create a system handle. There must only be one system + * handle per operating system. + * + * @param tmppath prefix path to use for all service homes + * @param controller hostname of the controlling host, + * service configurations are modified to allow + * control connections from this host; can be NULL + * @return handle to this system, NULL on error + */ +struct GNUNET_TESTING_System * +GNUNET_TESTING_system_create (const char *tmppath, + const char *controller) +{ + struct GNUNET_TESTING_System *system; + + if (NULL == tmppath) + { + LOG (GNUNET_ERROR_TYPE_ERROR, _("tmppath cannot be NULL\n")); + return NULL; + } + system = GNUNET_malloc (sizeof (struct GNUNET_TESTING_System)); + system->tmppath = GNUNET_strdup (tmppath); + if (NULL != controller) + system->controller = GNUNET_strdup (controller); + return system; +} + + +/** + * Free system resources. + * + * @param system system to be freed + * @param remove_paths should the 'tmppath' and all subdirectories + * be removed (clean up on shutdown)? + */ +void +GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system, + int remove_paths) +{ + if (NULL != system->hostkeys_data) + { + GNUNET_break (0); /* Use GNUNET_TESTING_hostkeys_unload() */ + GNUNET_TESTING_hostkeys_unload (system); + } + if (GNUNET_YES == remove_paths) + GNUNET_DISK_directory_remove (system->tmppath); + GNUNET_free (system->tmppath); + GNUNET_free_non_null (system->controller); + GNUNET_free (system); +} + + +/** + * Reserve a TCP or UDP port for a peer. + * + * @param system system to use for reservation tracking + * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP + * @return 0 if no free port was available + */ +uint16_t +GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system, + int is_tcp) +{ + struct GNUNET_NETWORK_Handle *socket; + struct addrinfo hint; + struct addrinfo *ret; + uint32_t *port_buckets; + char *open_port_str; + int bind_status; + uint32_t xor_image; + uint16_t index; + uint16_t open_port; + uint16_t pos; + + /* + FIXME: Instead of using getaddrinfo we should try to determine the port + status by the following heurestics. + + On systems which support both IPv4 and IPv6, only ports open on both + address families are considered open. + On system with either IPv4 or IPv6. A port is considered open if it's + open in the respective address family + */ + hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */ + hint.ai_socktype = (GNUNET_YES == is_tcp)? SOCK_STREAM : SOCK_DGRAM; + hint.ai_protocol = 0; + hint.ai_addrlen = 0; + hint.ai_addr = NULL; + hint.ai_canonname = NULL; + hint.ai_next = NULL; + hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */ + port_buckets = (GNUNET_YES == is_tcp) ? + system->reserved_tcp_ports : system->reserved_udp_ports; + for (index = (LOW_PORT / 32) + 1; index < (HIGH_PORT / 32); index++) + { + xor_image = (UINT32_MAX ^ port_buckets[index]); + if (0 == xor_image) /* Ports in the bucket are full */ + continue; + pos = 0; + while (pos < 32) + { + if (0 == ((xor_image >> pos) & 1U)) + { + pos++; + continue; + } + open_port = (index * 32) + pos; + GNUNET_asprintf (&open_port_str, "%u", (unsigned int) open_port); + ret = NULL; + GNUNET_assert (0 == getaddrinfo (NULL, open_port_str, &hint, &ret)); + GNUNET_free (open_port_str); + socket = GNUNET_NETWORK_socket_create (ret->ai_family, + (GNUNET_YES == is_tcp) ? + SOCK_STREAM : SOCK_DGRAM, + 0); + GNUNET_assert (NULL != socket); + bind_status = GNUNET_NETWORK_socket_bind (socket, + ret->ai_addr, + ret->ai_addrlen); + freeaddrinfo (ret); + GNUNET_NETWORK_socket_close (socket); + socket = NULL; + port_buckets[index] |= (1U << pos); /* Set the port bit */ + if (GNUNET_OK == bind_status) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found a free port %u\n", (unsigned int) open_port); + return open_port; + } + pos++; + } + } + return 0; +} + + +/** + * Release reservation of a TCP or UDP port for a peer + * (used during GNUNET_TESTING_peer_destroy). + * + * @param system system to use for reservation tracking + * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP + * @param port reserved port to release + */ +void +GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, + int is_tcp, + uint16_t port) +{ + uint32_t *port_buckets; + uint16_t bucket; + uint16_t pos; + + port_buckets = (GNUNET_YES == is_tcp) ? + system->reserved_tcp_ports : system->reserved_udp_ports; + bucket = port / 32; + pos = port % 32; + LOG (GNUNET_ERROR_TYPE_DEBUG, "Releasing port %u\n", port); + if (0 == (port_buckets[bucket] & (1U << pos))) + { + GNUNET_break(0); /* Port was not reserved by us using reserve_port() */ + return; + } + port_buckets[bucket] &= ~(1U << pos); +} + + +/** + * Reserve a SERVICEHOME path for a peer. + * + * @param system system to use for reservation tracking + * @return NULL on error, otherwise fresh unique path to use + * as the servicehome for the peer; must be freed by the caller + */ +// static +char * +reserve_path (struct GNUNET_TESTING_System *system) +{ + char *reserved_path; + + GNUNET_asprintf (&reserved_path, + "%s/%u", system->tmppath, system->path_counter++); + return reserved_path; +} + + +/** + * Testing includes a number of pre-created hostkeys for faster peer + * startup. This function loads such keys into memory from a file. + * + * @param system the testing system handle + * @param filename the path of the hostkeys file + * @return GNUNET_OK on success; GNUNET_SYSERR on error + */ +int +GNUNET_TESTING_hostkeys_load (struct GNUNET_TESTING_System *system, + const char *filename) +{ + struct GNUNET_DISK_FileHandle *fd; + uint64_t fs; + + if (GNUNET_YES != GNUNET_DISK_file_test (filename)) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Hostkeys file not found: %s\n"), filename); + return GNUNET_SYSERR; + } + /* Check hostkey file size, read entire thing into memory */ + fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, + GNUNET_DISK_PERM_NONE); + if (NULL == fd) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Could not open hostkeys file: %s\n"), filename); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) + fs = 0; + if (0 == fs) + { + GNUNET_DISK_file_close (fd); + return GNUNET_SYSERR; /* File is empty */ + } + if (0 != (fs % HOSTKEYFILESIZE)) + { + GNUNET_DISK_file_close (fd); + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Incorrect hostkey file format: %s\n"), filename); + return GNUNET_SYSERR; + } + GNUNET_break (NULL == system->hostkeys_data); + system->total_hostkeys = fs / HOSTKEYFILESIZE; + system->hostkeys_data = GNUNET_malloc_large (fs); /* free in hostkeys_unload */ + GNUNET_assert (fs == GNUNET_DISK_file_read (fd, system->hostkeys_data, fs)); + GNUNET_DISK_file_close (fd); + return GNUNET_OK; +} + + +/** + * Function to remove the loaded hostkeys + * + * @param system the testing system handle + */ +void +GNUNET_TESTING_hostkeys_unload (struct GNUNET_TESTING_System *system) +{ + GNUNET_break (NULL != system->hostkeys_data); + GNUNET_free_non_null (system->hostkeys_data); + system->hostkeys_data = NULL; + system->total_hostkeys = 0; +} + + +/** + * Testing includes a number of pre-created hostkeys for + * faster peer startup. This function can be used to + * access the n-th key of those pre-created hostkeys; note + * that these keys are ONLY useful for testing and not + * secure as the private keys are part of the public + * GNUnet source code. + * + * This is primarily a helper function used internally + * by 'GNUNET_TESTING_peer_configure'. + * + * @param system the testing system handle + * @param key_number desired pre-created hostkey to obtain + * @param id set to the peer's identity (hash of the public + * key; if NULL, GNUNET_SYSERR is returned immediately + * @return GNUNET_SYSERR on error (not enough keys) + */ +int +GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system, + uint32_t key_number, + struct GNUNET_PeerIdentity *id) +{ + struct GNUNET_CRYPTO_RsaPrivateKey *private_key; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; + + if ((NULL == id) || (NULL == system->hostkeys_data)) + return GNUNET_SYSERR; + if (key_number >= system->total_hostkeys) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Key number %u does not exist\n"), key_number); + return GNUNET_SYSERR; + } + private_key = GNUNET_CRYPTO_rsa_decode_key (system->hostkeys_data + + (key_number * HOSTKEYFILESIZE), + HOSTKEYFILESIZE); + if (NULL == private_key) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Error while decoding key %u\n"), key_number); + return GNUNET_SYSERR; + } + GNUNET_CRYPTO_rsa_key_get_public (private_key, &public_key); + GNUNET_CRYPTO_hash (&public_key, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &(id->hashPubKey)); + GNUNET_CRYPTO_rsa_key_free (private_key); + return GNUNET_OK; +} + + +/** + * Structure for holding data to build new configurations from a configuration + * template + */ +struct UpdateContext +{ + /** + * The system for which we are building configurations + */ + struct GNUNET_TESTING_System *system; + + /** + * The configuration we are building + */ + struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * The customized service home path for this peer + */ + char *service_home; + + /** + * build status - to signal error while building a configuration + */ + int status; +}; + + +/** + * Function to iterate over options. Copies + * the options to the target configuration, + * updating PORT values as needed. + * + * @param cls the UpdateContext + * @param section name of the section + * @param option name of the option + * @param value value of the option + */ +static void +update_config (void *cls, const char *section, const char *option, + const char *value) +{ + struct UpdateContext *uc = cls; + unsigned int ival; + char cval[12]; + char uval[128]; + char *single_variable; + char *per_host_variable; + unsigned long long num_per_host; + uint16_t new_port; + + if (GNUNET_OK != uc->status) + return; + if (! ((0 == strcmp (option, "PORT")) + || (0 == strcmp (option, "UNIXPATH")) + || (0 == strcmp (option, "HOSTNAME")))) + return; + GNUNET_asprintf (&single_variable, "single_%s_per_host", section); + GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section); + if ((0 == strcmp (option, "PORT")) && (1 == SSCANF (value, "%u", &ival))) + { + if ((ival != 0) && + (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", + single_variable))) + { + /* FIXME: What about UDP? */ + new_port = GNUNET_TESTING_reserve_port (uc->system, GNUNET_YES); + if (0 == new_port) + { + uc->status = GNUNET_SYSERR; + return; + } + GNUNET_snprintf (cval, sizeof (cval), "%u", new_port); + value = cval; + } + else if ((ival != 0) && + (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", + single_variable)) && + GNUNET_CONFIGURATION_get_value_number (uc->cfg, "testing", + per_host_variable, + &num_per_host)) + { + /* GNUNET_snprintf (cval, sizeof (cval), "%u", */ + /* ival + ctx->fdnum % num_per_host); */ + /* value = cval; */ + GNUNET_break (0); /* FIXME */ + } + } + if (0 == strcmp (option, "UNIXPATH")) + { + if (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", + single_variable)) + { + GNUNET_snprintf (uval, sizeof (uval), "%s/%s.sock", + uc->service_home, section); + value = uval; + } + else if ((GNUNET_YES == + GNUNET_CONFIGURATION_get_value_number (uc->cfg, "testing", + per_host_variable, + &num_per_host)) && + (num_per_host > 0)) + { + GNUNET_break(0); /* FIXME */ + } + } + if ((0 == strcmp (option, "HOSTNAME")) && (NULL != uc->system->controller)) + { + value = uc->system->controller; + } + GNUNET_free (single_variable); + GNUNET_free (per_host_variable); + GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, option, value); +} + + +/** + * Section iterator to set ACCEPT_FROM in all sections + * + * @param cls the UpdateContext + * @param section name of the section + */ +static void +update_config_sections (void *cls, + const char *section) +{ + struct UpdateContext *uc = cls; + char *orig_allowed_hosts; + char *allowed_hosts; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (uc->cfg, section, "ACCEPT_FROM", + &orig_allowed_hosts)) + { + orig_allowed_hosts = GNUNET_strdup ("127.0.0.1;"); + } + if (NULL == uc->system->controller) + allowed_hosts = GNUNET_strdup (orig_allowed_hosts); + else + GNUNET_asprintf (&allowed_hosts, "%s %s;", orig_allowed_hosts, + uc->system->controller); + GNUNET_free (orig_allowed_hosts); + GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, "ACCEPT_FROM", + allowed_hosts); + GNUNET_free (allowed_hosts); +} + + +/** + * Create a new configuration using the given configuration + * as a template; ports and paths will be modified to select + * available ports on the local system. If we run + * out of "*port" numbers, return SYSERR. + * + * This is primarily a helper function used internally + * by 'GNUNET_TESTING_peer_configure'. + * + * @param system system to use to coordinate resource usage + * @param cfg template configuration to update + * @return GNUNET_OK on success, GNUNET_SYSERR on error - the configuration will + * be incomplete and should not be used there upon + */ +int +GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system, + struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct UpdateContext uc; + + uc.system = system; + uc.cfg = cfg; + uc.status = GNUNET_OK; + GNUNET_asprintf (&uc.service_home, "%s/%u", system->tmppath, + system->path_counter++); + GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "SERVICEHOME", + uc.service_home); + /* make PORTs and UNIXPATHs unique */ + GNUNET_CONFIGURATION_iterate (cfg, &update_config, &uc); + /* allow connections to services from system controller host */ + GNUNET_CONFIGURATION_iterate_sections (cfg, &update_config_sections, &uc); + /* enable loopback-based connections between peers */ + GNUNET_CONFIGURATION_set_value_string (cfg, + "nat", + "USE_LOCALADDR", "YES"); + GNUNET_free (uc.service_home); + return uc.status; +} + + +/** + * Configure a GNUnet peer. GNUnet must be installed on the local + * system and available in the PATH. + * + * @param system system to use to coordinate resource usage + * @param cfg configuration to use; will be UPDATED (to reflect needed + * changes in port numbers and paths) + * @param key_number number of the hostkey to use for the peer + * @param id identifier for the daemon, will be set, can be NULL + * @param emsg set to error message (set to NULL on success), can be NULL + * @return handle to the peer, NULL on error + */ +struct GNUNET_TESTING_Peer * +GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system, + struct GNUNET_CONFIGURATION_Handle *cfg, + uint32_t key_number, + struct GNUNET_PeerIdentity *id, + char **emsg) +{ + struct GNUNET_TESTING_Peer *peer; + struct GNUNET_DISK_FileHandle *fd; + char *service_home; + char hostkey_filename[128]; + char *config_filename; + char *emsg_; + + if (NULL != emsg) + *emsg = NULL; + if (GNUNET_OK != GNUNET_TESTING_configuration_create (system, cfg)) + { + GNUNET_asprintf (&emsg_, + _("Failed to create configuration for peer (not enough free ports?)\n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + return NULL; + } + if (key_number >= system->total_hostkeys) + { + GNUNET_asprintf (&emsg_, + _("You attempted to create a testbed with more than %u hosts. Please precompute more hostkeys first.\n"), + (unsigned int) system->total_hostkeys); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + return NULL; + } + if ((NULL != id) && + (GNUNET_SYSERR == GNUNET_TESTING_hostkey_get (system, key_number, id))) + { + GNUNET_asprintf (&emsg_, + _("Failed to initialize hostkey for peer %u\n"), + (unsigned int) key_number); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + return NULL; + } + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", + "SERVICEHOME", + &service_home)); + GNUNET_snprintf (hostkey_filename, sizeof (hostkey_filename), "%s/.hostkey", + service_home); + fd = GNUNET_DISK_file_open (hostkey_filename, + GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, + GNUNET_DISK_PERM_USER_READ + | GNUNET_DISK_PERM_USER_WRITE); + if (NULL == fd) + { + GNUNET_break (0); + return NULL; + } + if (HOSTKEYFILESIZE != + GNUNET_DISK_file_write (fd, system->hostkeys_data + + (key_number * HOSTKEYFILESIZE), + HOSTKEYFILESIZE)) + { + GNUNET_asprintf (&emsg_, + _("Failed to write hostkey file for peer %u: %s\n"), + (unsigned int) key_number, + STRERROR (errno)); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + GNUNET_DISK_file_close (fd); + return NULL; + } + GNUNET_DISK_file_close (fd); + GNUNET_asprintf (&config_filename, "%s/config", service_home); + GNUNET_free (service_home); + if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config_filename)) + { + GNUNET_asprintf (&emsg_, + _("Failed to write configuration file `%s' for peer %u: %s\n"), + config_filename, + (unsigned int) key_number, + STRERROR (errno)); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + return NULL; + } + peer = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Peer)); + peer->cfgfile = config_filename; /* Free in peer_destroy */ + peer->main_binary = GNUNET_strdup ("gnunet-service-arm"); + return peer; +} + + +/** + * Start the peer. + * + * @param peer peer to start + * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer already running) + */ +int +GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer) +{ + if (NULL != peer->main_process) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_assert (NULL != peer->cfgfile); + peer->main_process = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, + peer->main_binary, "-c", + peer->cfgfile, + NULL); + if (NULL == peer->main_process) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to start `%s': %s\n"), + peer->main_binary, + STRERROR (errno)); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Stop the peer. + * + * @param peer peer to stop + * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer not running) + */ +int +GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer) +{ + if (NULL == peer->main_process) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + (void) GNUNET_OS_process_kill (peer->main_process, SIGTERM); + GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (peer->main_process)); + GNUNET_OS_process_destroy (peer->main_process); + peer->main_process = NULL; + return GNUNET_OK; +} + + +/** + * Destroy the peer. Releases resources locked during peer configuration. + * If the peer is still running, it will be stopped AND a warning will be + * printed (users of the API should stop the peer explicitly first). + * + * @param peer peer to destroy + */ +void +GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer) +{ + if (NULL != peer->main_process) + { + GNUNET_break (0); + GNUNET_TESTING_peer_stop (peer); + } + GNUNET_free (peer->cfgfile); + GNUNET_free (peer->main_binary); + GNUNET_free (peer); +} + + +/** + * Start a single peer and run a test using the testing library. + * Starts a peer using the given configuration and then invokes the + * given callback. This function ALSO initializes the scheduler loop + * and should thus be called directly from "main". The testcase + * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'. + * + * @param tmppath path for storing temporary data for the test + * @param cfgfilename name of the configuration file to use; + * use NULL to only run with defaults + * @param tm main function of the testcase + * @param tm_cls closure for 'tm' + * @return 0 on success, 1 on error + */ +int +GNUNET_TESTING_peer_run (const char *tmppath, + const char *cfgfilename, + GNUNET_TESTING_TestMain tm, + void *tm_cls) +{ + return GNUNET_TESTING_service_run (tmppath, "arm", + cfgfilename, tm, tm_cls); +} + + +/** + * Structure for holding service data + */ +struct ServiceContext +{ + /** + * The configuration of the peer in which the service is run + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Callback to signal service startup + */ + GNUNET_TESTING_TestMain tm; + + /** + * Closure for the above callback + */ + void *tm_cls; +}; + + +/** + * Callback to be called when SCHEDULER has been started + * + * @param cls the ServiceContext + * @param tc the TaskContext + */ +static void +service_run_main (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct ServiceContext *sc = cls; + + sc->tm (sc->tm_cls, sc->cfg); +} + + +/** + * Start a single service (no ARM, except of course if the given + * service name is 'arm') and run a test using the testing library. + * Starts a service using the given configuration and then invokes the + * given callback. This function ALSO initializes the scheduler loop + * and should thus be called directly from "main". The testcase + * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'. + * + * This function is useful if the testcase is for a single service + * and if that service doesn't itself depend on other services. + * + * @param tmppath path for storing temporary data for the test + * @param service_name name of the service to run + * @param cfgfilename name of the configuration file to use; + * use NULL to only run with defaults + * @param tm main function of the testcase + * @param tm_cls closure for 'tm' + * @return 0 on success, 1 on error + */ +int +GNUNET_TESTING_service_run (const char *tmppath, + const char *service_name, + const char *cfgfilename, + GNUNET_TESTING_TestMain tm, + void *tm_cls) +{ + struct ServiceContext sc; + struct GNUNET_TESTING_System *system; + struct GNUNET_TESTING_Peer *peer; + struct GNUNET_CONFIGURATION_Handle *cfg; + char *data_dir; + char *hostkeys_file; + + data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); + GNUNET_asprintf (&hostkeys_file, "%s/testing_hostkeys.dat", data_dir); + GNUNET_free (data_dir); + system = GNUNET_TESTING_system_create (tmppath, "localhost"); + if (NULL == system) + { + GNUNET_free (hostkeys_file); + return 1; + } + if (GNUNET_OK != GNUNET_TESTING_hostkeys_load (system, hostkeys_file)) + { + GNUNET_free (hostkeys_file); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + GNUNET_free (hostkeys_file); + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfgfilename)) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Failed to load configuration from %s\n"), cfgfilename); + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + peer = GNUNET_TESTING_peer_configure (system, cfg, 0, NULL, NULL); + if (NULL == peer) + { + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_hostkeys_unload (system); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + GNUNET_TESTING_hostkeys_unload (system); + GNUNET_free (peer->main_binary); + GNUNET_asprintf (&peer->main_binary, "gnunet-service-%s", service_name); + if (GNUNET_OK != GNUNET_TESTING_peer_start (peer)) + { + GNUNET_TESTING_peer_destroy (peer); + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + sc.cfg = cfg; + sc.tm = tm; + sc.tm_cls = tm_cls; + GNUNET_SCHEDULER_run (&service_run_main, &sc); /* Scheduler loop */ + if (GNUNET_OK != GNUNET_TESTING_peer_stop (peer)) + { + GNUNET_TESTING_peer_destroy (peer); + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + GNUNET_TESTING_peer_destroy (peer); + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 0; +} + + +/* end of testing_new.c */ diff --git a/src/testing/testing_peergroup.c b/src/testing/testing_peergroup.c index 0119d66..87504ed 100644 --- a/src/testing/testing_peergroup.c +++ b/src/testing/testing_peergroup.c @@ -445,46 +445,56 @@ internal_topology_callback (void *cls, const struct GNUNET_PeerIdentity *first, pg_start_ctx->connect_cb (pg_start_ctx->cls, first, second, distance, first_cfg, second_cfg, first_daemon, second_daemon, emsg); - if (GNUNET_YES == update_meter (pg_start_ctx->connect_meter)) + if (GNUNET_YES != update_meter (pg_start_ctx->connect_meter)) { + /* No finished yet */ + return; + } #if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Created %d total connections, which is our target number! Starting next phase of testing.\n", - pg_start_ctx->total_connections); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Created %d total connections, which is our target number! Starting next phase of testing.\n", + pg_start_ctx->total_connections); #endif #if TIMING - total_duration = - GNUNET_TIME_absolute_get_difference (connect_start_time, - GNUNET_TIME_absolute_get - ()).rel_value / 1000; - failed_conns_per_sec_total = (double) failed_connections / total_duration; - conns_per_sec_total = (double) total_connections / total_duration; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Overall connection info --- Total: %u, Total Failed %u/s\n", - total_connections, failed_connections); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Overall connection info --- Total: %.2f/s, Total Failed %.2f/s\n", - conns_per_sec_total, failed_conns_per_sec_total); + total_duration = + GNUNET_TIME_absolute_get_difference (connect_start_time, + GNUNET_TIME_absolute_get + ()).rel_value / 1000; + failed_conns_per_sec_total = (double) failed_connections / total_duration; + conns_per_sec_total = (double) total_connections / total_duration; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Overall connection info --- Total: %u, Total Failed %u/s\n", + total_connections, failed_connections); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Overall connection info --- Total: %.2f/s, Total Failed %.2f/s\n", + conns_per_sec_total, failed_conns_per_sec_total); #endif - GNUNET_assert (pg_start_ctx->die_task != GNUNET_SCHEDULER_NO_TASK); - GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task); + GNUNET_assert (pg_start_ctx->die_task != GNUNET_SCHEDULER_NO_TASK); + GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task); - /* Call final callback, signifying that the peer group has been started and connected */ - if (pg_start_ctx->peergroup_cb != NULL) - pg_start_ctx->peergroup_cb (pg_start_ctx->cls, NULL); + /* Call final callback, signifying that the peer group has been started and connected */ + if (pg_start_ctx->peergroup_cb != NULL) + pg_start_ctx->peergroup_cb (pg_start_ctx->cls, NULL); - if (pg_start_ctx->topology_output_file != NULL) - { - temp = GNUNET_asprintf (&temp_str, "}\n"); - if (temp > 0) - GNUNET_DISK_file_write (pg_start_ctx->topology_output_file, temp_str, - temp); - GNUNET_free (temp_str); - GNUNET_DISK_file_close (pg_start_ctx->topology_output_file); - } + if (pg_start_ctx->topology_output_file != NULL) + { + temp = GNUNET_asprintf (&temp_str, "}\n"); + if (temp > 0) + GNUNET_DISK_file_write (pg_start_ctx->topology_output_file, temp_str, + temp); + GNUNET_free (temp_str); + GNUNET_DISK_file_close (pg_start_ctx->topology_output_file); } + GNUNET_free_non_null (pg_start_ctx->fail_reason); + if (NULL != pg_start_ctx->hostkey_meter) + free_meter(pg_start_ctx->hostkey_meter); + if (NULL != pg_start_ctx->peer_start_meter) + free_meter(pg_start_ctx->peer_start_meter); + if (NULL != pg_start_ctx->connect_meter) + free_meter(pg_start_ctx->connect_meter); + GNUNET_free (pg_start_ctx); } @@ -932,7 +942,7 @@ GNUNET_TESTING_peergroup_start (const struct GNUNET_CONFIGURATION_Handle *cfg, "connect_topology_option_modifier", &temp_str)) { - if (sscanf + if (SSCANF (temp_str, "%lf", &pg_start_ctx->connect_topology_option_modifier) != 1) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, diff --git a/src/topology/Makefile.in b/src/topology/Makefile.in index a7ae50d..7cde7ff 100644 --- a/src/topology/Makefile.in +++ b/src/topology/Makefile.in @@ -195,6 +195,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -228,6 +229,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c index 38a648a..382c9f3 100644 --- a/src/topology/gnunet-daemon-topology.c +++ b/src/topology/gnunet-daemon-topology.c @@ -23,8 +23,6 @@ * @brief code for maintaining the mesh topology * @author Christian Grothoff */ - -#include #include "platform.h" #include "gnunet_constants.h" #include "gnunet_core_service.h" @@ -35,39 +33,46 @@ #include "gnunet_util_lib.h" -#define DEBUG_TOPOLOGY GNUNET_YES +/** + * Minimum required delay between calls to GNUNET_TRANSPORT_try_connect. + */ +#define MAX_CONNECT_FREQUENCY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250) /** * For how long do we blacklist a peer after a failed connection - * attempt? + * attempt? This is the baseline factor which is then multiplied by + * two to the power of the number of failed attempts. */ -#define GREYLIST_AFTER_ATTEMPT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) +#define GREYLIST_AFTER_ATTEMPT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1) /** * For how long do we blacklist a friend after a failed connection - * attempt? + * attempt? This is the baseline factor which is then multiplied by + * two to the power of the number of failed attempts. */ -#define GREYLIST_AFTER_ATTEMPT_FRIEND GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) +#define GREYLIST_AFTER_ATTEMPT_FRIEND GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) /** - * For how long do we blacklist anyone under any cirumstances after a failed connection - * attempt? + * For how long do we blacklist anyone under any cirumstances at least after a failed connection + * attempt? This is the absolute minimum, regardless of what the calculation based on + * exponential backoff returns. */ -#define GREYLIST_AFTER_ATTEMPT_MIN GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) +#define GREYLIST_AFTER_ATTEMPT_MIN GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) /** - * For how long do we blacklist anyone under any cirumstances after a failed connection - * attempt? + * For how long do we blacklist anyone under any cirumstances at most after a failed connection + * attempt? This is the absolute maximum, regardless of what the calculation based on + * exponential back-off returns. */ #define GREYLIST_AFTER_ATTEMPT_MAX GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1) /** - * How often do we at most advertise any HELLO to a peer? + * At what frequency do we sent HELLOs to a peer? */ -#define HELLO_ADVERTISEMENT_MIN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) +#define HELLO_ADVERTISEMENT_MIN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) /** - * How often do we at most advertise the same HELLO to the same peer? + * After what time period do we expire the HELLO Bloom filter? */ #define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) @@ -121,6 +126,11 @@ struct Peer */ GNUNET_SCHEDULER_TaskIdentifier hello_delay_task; + /** + * Task for issuing GNUNET_TRANSPORT_try_connect for this peer. + */ + GNUNET_SCHEDULER_TaskIdentifier attempt_connect_task; + /** * ID of task we use to clear peers from the greylist. */ @@ -187,6 +197,11 @@ static struct GNUNET_STATISTICS_Handle *stats; */ static struct GNUNET_TRANSPORT_Blacklist *blacklist; +/** + * When can we next ask transport to create a connection? + */ +static struct GNUNET_TIME_Absolute next_connect_attempt; + /** * Task scheduled to try to add peers. */ @@ -278,20 +293,16 @@ is_connection_allowed (struct Peer *peer) return GNUNET_OK; if (GNUNET_YES == friends_only) { -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Determined that `%s' is not allowed to connect (not a friend)\n", GNUNET_i2s (&peer->pid)); -#endif return GNUNET_SYSERR; } if (friend_count >= minimum_friend_count) return GNUNET_OK; -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Determined that `%s' is not allowed to connect (not enough connected friends)\n", GNUNET_i2s (&peer->pid)); -#endif return GNUNET_SYSERR; } @@ -309,12 +320,15 @@ free_peer (void *cls, const GNUNET_HashCode * pid, void *value) { struct Peer *pos = value; + GNUNET_break (GNUNET_NO == pos->is_connected); GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (peers, pid, pos)); if (pos->hello_req != NULL) GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req); if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (pos->hello_delay_task); + if (pos->attempt_connect_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (pos->attempt_connect_task); if (pos->greylist_clean_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (pos->greylist_clean_task); GNUNET_free_non_null (pos->hello); @@ -371,10 +385,8 @@ attempt_connect (struct Peer *pos) GNUNET_SCHEDULER_cancel (pos->greylist_clean_task); pos->greylist_clean_task = GNUNET_SCHEDULER_add_delayed (rem, &remove_from_greylist, pos); -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking to connect to `%s'\n", GNUNET_i2s (&pos->pid)); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# connect requests issued to transport"), 1, @@ -383,6 +395,51 @@ attempt_connect (struct Peer *pos) } +/** + * Try to connect to the specified peer. + * + * @param cls peer to connect to + * @param tc scheduler context + */ +static void +do_attempt_connect (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Peer *pos = cls; + struct GNUNET_TIME_Relative delay; + + pos->attempt_connect_task = GNUNET_SCHEDULER_NO_TASK; + if (GNUNET_YES == pos->is_connected) + return; + delay = GNUNET_TIME_absolute_get_remaining (next_connect_attempt); + if (delay.rel_value > 0) + { + pos->attempt_connect_task = GNUNET_SCHEDULER_add_delayed (delay, + &do_attempt_connect, + pos); + return; + } + next_connect_attempt = GNUNET_TIME_relative_to_absolute (MAX_CONNECT_FREQUENCY_DELAY); + attempt_connect (pos); +} + + +/** + * Schedule a task to try to connect to the specified peer. + * + * @param pos peer to connect to + */ +static void +schedule_attempt_connect (struct Peer *pos) +{ + if (GNUNET_SCHEDULER_NO_TASK != pos->attempt_connect_task) + return; + pos->attempt_connect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (next_connect_attempt), + &do_attempt_connect, + pos); +} + + /** * Discard peer entries for greylisted peers * where the greylisting has expired. @@ -400,7 +457,7 @@ remove_from_greylist (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) rem = GNUNET_TIME_absolute_get_remaining (pos->greylisted_until); if (rem.rel_value == 0) { - attempt_connect (pos); + schedule_attempt_connect (pos); } else { @@ -642,11 +699,9 @@ connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, { struct Peer *pos; -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core told us that we are connecting to `%s'\n", GNUNET_i2s (peer)); -#endif if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) return; @@ -654,7 +709,7 @@ connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_STATISTICS_set (stats, gettext_noop ("# peers connected"), connection_count, GNUNET_NO); pos = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey); - if (pos == NULL) + if (NULL == pos) { pos = make_peer (peer, NULL, GNUNET_NO); GNUNET_break (GNUNET_OK == is_connection_allowed (pos)); @@ -692,7 +747,7 @@ try_add_peers (void *cls, const GNUNET_HashCode * pid, void *value) { struct Peer *pos = value; - attempt_connect (pos); + schedule_attempt_connect (pos); return GNUNET_YES; } @@ -712,6 +767,7 @@ add_peer_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONTAINER_multihashmap_iterate (peers, &try_add_peers, NULL); } + /** * Method called whenever a peer disconnects. * @@ -725,13 +781,11 @@ disconnect_notify (void *cls, const struct GNUNET_PeerIdentity *peer) if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) return; -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core told us that we disconnected from `%s'\n", GNUNET_i2s (peer)); -#endif pos = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey); - if (pos == NULL) + if (NULL == pos) { GNUNET_break (0); return; @@ -818,7 +872,7 @@ consider_for_advertising (const struct GNUNET_HELLO_Message *hello) if (GNUNET_NO == have_address) return; /* no point in advertising this one... */ peer = GNUNET_CONTAINER_multihashmap_get (peers, &pid.hashPubKey); - if (peer == NULL) + if (NULL == peer) { peer = make_peer (&pid, hello, GNUNET_NO); } @@ -828,11 +882,9 @@ consider_for_advertising (const struct GNUNET_HELLO_Message *hello) if (dt.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value) return; /* nothing new here */ } -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' from peer `%s' for advertising\n", "HELLO", GNUNET_i2s (&pid)); -#endif if (peer->hello != NULL) { nh = GNUNET_HELLO_merge (peer->hello, hello); @@ -894,7 +946,7 @@ process_peer (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_CONTAINER_bloomfilter_free (pos->filter); pos->filter = NULL; } - if ((!pos->is_connected) && (!pos->is_friend) && + if ((GNUNET_NO == pos->is_connected) && (GNUNET_NO == pos->is_friend) && (0 == GNUNET_TIME_absolute_get_remaining (pos-> greylisted_until).rel_value)) @@ -909,25 +961,19 @@ process_peer (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_assert (NULL != pos); if (GNUNET_YES == pos->is_connected) { -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Already connected to peer `%s'\n", GNUNET_i2s (peer)); -#endif return; } if (GNUNET_TIME_absolute_get_remaining (pos->greylisted_until).rel_value > 0) { -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Already tried peer `%s' recently\n", GNUNET_i2s (peer)); -#endif return; /* peer still greylisted */ } -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Considering connecting to peer `%s'\n", GNUNET_i2s (peer)); -#endif - attempt_connect (pos); + schedule_attempt_connect (pos); } @@ -953,9 +999,7 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server, } handle = server; my_identity = *my_id; -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am peer `%s'\n", GNUNET_i2s (my_id)); -#endif peerinfo_notify = GNUNET_PEERINFO_notify (cfg, &process_peer, NULL); } @@ -970,7 +1014,7 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) char *data; size_t pos; struct GNUNET_PeerIdentity pid; - struct stat frstat; + uint64_t fsize; struct GNUNET_CRYPTO_HashAsciiEncoded enc; unsigned int entries_found; struct Peer *fl; @@ -987,7 +1031,8 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) GNUNET_DISK_fn_write (fn, NULL, 0, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); - if (0 != STAT (fn, &frstat)) + if (GNUNET_OK != GNUNET_DISK_file_size (fn, + &fsize, GNUNET_NO, GNUNET_YES)) { if ((friends_only) || (minimum_friend_count > 0)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -995,14 +1040,14 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) GNUNET_free (fn); return; } - if (frstat.st_size == 0) + if (fsize == 0) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Friends file `%s' is empty.\n"), fn); GNUNET_free (fn); return; } - data = GNUNET_malloc_large (frstat.st_size); + data = GNUNET_malloc_large (fsize); if (data == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1011,7 +1056,7 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) GNUNET_free (fn); return; } - if (frstat.st_size != GNUNET_DISK_fn_read (fn, data, frstat.st_size)) + if (fsize != GNUNET_DISK_fn_read (fn, data, fsize)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read friends list from `%s'\n"), fn); @@ -1021,11 +1066,11 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) } entries_found = 0; pos = 0; - while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) + while ((pos < fsize) && isspace ((unsigned char) data[pos])) pos++; - while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && + while ((fsize >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && (pos <= - frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) + fsize - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) { memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); if (!isspace @@ -1037,7 +1082,7 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) ("Syntax error in topology specification at offset %llu, skipping bytes.\n"), (unsigned long long) pos); pos++; - while ((pos < frstat.st_size) && (!isspace ((unsigned char) data[pos]))) + while ((pos < fsize) && (!isspace ((unsigned char) data[pos]))) pos++; continue; } @@ -1068,7 +1113,7 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) } } pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded); - while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) + while ((pos < fsize) && isspace ((unsigned char) data[pos])) pos++; } GNUNET_free (data); @@ -1113,10 +1158,8 @@ handle_encrypted_hello (void *cls, const struct GNUNET_PeerIdentity *other, struct Peer *peer; struct GNUNET_PeerIdentity pid; -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received encrypted `%s' from peer `%s'", "HELLO", GNUNET_i2s (other)); -#endif if (GNUNET_OK != GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) message, &pid)) { @@ -1126,7 +1169,7 @@ handle_encrypted_hello (void *cls, const struct GNUNET_PeerIdentity *other, GNUNET_STATISTICS_update (stats, gettext_noop ("# HELLO messages received"), 1, GNUNET_NO); peer = GNUNET_CONTAINER_multihashmap_get (peers, &pid.hashPubKey); - if (peer == NULL) + if (NULL == peer) { if ((GNUNET_YES == friends_only) || (friend_count < minimum_friend_count)) return GNUNET_OK; @@ -1175,10 +1218,8 @@ hello_advertising_ready (void *cls, size_t size, void *buf) GNUNET_assert (want <= size); memcpy (buf, fah.result->hello, want); GNUNET_CONTAINER_bloomfilter_add (fah.result->filter, &pl->pid.hashPubKey); -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' with %u bytes", "HELLO", (unsigned int) want); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# HELLO messages gossipped"), 1, GNUNET_NO); @@ -1208,21 +1249,22 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_PEERINFO_notify_cancel (peerinfo_notify); peerinfo_notify = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != add_task) - { - GNUNET_SCHEDULER_cancel (add_task); - add_task = GNUNET_SCHEDULER_NO_TASK; - } GNUNET_TRANSPORT_disconnect (transport); transport = NULL; - GNUNET_CONTAINER_multihashmap_iterate (peers, &free_peer, NULL); - GNUNET_CONTAINER_multihashmap_destroy (peers); if (handle != NULL) { GNUNET_CORE_disconnect (handle); handle = NULL; } whitelist_peers (); + if (GNUNET_SCHEDULER_NO_TASK != add_task) + { + GNUNET_SCHEDULER_cancel (add_task); + add_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_CONTAINER_multihashmap_iterate (peers, &free_peer, NULL); + GNUNET_CONTAINER_multihashmap_destroy (peers); + peers = NULL; if (stats != NULL) { GNUNET_STATISTICS_destroy (stats, GNUNET_NO); @@ -1269,12 +1311,10 @@ run (void *cls, char *const *args, const char *cfgfile, if ((friends_only == GNUNET_YES) || (minimum_friend_count > 0)) read_friends_file (cfg); -#if DEBUG_TOPOLOGY GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Topology would like %u connections with at least %u friends (%s)\n", target_connection_count, minimum_friend_count, autoconnect ? "autoconnect enabled" : "autoconnect disabled"); -#endif if ((friend_count < minimum_friend_count) && (blacklist == NULL)) blacklist = GNUNET_TRANSPORT_blacklist (cfg, &blacklist_check, NULL); transport = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, NULL, NULL, NULL); diff --git a/src/topology/test_gnunet_daemon_topology.c b/src/topology/test_gnunet_daemon_topology.c index 7592ede..35225e4 100644 --- a/src/topology/test_gnunet_daemon_topology.c +++ b/src/topology/test_gnunet_daemon_topology.c @@ -24,7 +24,6 @@ #include "platform.h" #include "gnunet_testing_lib.h" -#define VERBOSE GNUNET_NO #define NUM_PEERS 2 @@ -61,17 +60,13 @@ shutdown_callback (void *cls, const char *emsg) { if (emsg != NULL) { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); -#endif if (ok == 0) ok = 666; } else { -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); -#endif } } @@ -165,9 +160,7 @@ run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { ok = 1; -#if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); -#endif peers_left = NUM_PEERS; pg = GNUNET_TESTING_daemons_start (cfg, peers_left, peers_left, peers_left, TIMEOUT, NULL, NULL, &my_cb, NULL, NULL, @@ -183,9 +176,6 @@ check () "test-gnunet-daemon-topology", "-c", "test_gnunet_daemon_topology_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -204,11 +194,7 @@ main (int argc, char *argv[]) int ret; GNUNET_log_setup ("test-gnunet-daemon-topology", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); ret = check (); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-topology"); diff --git a/src/topology/test_gnunet_daemon_topology_data.conf b/src/topology/test_gnunet_daemon_topology_data.conf index 2bce10d..0be8cd4 100644 --- a/src/topology/test_gnunet_daemon_topology_data.conf +++ b/src/topology/test_gnunet_daemon_topology_data.conf @@ -56,7 +56,8 @@ HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat [dns] AUTOSTART = NO - +[namestore] +AUTOSTART = NO [nse] AUTOSTART = NO diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 0692450..b040874 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -61,7 +61,6 @@ UNIX_QUOTA_TEST = test_quota_compliance_unix \ endif noinst_PROGRAMS = \ - $(WLAN_BIN_DUMMY) \ $(WLAN_BIN_SENDER) # gnunet-transport-connect-running-peers @@ -92,11 +91,12 @@ libgnunettransport_la_LIBADD = \ $(GN_LIBINTL) libgnunettransport_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 0:0:0 + -version-info 1:0:0 bin_PROGRAMS = \ gnunet-transport \ $(WLAN_BIN) \ + $(WLAN_BIN_DUMMY) \ gnunet-service-transport \ gnunet-transport-certificate-creation diff --git a/src/transport/Makefile.in b/src/transport/Makefile.in index 36df686..b5f2c64 100644 --- a/src/transport/Makefile.in +++ b/src/transport/Makefile.in @@ -37,9 +37,9 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -noinst_PROGRAMS = $(am__EXEEXT_21) $(am__EXEEXT_22) +noinst_PROGRAMS = $(am__EXEEXT_22) bin_PROGRAMS = gnunet-transport$(EXEEXT) $(am__EXEEXT_1) \ - gnunet-service-transport$(EXEEXT) \ + $(am__EXEEXT_2) gnunet-service-transport$(EXEEXT) \ gnunet-transport-certificate-creation$(EXEEXT) check_PROGRAMS = test_transport_testing$(EXEEXT) \ test_transport_startonly$(EXEEXT) \ @@ -53,22 +53,22 @@ check_PROGRAMS = test_transport_testing$(EXEEXT) \ test_transport_api_limited_sockets_tcp$(EXEEXT) \ test_transport_api_tcp_nat$(EXEEXT) \ test_transport_api_udp$(EXEEXT) \ - test_transport_api_timeout_udp$(EXEEXT) $(am__EXEEXT_2) \ - $(am__EXEEXT_3) test_transport_api_udp_nat$(EXEEXT) \ - $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ - $(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \ + test_transport_api_timeout_udp$(EXEEXT) $(am__EXEEXT_3) \ + $(am__EXEEXT_4) test_transport_api_udp_nat$(EXEEXT) \ + $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7) \ + $(am__EXEEXT_8) $(am__EXEEXT_9) $(am__EXEEXT_10) \ test_transport_api_multi$(EXEEXT) \ test_transport_api_reliability_tcp$(EXEEXT) \ test_transport_api_reliability_tcp_nat$(EXEEXT) \ test_transport_api_unreliability_udp$(EXEEXT) \ test_transport_api_unreliability_constant_udp$(EXEEXT) \ - $(am__EXEEXT_10) $(am__EXEEXT_11) $(am__EXEEXT_12) \ - $(am__EXEEXT_13) $(am__EXEEXT_14) \ + $(am__EXEEXT_11) $(am__EXEEXT_12) $(am__EXEEXT_13) \ + $(am__EXEEXT_14) $(am__EXEEXT_15) \ test_quota_compliance_tcp$(EXEEXT) \ test_quota_compliance_tcp_asymmetric$(EXEEXT) \ - test_quota_compliance_udp$(EXEEXT) $(am__EXEEXT_15) \ - $(am__EXEEXT_16) $(am__EXEEXT_17) $(am__EXEEXT_18) \ - $(am__EXEEXT_19) $(am__EXEEXT_20) + test_quota_compliance_udp$(EXEEXT) $(am__EXEEXT_16) \ + $(am__EXEEXT_17) $(am__EXEEXT_18) $(am__EXEEXT_19) \ + $(am__EXEEXT_20) $(am__EXEEXT_21) @ENABLE_TEST_RUN_TRUE@TESTS = test_transport_testing$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_startonly$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_blacklisting$(EXEEXT) \ @@ -82,25 +82,25 @@ check_PROGRAMS = test_transport_testing$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_tcp_nat$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_udp$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_timeout_udp$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_2) $(am__EXEEXT_3) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_3) $(am__EXEEXT_4) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_udp_nat$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_4) $(am__EXEEXT_5) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_6) $(am__EXEEXT_7) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_8) $(am__EXEEXT_9) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_5) $(am__EXEEXT_6) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_7) $(am__EXEEXT_8) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_9) $(am__EXEEXT_10) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_multi$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_reliability_tcp$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_reliability_tcp_nat$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_unreliability_udp$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_transport_api_unreliability_constant_udp$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_10) $(am__EXEEXT_11) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_12) $(am__EXEEXT_13) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_14) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_11) $(am__EXEEXT_12) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_13) $(am__EXEEXT_14) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_15) \ @ENABLE_TEST_RUN_TRUE@ test_quota_compliance_tcp$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_quota_compliance_tcp_asymmetric$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_quota_compliance_udp$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_15) $(am__EXEEXT_16) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_17) $(am__EXEEXT_18) \ -@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_19) $(am__EXEEXT_20) +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_16) $(am__EXEEXT_17) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_18) $(am__EXEEXT_19) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_20) $(am__EXEEXT_21) subdir = src/transport DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/transport.conf.in @@ -279,37 +279,37 @@ libgnunettransporttesting_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_CFLAGS) $(CFLAGS) $(libgnunettransporttesting_la_LDFLAGS) \ $(LDFLAGS) -o $@ @LINUX_TRUE@am__EXEEXT_1 = gnunet-helper-transport-wlan$(EXEEXT) -@MINGW_FALSE@am__EXEEXT_2 = test_transport_api_unix$(EXEEXT) -@MINGW_FALSE@am__EXEEXT_3 = test_transport_api_timeout_unix$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_4 = test_transport_api_http$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_5 = test_transport_api_http_nat$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_6 = \ +@LINUX_TRUE@am__EXEEXT_2 = \ +@LINUX_TRUE@ gnunet-helper-transport-wlan-dummy$(EXEEXT) +@MINGW_FALSE@am__EXEEXT_3 = test_transport_api_unix$(EXEEXT) +@MINGW_FALSE@am__EXEEXT_4 = test_transport_api_timeout_unix$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_5 = test_transport_api_http$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_6 = test_transport_api_http_nat$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_7 = \ @HAVE_MHD_TRUE@ test_transport_api_timeout_http$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_7 = test_transport_api_https$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_8 = test_transport_api_https_nat$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_9 = \ +@HAVE_MHD_TRUE@am__EXEEXT_8 = test_transport_api_https$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_9 = test_transport_api_https_nat$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_10 = \ @HAVE_MHD_TRUE@ test_transport_api_timeout_https$(EXEEXT) -@MINGW_FALSE@am__EXEEXT_10 = \ +@MINGW_FALSE@am__EXEEXT_11 = \ @MINGW_FALSE@ test_transport_api_unreliability_unix$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_11 = \ +@HAVE_MHD_TRUE@am__EXEEXT_12 = \ @HAVE_MHD_TRUE@ test_transport_api_reliability_http$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_12 = test_transport_api_reliability_http_nat$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_13 = \ +@HAVE_MHD_TRUE@am__EXEEXT_13 = test_transport_api_reliability_http_nat$(EXEEXT) +@HAVE_MHD_TRUE@am__EXEEXT_14 = \ @HAVE_MHD_TRUE@ test_transport_api_reliability_https$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_14 = test_transport_api_reliability_https_nat$(EXEEXT) -@MINGW_FALSE@am__EXEEXT_15 = test_quota_compliance_unix$(EXEEXT) \ +@HAVE_MHD_TRUE@am__EXEEXT_15 = test_transport_api_reliability_https_nat$(EXEEXT) +@MINGW_FALSE@am__EXEEXT_16 = test_quota_compliance_unix$(EXEEXT) \ @MINGW_FALSE@ test_quota_compliance_unix_asymmetric$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_16 = test_quota_compliance_http$(EXEEXT) \ +@HAVE_MHD_TRUE@am__EXEEXT_17 = test_quota_compliance_http$(EXEEXT) \ @HAVE_MHD_TRUE@ test_quota_compliance_http_asymmetric$(EXEEXT) -@HAVE_MHD_TRUE@am__EXEEXT_17 = test_quota_compliance_https$(EXEEXT) \ +@HAVE_MHD_TRUE@am__EXEEXT_18 = test_quota_compliance_https$(EXEEXT) \ @HAVE_MHD_TRUE@ test_quota_compliance_https_asymmetric$(EXEEXT) -@LINUX_TRUE@am__EXEEXT_18 = test_transport_api_wlan$(EXEEXT) -@LINUX_TRUE@am__EXEEXT_19 = \ -@LINUX_TRUE@ test_transport_api_reliability_wlan$(EXEEXT) +@LINUX_TRUE@am__EXEEXT_19 = test_transport_api_wlan$(EXEEXT) @LINUX_TRUE@am__EXEEXT_20 = \ -@LINUX_TRUE@ test_transport_api_unreliability_wlan$(EXEEXT) +@LINUX_TRUE@ test_transport_api_reliability_wlan$(EXEEXT) @LINUX_TRUE@am__EXEEXT_21 = \ -@LINUX_TRUE@ gnunet-helper-transport-wlan-dummy$(EXEEXT) +@LINUX_TRUE@ test_transport_api_unreliability_wlan$(EXEEXT) @LINUX_TRUE@am__EXEEXT_22 = gnunet-transport-wlan-sender$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) am_gnunet_helper_transport_wlan_OBJECTS = \ @@ -947,6 +947,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -980,6 +981,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -1169,7 +1171,7 @@ libgnunettransport_la_LIBADD = \ libgnunettransport_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 0:0:0 + -version-info 1:0:0 #bin_SCRIPTS = \ diff --git a/src/transport/gnunet-helper-transport-wlan-dummy.c b/src/transport/gnunet-helper-transport-wlan-dummy.c index 6fff758..a7015ac 100644 --- a/src/transport/gnunet-helper-transport-wlan-dummy.c +++ b/src/transport/gnunet-helper-transport-wlan-dummy.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + (C) 2010, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -27,22 +27,60 @@ #include "gnunet_util_lib.h" #include "plugin_transport_wlan.h" -#define FIFO_FILE1 "/tmp/test-transport/api-wlan-p1/WLAN_FIFO_in" -#define FIFO_FILE2 "/tmp/test-transport/api-wlan-p1/WLAN_FIFO_out" +/** + * Name of the fifo to use for IPC with the other dummy process. + */ +#define FIFO_FILE1 "/tmp/test-transport/api-wlan-p1/WLAN_FIFO_in" + +/** + * Name of the fifo to use for IPC with the other dummy process. + */ +#define FIFO_FILE2 "/tmp/test-transport/api-wlan-p1/WLAN_FIFO_out" +/** + * Maximum size of a message allowed in either direction + * (used for our receive and sent buffers). + */ #define MAXLINE 4096 -struct sendbuf + +/** + * IO buffer used for buffering data in transit. + */ +struct SendBuffer { - unsigned int pos; - unsigned int size; + + /** + * How many bytes that were stored in 'buf' did we already write to the + * destination? Always smaller than 'size'. + */ + size_t pos; + + /** + * How many bytes of data are stored in 'buf' for transmission right now? + * Data always starts at offset 0 and extends to 'size'. + */ + size_t size; + + /** + * Buffered data; twice the maximum allowed message size as we add some + * headers. + */ char buf[MAXLINE * 2]; }; -static int first; +/** + * Flag set to 1 if we are to terminate, otherwise 0. + */ static int closeprog; + +/** + * We're being killed, clean up. + * + * @param sig killing signal + */ static void sigfunc (int sig) { @@ -53,7 +91,8 @@ sigfunc (int sig) /** - * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin + * Create control message for plugin + * * @param buffer pointer to buffer for the message * @param mac pointer to the mac address * @return number of bytes written @@ -67,83 +106,90 @@ send_mac_to_plugin (char *buffer, struct GNUNET_TRANSPORT_WLAN_MacAddress *mac) memcpy (&macmsg.mac, (char *) mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); macmsg.hdr.size = htons (sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage)); macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL); - memcpy (buffer, &macmsg, sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage)); return sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage); } -static void + +/** + * We got a message from the FIFO, check it, convert the message + * type to the output forward and copy it to the buffer for stdout. + * + * @param cls the 'struct SendBuffer' to copy the converted message to + * @param client unused + * @param hdr inbound message from the FIFO + */ +static int stdin_send (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) { - struct sendbuf *write_pout = cls; - int sendsize; - struct GNUNET_MessageHeader newheader; - char *to_data; - char *to_radiotap; - char *to_start; - - sendsize = - ntohs (hdr->size) - sizeof (struct Radiotap_Send) + - sizeof (struct Radiotap_rx); - - if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) + struct SendBuffer *write_pout = cls; + const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *in; + size_t payload_size; + struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage newheader; + uint16_t sendsize; + + sendsize = ntohs (hdr->size); + in = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr; + if ( (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) || + (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) > sendsize) ) { - fprintf (stderr, "Function stdin_send: wrong packet type\n"); + FPRINTF (stderr, "%s", "Received malformed message\n"); exit (1); } - if ((sendsize + write_pout->size) > MAXLINE * 2) + payload_size = sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage); + if ((payload_size + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) + write_pout->size) > MAXLINE * 2) { - fprintf (stderr, "Function stdin_send: Packet too big for buffer\n"); + FPRINTF (stderr, "%s", "Packet too big for buffer\n"); exit (1); } - - newheader.size = htons (sendsize); - newheader.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); - - to_start = write_pout->buf + write_pout->size; - memcpy (to_start, &newheader, sizeof (struct GNUNET_MessageHeader)); - write_pout->size += sizeof (struct GNUNET_MessageHeader); - - to_radiotap = to_start + sizeof (struct GNUNET_MessageHeader); - memset (to_radiotap, 0, sizeof (struct Radiotap_rx)); - write_pout->size += sizeof (struct Radiotap_rx); - - to_data = to_radiotap + sizeof (struct Radiotap_rx); - memcpy (to_data, - ((char *) hdr) + sizeof (struct Radiotap_Send) + - sizeof (struct GNUNET_MessageHeader), - ntohs (hdr->size) - sizeof (struct Radiotap_Send) - - sizeof (struct GNUNET_MessageHeader)); - write_pout->size += - ntohs (hdr->size) - sizeof (struct Radiotap_Send) - - sizeof (struct GNUNET_MessageHeader); + memset (&newheader, 0, sizeof (newheader)); + newheader.header.size = htons (payload_size + sizeof (newheader)); + newheader.header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER); + newheader.frame = in->frame; + memcpy (write_pout->buf + write_pout->size, + &newheader, + sizeof (newheader)); + write_pout->size += sizeof (newheader); + memcpy (write_pout->buf + write_pout->size, + &in[1], + payload_size); + write_pout->size += payload_size; + return GNUNET_OK; } -static void +/** + * We read a full message from stdin. Copy it to our send buffer. + * + * @param cls the 'struct SendBuffer' to copy to + * @param client unused + * @param hdr the message we received to copy to the buffer + */ +static int file_in_send (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) { - struct sendbuf *write_std = cls; + struct SendBuffer *write_std = cls; uint16_t sendsize; sendsize = ntohs (hdr->size); - - if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) - { - fprintf (stderr, "Function file_in_send: wrong packet type\n"); - exit (1); - } if ((sendsize + write_std->size) > MAXLINE * 2) { - fprintf (stderr, "Function file_in_send: Packet too big for buffer\n"); + FPRINTF (stderr, "%s", "Packet too big for buffer\n"); exit (1); } - memcpy (write_std->buf + write_std->size, hdr, sendsize); write_std->size += sendsize; + return GNUNET_OK; } +/** + * Main function of a program that pretends to be a WLAN card. + * + * @param argc should be 2 + * @param argv either '1' or '2', depending on which of the two cards this dummy is to emulate + * @return 1 on error, 0 if terminated normally via signal + */ int main (int argc, char *argv[]) { @@ -154,105 +200,104 @@ main (int argc, char *argv[]) int fdpin; int fdpout; char readbuf[MAXLINE]; - int readsize = 0; - struct sendbuf write_std; - struct sendbuf write_pout; - int ret = 0; - int maxfd = 0; + int readsize; + struct SendBuffer write_std; + struct SendBuffer write_pout; + int ret; + int maxfd; fd_set rfds; fd_set wfds; struct timeval tv; int retval; - struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst; - struct GNUNET_SERVER_MessageStreamTokenizer *file_in_mst; + struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst = NULL; + struct GNUNET_SERVER_MessageStreamTokenizer *file_in_mst = NULL; struct GNUNET_TRANSPORT_WLAN_MacAddress macaddr; + int first; - if (2 != argc) + if ( (2 != argc) || + ((0 != strcmp (argv[1], "1")) && (0 != strcmp (argv[1], "2"))) ) { - fprintf (stderr, - "This program must be started with the operating mode (1 or 2) as the only argument.\n"); + FPRINTF (stderr, + "%s", + "This program must be started with the operating mode (1 or 2) as the only argument.\n"); return 1; } - if ((0 != strstr (argv[1], "1")) && (0 != strstr (argv[1], "2"))) - return 1; - //make the fifos if needed - if (0 != stat (FIFO_FILE1, &st)) + /* make the fifos if needed */ + umask (0); + if ( (GNUNET_OK != GNUNET_DISK_directory_create_for_file (FIFO_FILE1)) || + (GNUNET_OK != GNUNET_DISK_directory_create_for_file (FIFO_FILE2)) ) { - if (0 == stat (FIFO_FILE2, &st)) - { - fprintf (stderr, "FIFO_FILE2 exists, but FIFO_FILE1 not\n"); - exit (1); - } - umask (0); - erg = mkfifo (FIFO_FILE1, 0666); - if (0 != erg) - { - fprintf (stderr, "Error in mkfifo(%s): %s\n", FIFO_FILE1, - strerror (errno)); - //exit(1); - } - erg = mkfifo (FIFO_FILE2, 0666); - if (0 != erg) + FPRINTF (stderr, "Failed to create directory for file `%s'\n", FIFO_FILE1); + return 1; + } + if (0 == strcmp (argv[1], "1") ) + { + if (0 != stat (FIFO_FILE1, &st)) { - fprintf (stderr, "Error in mkfifo(%s): %s\n", FIFO_FILE2, - strerror (errno)); - //exit(1); + erg = mkfifo (FIFO_FILE1, 0666); + if ( (0 != erg) && (EEXIST != errno) ) + FPRINTF (stderr, "Error in mkfifo(%s): %s\n", FIFO_FILE1, + strerror (errno)); } - } else { if (0 != stat (FIFO_FILE2, &st)) { - fprintf (stderr, "FIFO_FILE1 exists, but FIFO_FILE2 not\n"); - exit (1); + erg = mkfifo (FIFO_FILE2, 0666); + if ( (0 != erg) && (EEXIST != errno) ) + FPRINTF (stderr, "Error in mkfifo(%s): %s\n", FIFO_FILE2, + strerror (errno)); } } - if (strstr (argv[1], "1")) + if (0 == strcmp (argv[1], "1")) { - //fprintf(stderr, "First\n"); first = 1; fpin = fopen (FIFO_FILE1, "r"); if (NULL == fpin) { - fprintf (stderr, "fopen of read FIFO_FILE1\n"); + FPRINTF (stderr, "fopen of read FIFO_FILE1 failed: %s\n", STRERROR (errno)); goto end; } - fpout = fopen (FIFO_FILE2, "w"); + if (NULL == (fpout = fopen (FIFO_FILE2, "w"))) + { + erg = mkfifo (FIFO_FILE2, 0666); + fpout = fopen (FIFO_FILE2, "w"); + } if (NULL == fpout) { - fprintf (stderr, "fopen of write FIFO_FILE2\n"); + FPRINTF (stderr, "fopen of write FIFO_FILE2 failed: %s\n", STRERROR (errno)); goto end; } - } else { first = 0; - //fprintf(stderr, "Second\n"); - fpout = fopen (FIFO_FILE1, "w"); + if (NULL == (fpout = fopen (FIFO_FILE1, "w"))) + { + erg = mkfifo (FIFO_FILE1, 0666); + fpout = fopen (FIFO_FILE1, "w"); + } if (NULL == fpout) { - fprintf (stderr, "fopen of write FIFO_FILE1\n"); + FPRINTF (stderr, "fopen of write FIFO_FILE1 failed: %s\n", STRERROR (errno)); goto end; } fpin = fopen (FIFO_FILE2, "r"); if (NULL == fpin) { - fprintf (stderr, "fopen of read FIFO_FILE2\n"); + FPRINTF (stderr, "fopen of read FIFO_FILE2 failed: %s\n", STRERROR (errno)); goto end; } - } fdpin = fileno (fpin); GNUNET_assert (fpin >= 0); - if (fdpin >= FD_SETSIZE) { - fprintf (stderr, "File fdpin number too large (%d > %u)\n", fdpin, + FPRINTF (stderr, "File fdpin number too large (%d > %u)\n", fdpin, (unsigned int) FD_SETSIZE); goto end; } @@ -262,10 +307,9 @@ main (int argc, char *argv[]) if (fdpout >= FD_SETSIZE) { - fprintf (stderr, "File fdpout number too large (%d > %u)\n", fdpout, + FPRINTF (stderr, "File fdpout number too large (%d > %u)\n", fdpout, (unsigned int) FD_SETSIZE); goto end; - } signal (SIGINT, &sigfunc); @@ -278,7 +322,7 @@ main (int argc, char *argv[]) stdin_mst = GNUNET_SERVER_mst_create (&stdin_send, &write_pout); file_in_mst = GNUNET_SERVER_mst_create (&file_in_send, &write_std); - //Send random mac address + /* Send 'random' mac address */ macaddr.mac[0] = 0x13; macaddr.mac[1] = 0x22; macaddr.mac[2] = 0x33; @@ -290,12 +334,12 @@ main (int argc, char *argv[]) while (0 == closeprog) { maxfd = -1; - //set timeout tv.tv_sec = 5; tv.tv_usec = 0; FD_ZERO (&rfds); - // if output queue is empty + FD_ZERO (&wfds); + /* if output queue is empty, read */ if (0 == write_pout.size) { FD_SET (STDIN_FILENO, &rfds); @@ -306,8 +350,8 @@ main (int argc, char *argv[]) FD_SET (fdpin, &rfds); maxfd = MAX (fdpin, maxfd); } - FD_ZERO (&wfds); - // if there is something to write + + /* if there is something to write, try to write */ if (0 < write_std.size) { FD_SET (STDOUT_FILENO, &wfds); @@ -324,7 +368,7 @@ main (int argc, char *argv[]) continue; if (0 > retval) { - fprintf (stderr, "select failed: %s\n", strerror (errno)); + FPRINTF (stderr, "select failed: %s\n", STRERROR (errno)); closeprog = 1; break; } @@ -337,14 +381,14 @@ main (int argc, char *argv[]) if (0 > ret) { closeprog = 1; - fprintf (stderr, "Write ERROR to STDOUT_FILENO: %s\n", - strerror (errno)); + FPRINTF (stderr, "Write ERROR to STDOUT_FILENO: %s\n", + STRERROR (errno)); break; } else { write_std.pos += ret; - // check if finished + /* check if finished writing */ if (write_std.pos == write_std.size) { write_std.pos = 0; @@ -362,12 +406,12 @@ main (int argc, char *argv[]) if (0 > ret) { closeprog = 1; - fprintf (stderr, "Write ERROR to fdpout: %s\n", strerror (errno)); + FPRINTF (stderr, "Write ERROR to fdpout failed: %s\n", STRERROR (errno)); } else { write_pout.pos += ret; - // check if finished + /* check if finished writing */ if (write_pout.pos == write_pout.size) { write_pout.pos = 0; @@ -383,8 +427,8 @@ main (int argc, char *argv[]) if (0 > readsize) { closeprog = 1; - fprintf (stderr, "Error reading from STDIN_FILENO: %s\n", - strerror (errno)); + FPRINTF (stderr, "Error reading from STDIN_FILENO: %s\n", + STRERROR (errno)); } else if (0 < readsize) { @@ -394,7 +438,7 @@ main (int argc, char *argv[]) } else { - //eof + /* eof */ closeprog = 1; } } @@ -405,7 +449,7 @@ main (int argc, char *argv[]) if (0 > readsize) { closeprog = 1; - fprintf (stderr, "Error reading from fdpin: %s\n", strerror (errno)); + FPRINTF (stderr, "Error reading from fdpin: %s\n", STRERROR (errno)); break; } else if (0 < readsize) @@ -415,20 +459,22 @@ main (int argc, char *argv[]) } else { - //eof + /* eof */ closeprog = 1; } } } - //clean up - GNUNET_SERVER_mst_destroy (stdin_mst); - GNUNET_SERVER_mst_destroy (file_in_mst); - end: - if (fpout != NULL) + /* clean up */ + if (NULL != stdin_mst) + GNUNET_SERVER_mst_destroy (stdin_mst); + if (NULL != file_in_mst) + GNUNET_SERVER_mst_destroy (file_in_mst); + + if (NULL != fpout) fclose (fpout); - if (fpin != NULL) + if (NULL != fpin) fclose (fpin); if (1 == first) { diff --git a/src/transport/gnunet-helper-transport-wlan.c b/src/transport/gnunet-helper-transport-wlan.c index 582df7c..363925c 100644 --- a/src/transport/gnunet-helper-transport-wlan.c +++ b/src/transport/gnunet-helper-transport-wlan.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010, 2011 Christian Grothoff (and other contributing authors) + (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors) Copyright (c) 2007, 2008, Andy Green Copyright (C) 2009 Thomas d'Otreppe @@ -21,12 +21,48 @@ */ /** * @file src/transport/gnunet-helper-transport-wlan.c - * @brief wlan layer two server; must run as root (SUID will do) + * @brief mediator between the wlan interface and gnunet; must run as root (SUID will do) * This code will work under GNU/Linux only. * @author David Brodski + * @author Christian Grothoff * - * This program serves as the mediator between the wlan interface and - * gnunet + * This program will allow receiving and sending traffic from the WLAN + * interface. It will force traffic to be in 'ad-hoc' mode, use the + * proper MAC address of the WLAN interface and use a GNUnet-specific + * SSID (and a GNUnet-specific SNAP header). It only takes a single + * argument, which is the name of the WLAN interface to use. The + * program detects if the interface is not a WLAN interface and exits + * with an error in that case. + * + * Once initialized, the program will first send a 'struct + * GNUNET_TRANSPORT_WLAN_HelperControlMessage' to 'stdout'. That + * message contains the MAC address of the WLAN interface. It will + * then read messages from the WLAN interface and send them together + * with performance information as 'struct + * GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage' messages to 'stdout'. + * Furthermore, it will read a stream of messages from 'stdin' that + * have the format from 'struct + * GNUNET_TRANSPORT_WLAN_RadiotapSendMessage'. Those messages will + * then be sent via the WLAN interface; however, the sender MAC + * address will be forced to be the correct address from our WLAN + * card. If 'stdin' closes, receiving from the WLAN interface will + * continue. If 'stdout' causes a SIGPIPE, the process dies from the + * signal. Errors cause an error message to be reported to 'stderr', + * in most cases the process also exits (with status code '1'). The + * program never terminates normally; it is safe to kill the + * process with SIGTERM or SIGKILL at any time. + * + * Since it uses RAW sockets, the binary must be installed SUID or run + * as 'root'. In order to keep the security risk of the resulting + * SUID binary minimal, the program ONLY opens the RAW socket with + * root privileges, then drops them and only then starts to process + * command line arguments. The code also does not link against any + * shared libraries (except libc) and is strictly minimal (except for + * checking for errors). The following list of people have reviewed + * this code and considered it safe since the last modification (if + * you reviewed it, please have your name added to the list): + * + * - Christian Grothoff (Apr 3rd 2012) */ /*- @@ -70,10 +106,10 @@ * Modifications to fit into the linux IEEE 802.11 stack, * Mike Kershaw (dragorn@kismetwireless.net) */ - -/** +/* * parts taken from aircrack-ng, parts changend. */ + #define _GNU_SOURCE #include #include @@ -102,183 +138,429 @@ #include "gnunet_protocols.h" #include "plugin_transport_wlan.h" +/** + * Packet format type for the messages we receive from + * the kernel. This is for plain messages (with no + * performance information included). + */ #define ARPHRD_IEEE80211 801 + +/** + * Packet format type for the messages we receive from + * the kernel. This is for the PRISM format. + */ #define ARPHRD_IEEE80211_PRISM 802 -#define ARPHRD_IEEE80211_FULL 803 /** - * size of 802.11 address + * Packet format type for the messages we receive from + * the kernel. This is for messages with a + * 'struct Ieee80211RadiotapHeader' (see below). */ -#define IEEE80211_ADDR_LEN 6 +#define ARPHRD_IEEE80211_FULL 803 + /** - * Maximum size of a message allowed in either direction. + * Maximum size of a message allowed in either direction + * (used for our receive and sent buffers). */ #define MAXLINE 4096 -#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000 +/* ********* structure of messages of type ARPHRD_IEEE80211_PRISM *********** */ -/* Name Data type Units - * ---- --------- ----- - * - * IEEE80211_RADIOTAP_TSFT __le64 microseconds - * - * Value in microseconds of the MAC's 64-bit 802.11 Time - * Synchronization Function timer when the first bit of the - * MPDU arrived at the MAC. For received frames, only. - * - * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap - * - * Tx/Rx frequency in MHz, followed by flags (see below). - * - * IEEE80211_RADIOTAP_FHSS __le16 see below - * - * For frequency-hopping radios, the hop set (first byte) - * and pattern (second byte). - * - * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s - * - * Tx/Rx data rate - * - * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from - * one milliwatt (dBm) - * - * RF signal power at the antenna, decibel difference from - * one milliwatt. - * - * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from - * one milliwatt (dBm) - * - * RF noise power at the antenna, decibel difference from one - * milliwatt. - * - * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) - * - * RF signal power at the antenna, decibel difference from an - * arbitrary, fixed reference. - * - * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) - * - * RF noise power at the antenna, decibel difference from an - * arbitrary, fixed reference point. - * - * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless - * - * Quality of Barker code lock. Unitless. Monotonically - * nondecreasing with "better" lock strength. Called "Signal - * Quality" in datasheets. (Is there a standard way to measure - * this?) - * - * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless - * - * Transmit power expressed as unitless distance from max - * power set at factory calibration. 0 is max power. - * Monotonically nondecreasing with lower power levels. - * - * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB) - * - * Transmit power expressed as decibel distance from max power - * set at factory calibration. 0 is max power. Monotonically - * nondecreasing with lower power levels. - * - * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from - * one milliwatt (dBm) - * - * Transmit power expressed as dBm (decibels from a 1 milliwatt - * reference). This is the absolute power level measured at - * the antenna port. - * - * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap - * - * Properties of transmitted and received frames. See flags - * defined below. - * - * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index - * - * Unitless indication of the Rx/Tx antenna for this packet. - * The first antenna is antenna 0. - * - * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap - * - * Properties of received frames. See flags defined below. - * - * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap - * - * Properties of transmitted frames. See flags defined below. - * - * IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data - * - * Number of rts retries a transmitted frame used. - * - * IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data - * - * Number of unicast retries a transmitted frame used. - * +/** + * Device name length in PRISM frames. + * (In the kernel, this is "WLAN_DEVNAMELEN_MAX") + */ +#define PRISM_DEVICE_NAME_LENGTH 16 + +/** + * Monitor Frame (indicator that we have a 'struct PrismHeader'). + */ +#define PRISM_MSGCODE_MONITOR 0x0041 + +/** + * Mac time element. In micro-seconds. + * Drivers appear to use a 64bit counter to hold mactime internal + * the then fill the prism header with the lower 32 bits + */ +#define PRISM_DID_MACTIME 0x2041 + +/** + * Channel element + */ +#define PRISM_DID_CHANNEL 0x3041 + +/** + * Signal element. Should be the signal strength in dbm, some people + * suggest that instead "100 - (strength in dbm)" is used (to make this + * a positive integer). + */ +#define PRISM_DID_SIGNAL 0x6041 + +/** + * Noise element + */ +#define PRISM_DID_NOISE 0x7041 + +/** + * Rate element, in units/multiples of 500Khz + */ +#define PRISM_DID_RATE 0x8041 + + +/** + * Value is set (supplied) + */ +#define PRISM_STATUS_OK 0 + +/** + * Value not supplied. + */ +#define PRISM_STATUS_NO_VALUE 1 + + +/** + * Values in the 'struct PrismHeader'. All in host byte order (!). + */ +struct PrismValue +{ + /** + * This has a different ID for each parameter, see + * PRISM_DID_* constants. + */ + uint32_t did; + + /** + * See PRISM_STATUS_*-constants. Note that they are unusual: 0 = set; 1 = not set + */ + uint16_t status; + + /** + * length of data (which is always a uint32_t, but presumably this can be used + * to specify that fewer bytes are used (with values in 'len' from 0-4). We + * ignore this field. + */ + uint16_t len; + + /** + * The data value + */ + uint32_t data; + +} __attribute__ ((packed)); + + +/** + * Prism header format ('struct p80211msg' in Linux). All in host byte order (!). + */ +struct PrismHeader +{ + /** + * We expect this to be a PRISM_MSGCODE_*. + */ + uint32_t msgcode; + + /** + * The length of the entire header. + */ + uint32_t msglen; + + /** + * Name of the device that captured the packet. + */ + char devname[PRISM_DEVICE_NAME_LENGTH]; + + /* followed by 'struct PrismValue's. Documentation suggests that these + are typically the hosttime, mactime, channel, rssi, sq, signal, noise, + rate, istx and frmlen values, but documentation is sparse. So we + will use the 'did' fields to find out what we actually got. */ + +} __attribute__ ((packed)); + + +/* ****** end of structure of messages of type ARPHRD_IEEE80211_PRISM ******* */ + +/* ********** structure of messages of type ARPHRD_IEEE80211_FULL *********** */ + +/** + * Bits in the 'it_present' bitmask from the 'struct + * Ieee80211RadiotapHeader'. For each value, we give the name, data + * type, unit and then a description below. Note that the actual size + * of the extension can be bigger as arguments must be padded so that + * args of a given length must begin at a boundary of that length. + * However, note that compound args are allowed (eg, 2 x uint16_t for + * IEEE80211_RADIOTAP_CHANNEL) so total argument length is not a + * reliable indicator of alignment requirement. See also + * 'man 9 ieee80211_radiotap'. */ enum RadiotapType { + + /** + * IEEE80211_RADIOTAP_TSFT __le64 microseconds + * + * Value in microseconds of the MAC's 64-bit 802.11 Time + * Synchronization Function timer when the first bit of the + * MPDU arrived at the MAC. For received frames, only. + */ IEEE80211_RADIOTAP_TSFT = 0, + + /** + * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap + * + * Properties of transmitted and received frames. See flags + * defined below. + */ IEEE80211_RADIOTAP_FLAGS = 1, + + /** + * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s + * + * Tx/Rx data rate + */ IEEE80211_RADIOTAP_RATE = 2, + + /** + * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap + * + * Tx/Rx frequency in MHz, followed by flags (see below). + */ IEEE80211_RADIOTAP_CHANNEL = 3, + /** + * IEEE80211_RADIOTAP_FHSS __le16 see below + * + * For frequency-hopping radios, the hop set (first byte) + * and pattern (second byte). + */ IEEE80211_RADIOTAP_FHSS = 4, + + /** + * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from + * one milliwatt (dBm) + * + * RF signal power at the antenna, decibel difference from + * one milliwatt. + */ IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, + + /** + * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from + * one milliwatt (dBm) + * + * RF noise power at the antenna, decibel difference from one + * milliwatt. + */ IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, + + /** + * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless + * + * Quality of Barker code lock. Unitless. Monotonically + * nondecreasing with "better" lock strength. Called "Signal + * Quality" in datasheets. (Is there a standard way to measure + * this?) + */ IEEE80211_RADIOTAP_LOCK_QUALITY = 7, + + /** + * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless + * + * Transmit power expressed as unitless distance from max + * power set at factory calibration. 0 is max power. + * Monotonically nondecreasing with lower power levels. + */ IEEE80211_RADIOTAP_TX_ATTENUATION = 8, + + /** + * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB) + * + * Transmit power expressed as decibel distance from max power + * set at factory calibration. 0 is max power. Monotonically + * nondecreasing with lower power levels. + */ IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, + + /** + * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from + * one milliwatt (dBm) + * + * Transmit power expressed as dBm (decibels from a 1 milliwatt + * reference). This is the absolute power level measured at + * the antenna port. + */ IEEE80211_RADIOTAP_DBM_TX_POWER = 10, + + /** + * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index + * + * Unitless indication of the Rx/Tx antenna for this packet. + * The first antenna is antenna 0. + */ IEEE80211_RADIOTAP_ANTENNA = 11, + + /** + * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) + * + * RF signal power at the antenna, decibel difference from an + * arbitrary, fixed reference. + */ IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, + + /** + * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) + * + * RF noise power at the antenna, decibel difference from an + * arbitrary, fixed reference point. + */ IEEE80211_RADIOTAP_DB_ANTNOISE = 13, + + /** + * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap + * + * Properties of received frames. See flags defined below. + */ IEEE80211_RADIOTAP_RX_FLAGS = 14, + + /** + * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap + * + * Properties of transmitted frames. See flags defined below. + */ IEEE80211_RADIOTAP_TX_FLAGS = 15, + + /** + * IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data + * + * Number of rts retries a transmitted frame used. + */ IEEE80211_RADIOTAP_RTS_RETRIES = 16, + + /** + * IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data + * + * Number of unicast retries a transmitted frame used. + */ IEEE80211_RADIOTAP_DATA_RETRIES = 17, + + /** + * Extension bit, used to indicate that more bits are needed for + * the bitmask. + */ IEEE80211_RADIOTAP_EXT = 31 }; -/* For IEEE80211_RADIOTAP_FLAGS */ -#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received - * during CFP - */ -#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received - * with short - * preamble - */ -#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received - * with WEP encryption - */ -#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received - * with fragmentation - */ -#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ -#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between - * 802.11 header and payload - * (to 32-bit boundary) - */ -/* For IEEE80211_RADIOTAP_RX_FLAGS */ -#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ - -/* For IEEE80211_RADIOTAP_TX_FLAGS */ -#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive - * retries */ -#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ -#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ -#define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* frame should not be ACKed */ -#define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010 /* sequence number handled - * by userspace */ +/** + * Bitmask indicating an extension of the bitmask is used. + * (Mask corresponding to IEEE80211_RADIOTAP_EXT). + */ +#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK (1 << IEEE80211_RADIOTAP_EXT) + + + +/** + * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get + * as part of a 'struct Ieee80211RadiotapHeader' extension + * if the IEEE80211_RADIOTAP_FLAGS bit is set in + * 'it_present'). The radiotap flags are an 8-bit field. + * + * Frame was sent/received during CFP (Contention Free Period) + */ +#define IEEE80211_RADIOTAP_F_CFP 0x01 +/** + * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get + * as part of a 'struct Ieee80211RadiotapHeader' extension + * if the IEEE80211_RADIOTAP_FLAGS bit is set in + * 'it_present'). The radiotap flags are an 8-bit field. + * + * Frame was sent/received with short preamble + */ +#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 + +/** + * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get + * as part of a 'struct Ieee80211RadiotapHeader' extension + * if the IEEE80211_RADIOTAP_FLAGS bit is set in + * 'it_present'). The radiotap flags are an 8-bit field. + * + * Frame was sent/received with WEP encryption + */ +#define IEEE80211_RADIOTAP_F_WEP 0x04 /** - * A generic radio capture format is desirable. There is one for - * Linux, but it is neither rigidly defined (there were not even - * units given for some fields) nor easily extensible. + * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get + * as part of a 'struct Ieee80211RadiotapHeader' extension + * if the IEEE80211_RADIOTAP_FLAGS bit is set in + * 'it_present'). The radiotap flags are an 8-bit field. * - * I suggest the following extensible radio capture format. It is - * based on a bitmap indicating which fields are present. + * Frame was sent/received with fragmentation + */ +#define IEEE80211_RADIOTAP_F_FRAG 0x08 + +/** + * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get + * as part of a 'struct Ieee80211RadiotapHeader' extension + * if the IEEE80211_RADIOTAP_FLAGS bit is set in + * 'it_present'). The radiotap flags are an 8-bit field. + * + * Frame includes FCS (CRC at the end that needs to be removeD). + */ +#define IEEE80211_RADIOTAP_F_FCS 0x10 + +/** + * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get + * as part of a 'struct Ieee80211RadiotapHeader' extension + * if the IEEE80211_RADIOTAP_FLAGS bit is set in + * 'it_present'). The radiotap flags are an 8-bit field. + * + * Frame has padding between 802.11 header and payload + * (to 32-bit boundary) + */ +#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 + + +/** + * For IEEE80211_RADIOTAP_RX_FLAGS: + * frame failed crc check + */ +#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 + +/** + * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'): + * failed due to excessive retries + */ +#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 + +/** + * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'): + * used cts 'protection' + */ +#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 + +/** + * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'): + * used rts/cts handshake + */ +#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 + +/** + * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'): + * frame should not be ACKed + */ +#define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 + +/** + * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'): + * sequence number handled by userspace + */ +#define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010 + + +/** + * Generic header for radiotap messages (receiving and sending). A + * bit mask (it_present) determines which specific records follow. * * I am trying to describe precisely what the application programmer * should expect in the following, and for that reason I tell the @@ -290,13 +572,17 @@ enum RadiotapType * The radio capture header precedes the 802.11 header. * All data in the header is little endian on all platforms. */ -struct ieee80211_radiotap_header +struct Ieee80211RadiotapHeader { /** * Version 0. Only increases for drastic changes, introduction of * compatible new fields does not count. */ uint8_t it_version; + + /** + * Padding. Set to 0. + */ uint8_t it_pad; /** @@ -313,89 +599,106 @@ struct ieee80211_radiotap_header uint32_t it_present; }; + /** - * + * Format of the header we need to prepend to messages to be sent to the + * Kernel. */ -struct RadioTapheader +struct RadiotapTransmissionHeader { + /** - * + * First we begin with the 'generic' header we also get when receiving + * messages. */ - struct ieee80211_radiotap_header header; + struct Ieee80211RadiotapHeader header; /** - * + * Transmission rate (we use 0, kernel makes up its mind anyway). */ uint8_t rate; /** - * + * Padding (we use 0). There is a requirement to pad args, so that + * args of a given length must begin at a boundary of that length. + * As our next argument is the 'it_len' with 2 bytes, we need 1 byte + * of padding. */ uint8_t pad1; /** - * + * Transmission flags from on the IEEE80211_RADIOTAP_F_TX_* constant family. */ uint16_t txflags; + }; +/** + * The above 'struct RadiotapTransmissionHeader' should have the + * following value for 'header.it_present' based on the presence of + * the 'rate' and 'txflags' in the overall struct. + */ +#define IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK ((1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_TX_FLAGS)) + + /** - * IO buffer used for buffering data in transit (to wireless or to stdout). + * struct Ieee80211RadiotapHeaderIterator - tracks walk through present radiotap arguments + * in the radiotap header. Used when we parse radiotap packets received from the kernel. */ -struct SendBuffer +struct Ieee80211RadiotapHeaderIterator { /** - * How many bytes of data are stored in 'buf' for transmission right now? - * Data always starts at offset 0 and extends to 'size'. + * pointer to the radiotap header we are walking through */ - size_t size; + const struct Ieee80211RadiotapHeader *rtheader; /** - * How many bytes that were stored in 'buf' did we already write to the - * destination? Always smaller than 'size'. + * pointer to current radiotap arg */ - size_t pos; - + const uint8_t *this_arg; + /** - * Buffered data; twice the maximum allowed message size as we add some - * headers. + * internal next argument pointer */ - char buf[MAXLINE * 2]; -}; + const uint8_t *arg; -/** - * Buffer for data read from stdin to be transmitted to the wirless card. - */ -static struct SendBuffer write_pout; + /** + * internal pointer to next present uint32_t (if IEEE80211_RADIOTAP_EXT is used). + */ + const uint32_t *next_bitmap; -/** - * Buffer for data read from the wireless card to be transmitted to stdout. - */ -static struct SendBuffer write_std; + /** + * length of radiotap header in host byte ordering + */ + size_t max_length; + /** + * internal shifter for current uint32_t bitmap, (it_present in host byte order), + * If bit 0 is set, the 'arg_index' argument is present. + */ + uint32_t bitmap_shifter; -GNUNET_NETWORK_STRUCT_BEGIN + /** + * IEEE80211_RADIOTAP_... index of current arg + */ + unsigned int this_arg_index; + + /** + * internal next argument index + */ + unsigned int arg_index; + +}; -/** - * generic definitions for IEEE 802.11 frames - */ -struct ieee80211_frame -{ - uint8_t i_fc[2]; - uint8_t i_dur[2]; - uint8_t i_addr1[IEEE80211_ADDR_LEN]; - uint8_t i_addr2[IEEE80211_ADDR_LEN]; - uint8_t i_addr3[IEEE80211_ADDR_LEN]; - uint8_t i_seq[2]; - /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ - /* see below */ -} GNUNET_PACKED; -GNUNET_NETWORK_STRUCT_END +/* ************** end of structure of ARPHRD_IEEE80211_FULL ************** */ + +/* ************************** our globals ******************************* */ /** - * struct for storing the information of the hardware + * struct for storing the information of the hardware. There is only + * one of these. */ struct HardwareInfos { @@ -424,56 +727,48 @@ struct HardwareInfos /** - * struct ieee80211_radiotap_iterator - tracks walk through present radiotap arguments - * in the radiotap header. + * IO buffer used for buffering data in transit (to wireless or to stdout). */ -struct ieee80211_radiotap_iterator +struct SendBuffer { /** - * pointer to the radiotap header we are walking through - */ - const struct ieee80211_radiotap_header *rtheader; - - /** - * length of radiotap header in cpu byte ordering - */ - size_t max_length; - - /** - * IEEE80211_RADIOTAP_... index of current arg + * How many bytes of data are stored in 'buf' for transmission right now? + * Data always starts at offset 0 and extends to 'size'. */ - unsigned int this_arg_index; + size_t size; /** - * pointer to current radiotap arg + * How many bytes that were stored in 'buf' did we already write to the + * destination? Always smaller than 'size'. */ - uint8_t *this_arg; - + size_t pos; + /** - * internal next argument index + * Buffered data; twice the maximum allowed message size as we add some + * headers. */ - unsigned int arg_index; + char buf[MAXLINE * 2]; +}; - /** - * internal next argument pointer - */ - uint8_t *arg; - /** - * internal pointer to next present uint32_t - */ - uint32_t *next_bitmap; +/** + * Buffer for data read from stdin to be transmitted to the wirless card. + */ +static struct SendBuffer write_pout; - /** - * internal shifter for curr uint32_t bitmap, b0 set == arg present - */ - uint32_t bitmap_shifter; -}; +/** + * Buffer for data read from the wireless card to be transmitted to stdout. + */ +static struct SendBuffer write_std; -/* specialized version of server_mst.c begins here */ +/* *********** specialized version of server_mst.c begins here ********** */ +/** + * To what multiple do we align messages? 8 byte should suffice for everyone + * for now. + */ #define ALIGN_FACTOR 8 /** @@ -533,7 +828,6 @@ struct MessageStreamTokenizer }; - /** * Create a message stream tokenizer. * @@ -549,10 +843,16 @@ mst_create (MessageTokenizerCallback cb, ret = malloc (sizeof (struct MessageStreamTokenizer)); if (NULL == ret) + { + fprintf (stderr, "Failed to allocate buffer for tokenizer\n"); exit (1); + } ret->hdr = malloc (MIN_BUFFER_SIZE); if (NULL == ret->hdr) - exit (2); + { + fprintf (stderr, "Failed to allocate buffer for alignment\n"); + exit (1); + } ret->curr_buf = MIN_BUFFER_SIZE; ret->cb = cb; ret->cb_cls = cb_cls; @@ -613,8 +913,9 @@ do_align: want = ntohs (hdr->size); if (want < sizeof (struct GNUNET_MessageHeader)) { - // GNUNET_break_op (0); - return GNUNET_SYSERR; + fprintf (stderr, + "Received invalid message from stdin\n"); + exit (1); } if (mst->curr_buf - mst->off < want) { @@ -627,7 +928,10 @@ do_align: { mst->hdr = realloc (mst->hdr, want); if (NULL == mst->hdr) - exit (3); + { + fprintf (stderr, "Failed to allocate buffer for alignment\n"); + exit (1); + } ibuf = (char *) mst->hdr; mst->curr_buf = want; } @@ -666,9 +970,9 @@ do_align: want = ntohs (hdr->size); if (want < sizeof (struct GNUNET_MessageHeader)) { - // GNUNET_break_op (0); - mst->off = 0; - return GNUNET_SYSERR; + fprintf (stderr, + "Received invalid message from stdin\n"); + exit (1); } if (size < want) break; /* or not, buffer incomplete, so copy to private buffer... */ @@ -689,11 +993,19 @@ do_align: { mst->hdr = realloc (mst->hdr, size + mst->pos); if (NULL == mst->hdr) - exit (4); + { + fprintf (stderr, "Failed to allocate buffer for alignment\n"); + exit (1); + } ibuf = (char *) mst->hdr; mst->curr_buf = size + mst->pos; } - // GNUNET_assert (mst->pos + size <= mst->curr_buf); + if (mst->pos + size > mst->curr_buf) + { + fprintf (stderr, + "Assertion failed\n"); + exit (1); + } memcpy (&ibuf[mst->pos], buf, size); mst->pos += size; } @@ -713,16 +1025,16 @@ mst_destroy (struct MessageStreamTokenizer *mst) free (mst); } -/* end of server_mst.c copy */ - +/* ***************** end of server_mst.c clone ***************** **/ +/* ************** code for handling of ARPHRD_IEEE80211_FULL ************** */ /** * Radiotap header iteration * * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator - * struct ieee80211_radiotap_iterator (no need to init the struct beforehand) + * struct Ieee80211RadiotapHeaderIterator (no need to init the struct beforehand) * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1 * if there are no more args in the header, or the next argument type index * that is present. The iterator's this_arg member points to the start of the @@ -736,9 +1048,8 @@ mst_destroy (struct MessageStreamTokenizer *mst) * @return 0 on success, -1 on error */ static int -ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator, - const struct ieee80211_radiotap_header - *radiotap_header, +ieee80211_radiotap_iterator_init (struct Ieee80211RadiotapHeaderIterator *iterator, + const struct Ieee80211RadiotapHeader *radiotap_header, size_t max_length) { if ( (iterator == NULL) || @@ -750,26 +1061,22 @@ ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator, return -1; /* sanity check for allowed length and radiotap length field */ - if ( (max_length < sizeof (struct ieee80211_radiotap_header)) || + if ( (max_length < sizeof (struct Ieee80211RadiotapHeader)) || (max_length < (GNUNET_le16toh (radiotap_header->it_len))) ) return -1; + memset (iterator, 0, sizeof (struct Ieee80211RadiotapHeaderIterator)); iterator->rtheader = radiotap_header; iterator->max_length = GNUNET_le16toh (radiotap_header->it_len); - iterator->arg_index = 0; iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present); - iterator->arg = - ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header); - iterator->this_arg = 0; + iterator->arg = ((uint8_t *) radiotap_header) + sizeof (struct Ieee80211RadiotapHeader); /* find payload start allowing for extended bitmap(s) */ - if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)) + if (0 != (iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)) { - while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) & - IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK) + while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK) { iterator->arg += sizeof (uint32_t); - /* * check for insanity where the present bitmaps * keep claiming to extend up to or even beyond the @@ -791,7 +1098,7 @@ ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator, /** - * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg + * Returns the next radiotap parser iterator arg. * * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...) * and sets iterator->this_arg to point to the payload for the arg. It takes @@ -800,13 +1107,11 @@ ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator, * format. * * @param iterator: radiotap_iterator to move to next arg (if any) - * * @return next present arg index on success or -1 if no more or error */ static int -ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator) +ieee80211_radiotap_iterator_next (struct Ieee80211RadiotapHeaderIterator *iterator) { - /* * small length lookup table for all radiotap types we heard of * starting from b0 in the bitmap, so we can walk the payload @@ -851,120 +1156,103 @@ ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator) * for every radiotap entry we can at * least skip (by knowing the length)... */ - while (iterator->arg_index < sizeof (rt_sizes)) { - int hit = 0; - - if (!(iterator->bitmap_shifter & 1)) - goto next_entry; /* arg not present */ - - /* - * arg is present, account for alignment padding - * 8-bit args can be at any alignment - * 16-bit args must start on 16-bit boundary - * 32-bit args must start on 32-bit boundary - * 64-bit args must start on 64-bit boundary - * - * note that total arg size can differ from alignment of - * elements inside arg, so we use upper nybble of length - * table to base alignment on - * - * also note: these alignments are ** relative to the - * start of the radiotap header **. There is no guarantee - * that the radiotap header itself is aligned on any - * kind of boundary. - */ - - if ((((void *) iterator->arg) - - ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4) - - 1)) - iterator->arg_index += - (rt_sizes[iterator->arg_index] >> 4) - - ((((void *) iterator->arg) - - ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> - 4) - 1)); - - /* - * this is what we will return to user, but we need to - * move on first so next call has something fresh to test - */ - - iterator->this_arg_index = iterator->arg_index; - iterator->this_arg = iterator->arg; - hit = 1; - - /* internally move on the size of this arg */ - - iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; - - /* - * check for insanity where we are given a bitmap that - * claims to have more arg content than the length of the - * radiotap section. We will normally end up equalling this - * max_length on the last arg, never exceeding it. - */ - - if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > - iterator->max_length) - return -1; + int hit = (0 != (iterator->bitmap_shifter & 1)); -next_entry: + if (hit) + { + unsigned int wanted_alignment; + unsigned int unalignment; + /* + * arg is present, account for alignment padding + * 8-bit args can be at any alignment + * 16-bit args must start on 16-bit boundary + * 32-bit args must start on 32-bit boundary + * 64-bit args must start on 64-bit boundary + * + * note that total arg size can differ from alignment of + * elements inside arg, so we use upper nybble of length table + * to base alignment on. First, 'wanted_alignment' is set to be + * 1 for 8-bit, 2 for 16-bit, 4 for 32-bit and 8 for 64-bit + * arguments. Then, we calculate the 'unalignment' (how many + * bytes we are over by taking the difference of 'arg' and the + * overall starting point modulo the desired alignment. As + * desired alignments are powers of two, we can do modulo with + * binary "&" (and also avoid the possibility of a division by + * zero if the 'rt_sizes' table contains bogus entries). + * + * also note: these alignments are relative to the start of the + * radiotap header. There is no guarantee that the radiotap + * header itself is aligned on any kind of boundary, thus we + * need to really look at the delta here. + */ + wanted_alignment = rt_sizes[iterator->arg_index] >> 4; + unalignment = (((void *) iterator->arg) - ((void *) iterator->rtheader)) & (wanted_alignment - 1); + if (0 != unalignment) + { + /* need padding (by 'wanted_alignment - unalignment') */ + iterator->arg_index += wanted_alignment - unalignment; + } + + /* + * this is what we will return to user, but we need to + * move on first so next call has something fresh to test + */ + iterator->this_arg_index = iterator->arg_index; + iterator->this_arg = iterator->arg; + + /* internally move on the size of this arg (using lower nybble from + the table) */ + iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; + + /* + * check for insanity where we are given a bitmap that + * claims to have more arg content than the length of the + * radiotap section. We will normally end up equalling this + * max_length on the last arg, never exceeding it. + */ + if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > iterator->max_length) + return -1; + } + /* Now, move on to next bit / next entry */ iterator->arg_index++; - if (((iterator->arg_index & 31) == 0)) + + if (0 == (iterator->arg_index % 32)) { /* completed current uint32_t bitmap */ - if (iterator->bitmap_shifter & 1) + if (0 != (iterator->bitmap_shifter & 1)) { - /* b31 was set, there is more */ - /* move to next uint32_t bitmap */ + /* bit 31 was set, there is more; move to next uint32_t bitmap */ iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap); iterator->next_bitmap++; } else { - /* no more bitmaps: end */ + /* no more bitmaps: end (by setting arg_index to high, unsupported value) */ iterator->arg_index = sizeof (rt_sizes); } } else - { /* just try the next bit */ + { + /* just try the next bit (while loop will move on) */ iterator->bitmap_shifter >>= 1; } /* if we found a valid arg earlier, return it now */ - if (hit) return iterator->this_arg_index; - } - /* we don't know how to handle any more args, we're done */ + /* we don't know how to handle any more args (or there are no more), + so we're done (this is not an error) */ return -1; } /** - * Return the channel from the frequency (in Mhz) - * @param frequency of the channel - * @return number of the channel - */ -static int -get_channel_from_frequency (int frequency) -{ - if (frequency >= 2412 && frequency <= 2472) - return (frequency - 2407) / 5; - if (frequency == 2484) - return 14; - if (frequency >= 5000 && frequency <= 6100) - return (frequency - 5000) / 5; - return -1; -} - - -/** - * function to calculate the crc, the start of the calculation + * Calculate crc32, the start of the calculation * * @param buf buffer to calc the crc * @param len len of the buffer @@ -1049,7 +1337,7 @@ calc_crc_osdep (const unsigned char *buf, size_t len) /** - * Function to calculate and check crc of the wlan packet + * Calculate and check crc of the wlan packet * * @param buf buffer of the packet, with len + 4 bytes of data, * the last 4 bytes being the checksum @@ -1070,6 +1358,30 @@ check_crc_buf_osdep (const unsigned char *buf, size_t len) } +/* ************end of code for handling of ARPHRD_IEEE80211_FULL ************** */ + + +/* ************beginning of code for reading packets from kernel ************** */ + +/** + * Return the channel from the frequency (in Mhz) + * + * @param frequency of the channel + * @return number of the channel + */ +static int +get_channel_from_frequency (int32_t frequency) +{ + if (frequency >= 2412 && frequency <= 2472) + return (frequency - 2407) / 5; + if (frequency == 2484) + return 14; + if (frequency >= 5000 && frequency <= 6100) + return (frequency - 5000) / 5; + return -1; +} + + /** * Get the channel used by our WLAN interface. * @@ -1080,46 +1392,46 @@ static int linux_get_channel (const struct HardwareInfos *dev) { struct iwreq wrq; - int fd; - int frequency; - int chan; + int32_t frequency; memset (&wrq, 0, sizeof (struct iwreq)); strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); - fd = dev->fd_raw; - if (0 > ioctl (fd, SIOCGIWFREQ, &wrq)) + if (0 > ioctl (dev->fd_raw, SIOCGIWFREQ, &wrq)) return -1; - - frequency = wrq.u.freq.m; + frequency = wrq.u.freq.m; /* 'iw_freq' defines 'm' as '__s32', so we keep it signed */ if (100000000 < frequency) frequency /= 100000; else if (1000000 < frequency) frequency /= 1000; if (1000 < frequency) - chan = get_channel_from_frequency (frequency); - else - chan = frequency; - return chan; + return get_channel_from_frequency (frequency); + return frequency; } /** - * function to read from a wlan card + * Read from the raw socket (the wlan card), parse the packet and + * put the result into the buffer for transmission to 'stdout'. + * * @param dev pointer to the struct of the wlan card - * @param buf buffer to read to + * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame', + * followed by the actual payload * @param buf_size size of the buffer - * @param ri radiotap_rx info - * @return size read from the buffer + * @param ri where to write radiotap_rx info + * @return number of bytes written to 'buf' */ static ssize_t -linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size, - struct Radiotap_rx *ri) +linux_read (struct HardwareInfos *dev, + unsigned char *buf, size_t buf_size, + struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri) { unsigned char tmpbuf[buf_size]; ssize_t caplen; - int n, got_signal, got_noise, got_channel, fcs_removed; - - n = got_signal = got_noise = got_channel = fcs_removed = 0; + size_t n; + int got_signal = 0; + int got_noise = 0; + int got_channel = 0; + int fcs_removed = 0; caplen = read (dev->fd_raw, tmpbuf, buf_size); if (0 > caplen) @@ -1130,171 +1442,181 @@ linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size, return -1; } - memset (buf, 0, buf_size); - memset (ri, 0, sizeof (*ri)); - + memset (ri, 0, sizeof (*ri)); switch (dev->arptype_in) { case ARPHRD_IEEE80211_PRISM: - { - /* skip the prism header */ - if (tmpbuf[7] == 0x40) { - /* prism54 uses a different format */ - ri->ri_power = tmpbuf[0x33]; - ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); - ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; - got_signal = 1; - got_noise = 1; - n = 0x40; - } - else - { - ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48); - ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); - ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); - ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); - ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; - got_channel = 1; - got_signal = 1; - got_noise = 1; - n = *(int *) (tmpbuf + 4); + const struct PrismHeader *ph; + + ph = (const struct PrismHeader*) tmpbuf; + n = ph->msglen; + if ( (n < 8) || (n >= caplen) ) + return 0; /* invalid format */ + if ( (PRISM_MSGCODE_MONITOR == ph->msgcode) && + (n >= sizeof (struct PrismHeader)) ) + { + const char *pos; + size_t left; + struct PrismValue pv; + + left = n - sizeof (struct PrismHeader); + pos = (const char *) &ph[1]; + while (left > sizeof (struct PrismValue)) + { + left -= sizeof (struct PrismValue); + memcpy (&pv, pos, sizeof (struct PrismValue)); + pos += sizeof (struct PrismValue); + + switch (pv.did) + { + case PRISM_DID_NOISE: + if (PRISM_STATUS_OK == pv.status) + { + ri->ri_noise = pv.data; + got_noise = 1; + } + break; + case PRISM_DID_RATE: + if (PRISM_STATUS_OK == pv.status) + ri->ri_rate = pv.data * 500000; + break; + case PRISM_DID_CHANNEL: + if (PRISM_STATUS_OK == pv.status) + { + ri->ri_channel = pv.data; + got_channel = 1; + } + break; + case PRISM_DID_MACTIME: + if (PRISM_STATUS_OK == pv.status) + ri->ri_mactime = pv.data; + break; + case PRISM_DID_SIGNAL: + if (PRISM_STATUS_OK == pv.status) + { + ri->ri_power = pv.data; + got_signal = 1; + } + break; + } + } + } + if ( (n < 8) || (n >= caplen) ) + return 0; /* invalid format */ } - - if ( (n < 8) || (n >= caplen) ) - return 0; - } break; - case ARPHRD_IEEE80211_FULL: - { - struct ieee80211_radiotap_iterator iterator; - struct ieee80211_radiotap_header *rthdr; - - rthdr = (struct ieee80211_radiotap_header *) tmpbuf; - - if (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen)) - return 0; - - /* go through the radiotap arguments we have been given - * by the driver - */ - - while (ieee80211_radiotap_iterator_next (&iterator) >= 0) { - - switch (iterator.this_arg_index) + struct Ieee80211RadiotapHeaderIterator iterator; + struct Ieee80211RadiotapHeader *rthdr; + + memset (&iterator, 0, sizeof (iterator)); + rthdr = (struct Ieee80211RadiotapHeader *) tmpbuf; + n = GNUNET_le16toh (rthdr->it_len); + if ( (n < sizeof (struct Ieee80211RadiotapHeader)) || (n >= caplen)) + return 0; /* invalid 'it_len' */ + if (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen)) + return 0; + /* go through the radiotap arguments we have been given by the driver */ + while (0 <= ieee80211_radiotap_iterator_next (&iterator)) { - - case IEEE80211_RADIOTAP_TSFT: - ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg)); - break; - - case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: - if (!got_signal) - { - if (*iterator.this_arg < 127) - ri->ri_power = *iterator.this_arg; - else - ri->ri_power = *iterator.this_arg - 255; - - got_signal = 1; - } - break; - - case IEEE80211_RADIOTAP_DB_ANTSIGNAL: - if (!got_signal) - { - if (*iterator.this_arg < 127) - ri->ri_power = *iterator.this_arg; - else - ri->ri_power = *iterator.this_arg - 255; - - got_signal = 1; - } - break; - - case IEEE80211_RADIOTAP_DBM_ANTNOISE: - if (!got_noise) - { - if (*iterator.this_arg < 127) - ri->ri_noise = *iterator.this_arg; - else - ri->ri_noise = *iterator.this_arg - 255; - - got_noise = 1; - } - break; - - case IEEE80211_RADIOTAP_DB_ANTNOISE: - if (!got_noise) - { - if (*iterator.this_arg < 127) - ri->ri_noise = *iterator.this_arg; - else - ri->ri_noise = *iterator.this_arg - 255; - - got_noise = 1; - } - break; - - case IEEE80211_RADIOTAP_ANTENNA: - ri->ri_antenna = *iterator.this_arg; - break; - - case IEEE80211_RADIOTAP_CHANNEL: - ri->ri_channel = *iterator.this_arg; - got_channel = 1; - break; - - case IEEE80211_RADIOTAP_RATE: - ri->ri_rate = (*iterator.this_arg) * 500000; - break; - - case IEEE80211_RADIOTAP_FLAGS: - /* is the CRC visible at the end? - * remove - */ - if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) - { - fcs_removed = 1; - caplen -= 4; - } - - if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) - return (0); - - break; - } - } - n = GNUNET_le16toh (rthdr->it_len); - if (n <= 0 || n >= caplen) - return 0; - } + switch (iterator.this_arg_index) + { + case IEEE80211_RADIOTAP_TSFT: + ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg)); + break; + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: + if (!got_signal) + { + ri->ri_power = * ((int8_t*) iterator.this_arg); + got_signal = 1; + } + break; + case IEEE80211_RADIOTAP_DB_ANTSIGNAL: + if (!got_signal) + { + ri->ri_power = * ((int8_t*) iterator.this_arg); + got_signal = 1; + } + break; + case IEEE80211_RADIOTAP_DBM_ANTNOISE: + if (!got_noise) + { + ri->ri_noise = * ((int8_t*) iterator.this_arg); + got_noise = 1; + } + break; + case IEEE80211_RADIOTAP_DB_ANTNOISE: + if (!got_noise) + { + ri->ri_noise = * ((int8_t*) iterator.this_arg); + got_noise = 1; + } + break; + case IEEE80211_RADIOTAP_ANTENNA: + ri->ri_antenna = *iterator.this_arg; + break; + case IEEE80211_RADIOTAP_CHANNEL: + ri->ri_channel = *iterator.this_arg; + got_channel = 1; + break; + case IEEE80211_RADIOTAP_RATE: + ri->ri_rate = (*iterator.this_arg) * 500000; + break; + case IEEE80211_RADIOTAP_FLAGS: + { + uint8_t flags = *iterator.this_arg; + /* is the CRC visible at the end? if so, remove */ + if (0 != (flags & IEEE80211_RADIOTAP_F_FCS)) + { + fcs_removed = 1; + caplen -= sizeof (uint32_t); + } + break; + } + case IEEE80211_RADIOTAP_RX_FLAGS: + { + uint16_t flags = ntohs (* ((uint16_t *) iterator.this_arg)); + if (0 != (flags & IEEE80211_RADIOTAP_F_RX_BADFCS)) + return 0; + } + break; + } /* end of 'switch' */ + } /* end of the 'while' loop */ + } break; case ARPHRD_IEEE80211: - /* do nothing? */ + n = 0; /* no header */ break; default: - errno = ENOTSUP; + errno = ENOTSUP; /* unsupported format */ return -1; } - caplen -= n; + if (! got_channel) + ri->ri_channel = linux_get_channel (dev); - //detect fcs at the end, even if the flag wasn't set and remove it - if ((0 == fcs_removed) && (0 == check_crc_buf_osdep (tmpbuf + n, caplen - 4))) + /* detect CRC32 at the end, even if the flag wasn't set and remove it */ + if ( (0 == fcs_removed) && + (0 == check_crc_buf_osdep (tmpbuf + n, caplen - sizeof (uint32_t))) ) { - caplen -= 4; + /* NOTE: this heuristic can of course fail if there happens to + be a matching checksum at the end. Would be good to have + some data to see how often this heuristic actually works. */ + caplen -= sizeof (uint32_t); } + /* copy payload to target buffer */ memcpy (buf, tmpbuf + n, caplen); - if (!got_channel) - ri->ri_channel = linux_get_channel (dev); - return caplen; } +/* ************end of code for reading packets from kernel ************** */ + +/* ************other helper functions for main start here ************** */ + + /** * Open the wireless network interface for reading/writing. * @@ -1400,11 +1722,12 @@ open_device_raw (struct HardwareInfos *dev) setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof (mr))) { - fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n", - IFNAMSIZ, dev->iface); + fprintf (stderr, + "Failed to enable promiscuous mode on interface `%.*s'\n", + IFNAMSIZ, + dev->iface); return 1; } - return 0; } @@ -1423,106 +1746,101 @@ test_wlan_interface (const char *iface) struct stat sbuf; int ret; - /* mac80211 stack detection */ - ret = - snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem", - iface); + ret = snprintf (strbuf, sizeof (strbuf), + "/sys/class/net/%s/phy80211/subsystem", + iface); if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf))) { - fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface); - return 1; + fprintf (stderr, + "Did not find 802.11 interface `%s'. Exiting.\n", + iface); + exit (1); } return 0; } /** - * Function to test incoming packets mac for being our own. + * Test incoming packets mac for being our own. * - * @param uint8_taIeeeHeader buffer of the packet + * @param taIeeeHeader buffer of the packet * @param dev the Hardware_Infos struct * @return 0 if mac belongs to us, 1 if mac is for another target */ static int -mac_test (const struct ieee80211_frame *uint8_taIeeeHeader, +mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev) { - if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE)) - return 1; - if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE)) - return 0; - if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE)) - return 0; - return 1; + if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE)) + return 1; /* not a GNUnet ad-hoc package */ + if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) || + (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) ) + return 0; /* for us, or broadcast */ + return 1; /* not for us */ } /** - * function to set the wlan header to make attacks more difficult - * @param uint8_taIeeeHeader pointer to the header of the packet + * Set the wlan header to sane values to make attacks more difficult + * + * @param taIeeeHeader pointer to the header of the packet * @param dev pointer to the Hardware_Infos struct */ static void -mac_set (struct ieee80211_frame *uint8_taIeeeHeader, +mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev) { - uint8_taIeeeHeader->i_fc[0] = 0x08; - uint8_taIeeeHeader->i_fc[1] = 0x00; - memcpy (uint8_taIeeeHeader->i_addr2, &dev->pl_mac, MAC_ADDR_SIZE); - memcpy (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE); + taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA); + taIeeeHeader->addr2 = dev->pl_mac; + taIeeeHeader->addr3 = mac_bssid_gnunet; } /** - * function to process the data from the stdin - * @param cls pointer to the device struct + * Process data from the stdin. Takes the message, prepends the + * radiotap transmission header, forces the sender MAC to be correct + * and puts it into our buffer for transmission to the kernel. + * + * @param cls pointer to the device struct ('struct HardwareInfos*') * @param hdr pointer to the start of the packet */ static void stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) { struct HardwareInfos *dev = cls; - struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1]; - struct ieee80211_frame *wlanheader; + const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header; + struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader; size_t sendsize; - struct RadioTapheader rtheader; - - rtheader.header.it_version = 0; /* radiotap version */ - rtheader.header.it_len = GNUNET_htole16 (0x0c); /* radiotap header length */ - rtheader.header.it_present = GNUNET_le16toh (0x00008004); /* our bitmap */ - rtheader.rate = 0x00; - rtheader.pad1 = 0x00; - rtheader.txflags = - GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ); + struct RadiotapTransmissionHeader rtheader; sendsize = ntohs (hdr->size); - if (sendsize < - sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader)) + if ( (sendsize < + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) || + (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) { - fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n"); + fprintf (stderr, "Received malformed message\n"); exit (1); } - sendsize -= - sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader); - + sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)); if (MAXLINE < sendsize) { - fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n"); - exit (1); - } - if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) - { - fprintf (stderr, "Function stdin_send_hw: wrong packet type\n"); + fprintf (stderr, "Packet too big for buffer\n"); exit (1); } - + header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr; + rtheader.header.it_version = 0; + rtheader.header.it_pad = 0; rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader)); - rtheader.rate = header->rate; + rtheader.header.it_present = GNUNET_htole16 (IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK); + rtheader.rate = header->rate; + rtheader.pad1 = 0; + rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ); memcpy (write_pout.buf, &rtheader, sizeof (rtheader)); - memcpy (write_pout.buf + sizeof (rtheader), &header[1], sendsize); + memcpy (&write_pout.buf[sizeof (rtheader)], &header->frame, sendsize); + wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof (rtheader)]; + /* payload contains MAC address, but we don't trust it, so we'll - * overwrite it with OUR MAC address again to prevent mischief */ - wlanheader = (struct ieee80211_frame *) (write_pout.buf + sizeof (rtheader)); + * overwrite it with OUR MAC address to prevent mischief */ mac_set (wlanheader, dev); write_pout.size = sendsize + sizeof (rtheader); } @@ -1721,33 +2039,30 @@ main (int argc, char *argv[]) if (FD_ISSET (dev.fd_raw, &rfds)) { - struct GNUNET_MessageHeader *header; - struct Radiotap_rx *rxinfo; - struct ieee80211_frame *datastart; + struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm; ssize_t ret; - header = (struct GNUNET_MessageHeader *) write_std.buf; - rxinfo = (struct Radiotap_rx *) &header[1]; - datastart = (struct ieee80211_frame *) &rxinfo[1]; + rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf; ret = - linux_read (&dev, (unsigned char *) datastart, - sizeof (write_std.buf) - sizeof (struct Radiotap_rx) - - sizeof (struct GNUNET_MessageHeader), rxinfo); + linux_read (&dev, (unsigned char *) &rrm->frame, + sizeof (write_std.buf) + - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) + + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), + rrm); if (0 > ret) { fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno)); break; } - if ((0 < ret) && (0 == mac_test (datastart, &dev))) + if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev))) { - write_std.size = - ret + sizeof (struct GNUNET_MessageHeader) + - sizeof (struct Radiotap_rx); - header->size = htons (write_std.size); - header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); + write_std.size = ret + + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) + - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame); + rrm->header.size = htons (write_std.size); + rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER); } } - } /* Error handling, try to clean up a bit at least */ mst_destroy (stdin_mst); diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index cd9bb5c..c200cb5 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -76,6 +76,11 @@ struct GNUNET_CRYPTO_RsaPrivateKey *GST_my_private_key; */ struct GNUNET_ATS_SchedulingHandle *GST_ats; +/** + * DEBUGGING connection counter + */ +static int connections; + /** * Transmit our HELLO message to the given (connected) neighbour. @@ -139,7 +144,7 @@ process_payload (const struct GNUNET_PeerIdentity *peer, size_t size = sizeof (struct InboundMessage) + msg_size + sizeof (struct GNUNET_ATS_Information) * (ats_count + 1); - char buf[size]; + char buf[size] GNUNET_ALIGN; struct GNUNET_ATS_Information *ap; ret = GNUNET_TIME_UNIT_ZERO; @@ -225,10 +230,12 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, if (NULL == message) goto end; type = ntohs (message->type); -#if DEBUG_TRANSPORT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Message with type %u from peer `%s'\n", type, GNUNET_i2s (peer)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Message with type %u\n", type); -#endif + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# bytes total received"), + ntohs (message->size), GNUNET_NO); switch (type) { @@ -236,21 +243,17 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, GST_validation_handle_hello (message); return ret; case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Processing `%s' from `%s'\n", "PING", (sender_address != NULL) ? GST_plugins_a2s (&address) : ""); -#endif GST_validation_handle_ping (peer, message, &address, session); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Processing `%s' from `%s'\n", "PONG", (sender_address != NULL) ? GST_plugins_a2s (&address) : ""); -#endif GST_validation_handle_pong (peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT: @@ -262,8 +265,8 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK: - GST_neighbours_handle_ack (message, peer, &address, session, ats, - ats_count); + GST_neighbours_handle_session_ack (message, peer, &address, session, ats, + ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: GST_neighbours_handle_disconnect_message (peer, message); @@ -276,6 +279,10 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, break; default: /* should be payload */ + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# bytes payload received"), + ntohs (message->size), GNUNET_NO); ret = process_payload (peer, &address, session, message, ats, ats_count); break; } @@ -285,11 +292,9 @@ end: * this connections seem to go extra-slow */ GNUNET_ATS_address_update (GST_ats, &address, session, ats, ats_count); #endif -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Allowing receive from peer %s to continue in %llu ms\n", GNUNET_i2s (peer), (unsigned long long) ret.rel_value); -#endif return ret; } @@ -341,12 +346,10 @@ plugin_env_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_HELLO_Address address; GNUNET_assert (strlen (transport_name) > 0); -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %X to peer `%s' ended \n", session, GNUNET_i2s (peer)); -#endif if (NULL != session) - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "transport-ats", "Telling ATS to destroy session %p from peer %s\n", session, GNUNET_i2s (peer)); @@ -368,7 +371,7 @@ plugin_env_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, * @param addrlen length of the address * @return ATS Information containing the network type */ -static const struct GNUNET_ATS_Information +static struct GNUNET_ATS_Information plugin_env_address_to_type (void *cls, const struct sockaddr *addr, size_t addrlen) @@ -425,15 +428,12 @@ ats_request_address_change (void *cls, /* ATS tells me to disconnect from peer */ if ((bw_in == 0) && (bw_out == 0)) { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS tells me to disconnect from peer `%s'\n", GNUNET_i2s (&address->peer)); -#endif GST_neighbours_force_disconnect (&address->peer); return; } - /* will never return GNUNET_YES since connection is to be established */ GST_neighbours_switch_to_address (&address->peer, address, session, ats, ats_count, bandwidth_in, bandwidth_out); @@ -458,10 +458,15 @@ neighbours_connect_notification (void *cls, size_t len = sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_ATS_Information); - char buf[len]; + char buf[len] GNUNET_ALIGN; struct ConnectInfoMessage *connect_msg = (struct ConnectInfoMessage *) buf; struct GNUNET_ATS_Information *ap; + connections++; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "We are now connected to peer `%s' and %u peers in total\n", + GNUNET_i2s (peer), connections); + connect_msg->header.size = htons (sizeof (buf)); connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); connect_msg->ats_count = htonl (ats_count); @@ -485,6 +490,11 @@ neighbours_disconnect_notification (void *cls, { struct DisconnectInfoMessage disconnect_msg; + connections--; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Peer `%s' disconnected and we are connected to %u peers\n", + GNUNET_i2s (peer), connections); + disconnect_msg.header.size = htons (sizeof (struct DisconnectInfoMessage)); disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); disconnect_msg.reserved = htonl (0); @@ -560,7 +570,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c) { char *keyfile; - + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded tmp; /* setup globals */ GST_cfg = c; if (GNUNET_OK != @@ -584,9 +594,15 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, } GST_stats = GNUNET_STATISTICS_create ("transport", c); GST_peerinfo = GNUNET_PEERINFO_connect (c); + memset (&GST_my_public_key, '\0', sizeof (GST_my_public_key)); + memset (&tmp, '\0', sizeof (tmp)); GNUNET_CRYPTO_rsa_key_get_public (GST_my_private_key, &GST_my_public_key); GNUNET_CRYPTO_hash (&GST_my_public_key, sizeof (GST_my_public_key), &GST_my_identity.hashPubKey); + + GNUNET_assert (NULL != GST_my_private_key); + GNUNET_assert (0 != memcmp (&GST_my_public_key, &tmp, sizeof (GST_my_public_key))); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); if (GST_peerinfo == NULL) @@ -599,6 +615,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, /* start subsystems */ GST_hello_start (&process_hello_update, NULL); + GNUNET_assert (NULL != GST_hello_get()); GST_blacklist_start (server); GST_ats = GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL); @@ -630,4 +647,4 @@ main (int argc, char *const *argv) GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; } -/* end of file gnunet-service-transport-new.c */ +/* end of file gnunet-service-transport.c */ diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c index 2089949..8c36888 100644 --- a/src/transport/gnunet-service-transport_blacklist.c +++ b/src/transport/gnunet-service-transport_blacklist.c @@ -113,7 +113,7 @@ struct GST_BlacklistCheck * Current transmission request handle for this client, or NULL if no * request is pending. */ - struct GNUNET_CONNECTION_TransmitHandle *th; + struct GNUNET_SERVER_TransmitHandle *th; /** * Our current position in the blacklisters list. @@ -191,7 +191,7 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) bc->bl_pos = bl->next; if (bc->th != NULL) { - GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); + GNUNET_SERVER_notify_transmit_ready_cancel (bc->th); bc->th = NULL; } if (bc->task == GNUNET_SCHEDULER_NO_TASK) @@ -221,7 +221,7 @@ read_blacklist_file () size_t colon_pos; int tsize; struct GNUNET_PeerIdentity pid; - struct stat frstat; + uint64_t fsize; struct GNUNET_CRYPTO_HashAsciiEncoded enc; unsigned int entries_found; char *transport_name; @@ -230,37 +230,34 @@ read_blacklist_file () GNUNET_CONFIGURATION_get_value_filename (GST_cfg, "TRANSPORT", "BLACKLIST_FILE", &fn)) { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Option `%s' in section `%s' not specified!\n", "BLACKLIST_FILE", "TRANSPORT"); -#endif return; } if (GNUNET_OK != GNUNET_DISK_file_test (fn)) GNUNET_DISK_fn_write (fn, NULL, 0, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); - if (0 != STAT (fn, &frstat)) + if (GNUNET_OK != GNUNET_DISK_file_size (fn, + &fsize, GNUNET_NO, GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not read blacklist file `%s'\n"), fn); GNUNET_free (fn); return; } - if (frstat.st_size == 0) + if (fsize == 0) { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Blacklist file `%s' is empty.\n"), fn); -#endif GNUNET_free (fn); return; } /* FIXME: use mmap */ - data = GNUNET_malloc_large (frstat.st_size); + data = GNUNET_malloc_large (fsize); GNUNET_assert (data != NULL); - if (frstat.st_size != GNUNET_DISK_fn_read (fn, data, frstat.st_size)) + if (fsize != GNUNET_DISK_fn_read (fn, data, fsize)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read blacklist from `%s'\n"), fn); @@ -270,17 +267,17 @@ read_blacklist_file () } entries_found = 0; pos = 0; - while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) + while ((pos < fsize) && isspace ((unsigned char) data[pos])) pos++; - while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && + while ((fsize >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && (pos <= - frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) + fsize - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) { colon_pos = pos; - while ((colon_pos < frstat.st_size) && (data[colon_pos] != ':') && + while ((colon_pos < fsize) && (data[colon_pos] != ':') && (!isspace ((unsigned char) data[colon_pos]))) colon_pos++; - if (colon_pos >= frstat.st_size) + if (colon_pos >= fsize) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ @@ -298,12 +295,12 @@ read_blacklist_file () ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), (unsigned long long) colon_pos); pos = colon_pos; - while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) + while ((pos < fsize) && isspace ((unsigned char) data[pos])) pos++; continue; } tsize = colon_pos - pos; - if ((pos >= frstat.st_size) || (pos + tsize >= frstat.st_size) || + if ((pos >= fsize) || (pos + tsize >= fsize) || (tsize == 0)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -321,11 +318,9 @@ read_blacklist_file () transport_name = GNUNET_malloc (tsize + 1); memcpy (transport_name, &data[pos], tsize); pos = colon_pos + 1; -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read transport name `%s' in blacklist file.\n", transport_name); -#endif memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); if (!isspace ((unsigned char) @@ -336,7 +331,7 @@ read_blacklist_file () ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), (unsigned long long) pos); pos++; - while ((pos < frstat.st_size) && (!isspace ((unsigned char) data[pos]))) + while ((pos < fsize) && (!isspace ((unsigned char) data[pos]))) pos++; GNUNET_free_non_null (transport_name); continue; @@ -367,7 +362,7 @@ read_blacklist_file () } pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded); GNUNET_free_non_null (transport_name); - while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) + while ((pos < fsize) && isspace ((unsigned char) data[pos])) pos++; } GNUNET_STATISTICS_update (GST_stats, "# Transport entries blacklisted", @@ -450,11 +445,9 @@ transmit_blacklist_message (void *cls, size_t size, void *buf) GNUNET_i2s (&bc->peer)); return 0; } -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending blacklist test for peer `%s' to client\n", GNUNET_i2s (&bc->peer)); -#endif bl = bc->bl_pos; bm.header.size = htons (sizeof (struct BlacklistMessage)); bm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY); @@ -483,11 +476,9 @@ do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) bl = bc->bl_pos; if (bl == NULL) { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No other blacklist clients active, will allow neighbour `%s'\n", GNUNET_i2s (&bc->peer)); -#endif bc->cont (bc->cont_cls, &bc->peer, GNUNET_OK); GNUNET_CONTAINER_DLL_remove(bc_head, bc_tail, bc); GNUNET_free (bc); @@ -578,7 +569,6 @@ test_connection_ok (void *cls, const struct GNUNET_PeerIdentity *neighbour, } - /** * Initialize a blacklisting client. We got a blacklist-init * message from this client, add him to the list of clients @@ -606,6 +596,7 @@ GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client, } bl = bl->next; } + GNUNET_SERVER_client_mark_monitor (client); bl = GNUNET_malloc (sizeof (struct Blacklisters)); bl->client = client; GNUNET_SERVER_client_keep (client); @@ -639,9 +630,7 @@ GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client, bl = bl->next; if (bl == NULL) { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist client disconnected\n"); -#endif /* FIXME: other error handling here!? */ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; @@ -655,20 +644,16 @@ GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client, * cancelled in the meantime... */ if (ntohl (msg->is_allowed) == GNUNET_SYSERR) { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist check failed, peer not allowed\n"); -#endif bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO); GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); GNUNET_free (bc); } else { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist check succeeded, continuing with checks\n"); -#endif bc->bl_pos = bc->bl_pos->next; bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); } @@ -694,11 +679,9 @@ void GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, const char *transport_name) { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding peer `%s' with plugin `%s' to blacklist\n", GNUNET_i2s (peer), transport_name); -#endif if (blacklist == NULL) blacklist = GNUNET_CONTAINER_multihashmap_create (TRANSPORT_BLACKLIST_HT_SIZE); @@ -812,7 +795,7 @@ GST_blacklist_test_cancel (struct GST_BlacklistCheck *bc) } if (NULL != bc->th) { - GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); + GNUNET_SERVER_notify_transmit_ready_cancel (bc->th); bc->th = NULL; } GNUNET_free (bc); diff --git a/src/transport/gnunet-service-transport_blacklist.h b/src/transport/gnunet-service-transport_blacklist.h index 68da7e4..b8335ab 100644 --- a/src/transport/gnunet-service-transport_blacklist.h +++ b/src/transport/gnunet-service-transport_blacklist.h @@ -58,6 +58,7 @@ void GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message); + /** * A blacklisting client has sent us reply. Process it. * @@ -69,6 +70,7 @@ void GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message); + /** * Add the given peer to the blacklist (for the given transport). * diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c index d6ff554..b298195 100644 --- a/src/transport/gnunet-service-transport_clients.c +++ b/src/transport/gnunet-service-transport_clients.c @@ -102,7 +102,7 @@ struct TransportClient /** * Current transmit request handle. */ - struct GNUNET_CONNECTION_TransmitHandle *th; + struct GNUNET_SERVER_TransmitHandle *th; /** * Length of the list of messages pending for this client. @@ -208,10 +208,7 @@ setup_client (struct GNUNET_SERVER_Client *client) GNUNET_assert (lookup_client (client) == NULL); tc = GNUNET_malloc (sizeof (struct TransportClient)); tc->client = client; - -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", tc); -#endif return tc; } @@ -293,10 +290,8 @@ transmit_to_client_callback (void *cls, size_t size, void *buf) tc->th = NULL; if (buf == NULL) { -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission to client failed, closing connection.\n"); -#endif return 0; } cbuf = buf; @@ -307,11 +302,9 @@ transmit_to_client_callback (void *cls, size_t size, void *buf) msize = ntohs (msg->size); if (msize + tsize > size) break; -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting message of type %u to client %p.\n", ntohs (msg->type), tc); -#endif GNUNET_CONTAINER_DLL_remove (tc->message_queue_head, tc->message_queue_tail, q); tc->message_count--; @@ -346,6 +339,12 @@ unicast (struct TransportClient *tc, const struct GNUNET_MessageHeader *msg, struct ClientMessageQueueEntry *q; uint16_t msize; + if (msg == NULL) + { + GNUNET_break (0); + return; + } + if ((tc->message_count >= MAX_PENDING) && (GNUNET_YES == may_drop)) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -403,10 +402,8 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) tc = lookup_client (client); if (tc == NULL) return; -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Client %p disconnected, cleaning up.\n", tc); -#endif while (NULL != (mqe = tc->message_queue_head)) { GNUNET_CONTAINER_DLL_remove (tc->message_queue_head, tc->message_queue_tail, @@ -417,7 +414,7 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, tc); if (tc->th != NULL) { - GNUNET_CONNECTION_notify_transmit_ready_cancel (tc->th); + GNUNET_SERVER_notify_transmit_ready_cancel (tc->th); tc->th = NULL; } GNUNET_break (0 == tc->message_count); @@ -448,7 +445,7 @@ notify_client_about_neighbour (void *cls, size_t size = sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_ATS_Information); - char buf[size]; + char buf[size] GNUNET_ALIGN; GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); cim = (struct ConnectInfoMessage *) buf; @@ -481,18 +478,14 @@ clients_handle_start (void *cls, struct GNUNET_SERVER_Client *client, tc = lookup_client (client); -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Client %p sent START\n", tc); -#endif if (tc != NULL) { /* got 'start' twice from the same client, not allowed */ -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "TransportClient %p ServerClient %p sent multiple START messages\n", tc, tc->client); -#endif GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; @@ -623,23 +616,16 @@ clients_handle_send (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# bytes payload received for other peers"), msize, - GNUNET_NO); -#if DEBUG_TRANSPORT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' request from client with target `%4s' and first message of type %u and total size %u\n", "SEND", GNUNET_i2s (&obm->peer), ntohs (obmm->type), msize); -#endif if (GNUNET_NO == GST_neighbours_test_connected (&obm->peer)) { /* not connected, not allowed to send; can happen due to asynchronous operations */ -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Could not send message to peer `%s': not connected\n", GNUNET_i2s (&obm->peer)); -#endif GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# bytes payload dropped (other peer was not connected)"), @@ -695,11 +681,9 @@ clients_handle_request_connect (void *cls, struct GNUNET_SERVER_Client *client, gettext_noop ("# REQUEST CONNECT messages received"), 1, GNUNET_NO); -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a request connect message for peer `%s'\n", GNUNET_i2s (&trcm->peer)); -#endif (void) GST_blacklist_test_allowed (&trcm->peer, NULL, &try_connect_if_allowed, NULL); GNUNET_SERVER_receive_done (client, GNUNET_OK); diff --git a/src/transport/gnunet-service-transport_hello.c b/src/transport/gnunet-service-transport_hello.c index 120f176..870c083 100644 --- a/src/transport/gnunet-service-transport_hello.c +++ b/src/transport/gnunet-service-transport_hello.c @@ -162,18 +162,18 @@ refresh_hello_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) gc.expiration = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION); + GNUNET_free (our_hello); our_hello = GNUNET_HELLO_create (&GST_my_public_key, &address_generator, &gc); -#if DEBUG_TRANSPORT + GNUNET_assert (NULL != our_hello); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Refreshed my `%s', new size is %d\n", "HELLO", GNUNET_HELLO_size (our_hello)); -#endif GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# refreshed my HELLO"), 1, GNUNET_NO); if (NULL != hello_cb) hello_cb (hello_cb_cls, GST_hello_get ()); - GNUNET_PEERINFO_add_peer (GST_peerinfo, our_hello); + GNUNET_PEERINFO_add_peer (GST_peerinfo, our_hello, NULL, NULL); hello_task = GNUNET_SCHEDULER_add_delayed (HELLO_REFRESH_PERIOD, &refresh_hello_task, NULL); @@ -206,6 +206,7 @@ GST_hello_start (GST_HelloCallback cb, void *cb_cls) hello_cb = cb; hello_cb_cls = cb_cls; our_hello = GNUNET_HELLO_create (&GST_my_public_key, NULL, NULL); + GNUNET_assert (NULL != our_hello); refresh_hello (); } @@ -255,13 +256,11 @@ GST_hello_modify_addresses (int addremove, { struct OwnAddressList *al; -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - (add_remove == - GNUNET_YES) ? "Adding `%s':%s to the set of our addresses\n" : - "Removing `%s':%s from the set of our addresses\n", - GST_plugins_a2s (address), p->short_name); -#endif + (addremove == + GNUNET_YES) ? "Adding `%s' to the set of our addresses\n" : + "Removing `%s' from the set of our addresses\n", + GST_plugins_a2s (address)); GNUNET_assert (address != NULL); if (GNUNET_NO == addremove) { diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 3e8ef5a..c580168 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010,2011 Christian Grothoff (and other contributing authors) + (C) 2010,2011,2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -22,6 +22,10 @@ * @file transport/gnunet-service-transport_neighbours.c * @brief neighbour management * @author Christian Grothoff + * + * TODO: + * - "address_change_cb" is NEVER invoked; when should we call this one exactly? + * - TEST, TEST, TEST... */ #include "platform.h" #include "gnunet_ats_service.h" @@ -41,6 +45,12 @@ */ #define NEIGHBOUR_TABLE_SIZE 256 +/** + * Time we give plugin to transmit DISCONNECT message before the + * neighbour entry self-destructs. + */ +#define DISCONNECT_SENT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100) + /** * How often must a peer violate bandwidth quotas before we start * to simply drop its messages? @@ -50,38 +60,53 @@ /** * How often do we send KEEPALIVE messages to each of our neighbours and measure * the latency with this neighbour? - * (idle timeout is 5 minutes or 300 seconds, so with 30s interval we - * send 10 keepalives in each interval, so 10 messages would need to be + * (idle timeout is 5 minutes or 300 seconds, so with 100s interval we + * send 3 keepalives in each interval, so 3 messages would need to be * lost in a row for a disconnect). */ -#define KEEPALIVE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) +#define KEEPALIVE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100) +/** + * How long are we willing to wait for a response from ATS before timing out? + */ +#define ATS_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500) -#define ATS_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) - -#define FAST_RECONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) - +/** + * How long are we willing to wait for an ACK from the other peer before + * giving up on our connect operation? + */ #define SETUP_CONNECTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) -#define TEST_NEW_CODE GNUNET_NO +/** + * How long are we willing to wait for a successful reconnect if + * an existing connection went down? Much shorter than the + * usual SETUP_CONNECTION_TIMEOUT as we do not inform the + * higher layers about the disconnect during this period. + */ +#define FAST_RECONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) /** - * Entry in neighbours. + * How long are we willing to wait for a response from the blacklist + * subsystem before timing out? */ -struct NeighbourMapEntry; +#define BLACKLIST_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500) + GNUNET_NETWORK_STRUCT_BEGIN /** - * Message a peer sends to another to indicate its - * preference for communicating via a particular - * session (and the desire to establish a real - * connection). + * Message a peer sends to another to indicate that it intends to + * setup a connection/session for data exchange. A 'SESSION_CONNECT' + * should be answered with a 'SESSION_CONNECT_ACK' with the same body + * to confirm. A 'SESSION_CONNECT_ACK' should then be followed with + * a 'SESSION_ACK'. Once the 'SESSION_ACK' is received, both peers + * should be connected. */ struct SessionConnectMessage { /** * Header of type 'GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT' + * or 'GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT_ACK' */ struct GNUNET_MessageHeader header; @@ -99,6 +124,12 @@ struct SessionConnectMessage }; +/** + * Message we send to the other peer to notify him that we intentionally + * are disconnecting (to reduce timeouts). This is just a friendly + * notification, peers must not rely on always receiving disconnect + * messages. + */ struct SessionDisconnectMessage { /** @@ -136,8 +167,10 @@ struct SessionDisconnectMessage struct GNUNET_CRYPTO_RsaSignature signature; }; + GNUNET_NETWORK_STRUCT_END + /** * For each neighbour we keep a list of messages * that we still want to transmit to the neighbour. @@ -155,12 +188,6 @@ struct MessageQueue */ struct MessageQueue *prev; - /** - * Once this message is actively being transmitted, which - * neighbour is it associated with? - */ - struct NeighbourMapEntry *n; - /** * Function to call once we're done. */ @@ -190,44 +217,196 @@ struct MessageQueue }; +/** + * Possible state of a neighbour. Initially, we are S_NOT_CONNECTED. + * + * Then, there are two main paths. If we receive a CONNECT message, we + * first run a check against the blacklist and ask ATS for a + * suggestion. (S_CONNECT_RECV_ATS). If the blacklist comes back + * positive, we give the address to ATS. If ATS makes a suggestion, + * we ALSO give that suggestion to the blacklist + * (S_CONNECT_RECV_BLACKLIST). Once the blacklist approves the + * address we got from ATS, we send our CONNECT_ACK and go to + * S_CONNECT_RECV_ACK. If we receive a SESSION_ACK, we go to + * S_CONNECTED (and notify everyone about the new connection). If the + * operation times out, we go to S_DISCONNECT. + * + * The other case is where we transmit a CONNECT message first. We + * start with S_INIT_ATS. If we get an address, we enter + * S_INIT_BLACKLIST and check the blacklist. If the blacklist is OK + * with the connection, we actually send the CONNECT message and go to + * state S_CONNECT_SENT. Once we receive a CONNECT_ACK, we go to + * S_CONNECTED (and notify everyone about the new connection and send + * back a SESSION_ACK). If the operation times out, we go to + * S_DISCONNECT. + * + * If the session is in trouble (i.e. transport-level disconnect or + * timeout), we go to S_RECONNECT_ATS where we ask ATS for a new + * address (we don't notify anyone about the disconnect yet). Once we + * have a new address, we go to S_RECONNECT_BLACKLIST to check the new + * address against the blacklist. If the blacklist approves, we enter + * S_RECONNECT_SENT and send a CONNECT message. If we receive a + * CONNECT_ACK, we go to S_CONNECTED and nobody noticed that we had + * trouble; we also send a SESSION_ACK at this time just in case. If + * the operation times out, we go to S_DISCONNECT (and notify everyone + * about the lost connection). + * + * If ATS decides to switch addresses while we have a normal + * connection, we go to S_CONNECTED_SWITCHING_BLACKLIST to check the + * new address against the blacklist. If the blacklist approves, we + * go to S_CONNECTED_SWITCHING_CONNECT_SENT and send a + * SESSION_CONNECT. If we get a SESSION_ACK back, we switch the + * primary connection to the suggested alternative from ATS, go back + * to S_CONNECTED and send a SESSION_ACK to the other peer just to be + * sure. If the operation times out (or the blacklist disapproves), + * we go to S_CONNECTED (and notify ATS that the given alternative + * address is "invalid"). + * + * Once a session is in S_DISCONNECT, it is cleaned up and then goes + * to (S_DISCONNECT_FINISHED). If we receive an explicit disconnect + * request, we can go from any state to S_DISCONNECT, possibly after + * generating disconnect notifications. + * + * Note that it is quite possible that while we are in any of these + * states, we could receive a 'CONNECT' request from the other peer. + * We then enter a 'weird' state where we pursue our own primary state + * machine (as described above), but with the 'send_connect_ack' flag + * set to 1. If our state machine allows us to send a 'CONNECT_ACK' + * (because we have an acceptable address), we send the 'CONNECT_ACK' + * and set the 'send_connect_ack' to 2. If we then receive a + * 'SESSION_ACK', we go to 'S_CONNECTED' (and reset 'send_connect_ack' + * to 0). + * + */ enum State { /** * fresh peer or completely disconnected */ - S_NOT_CONNECTED, + S_NOT_CONNECTED = 0, + + /** + * Asked to initiate connection, trying to get address from ATS + */ + S_INIT_ATS, + + /** + * Asked to initiate connection, trying to get address approved + * by blacklist. + */ + S_INIT_BLACKLIST, /** - * sent CONNECT message to other peer, waiting for CONNECT_ACK + * Sent CONNECT message to other peer, waiting for CONNECT_ACK */ S_CONNECT_SENT, /** - * received CONNECT message to other peer, sending CONNECT_ACK + * Received a CONNECT, asking ATS about address suggestions. + */ + S_CONNECT_RECV_ATS, + + /** + * Received CONNECT from other peer, got an address, checking with blacklist. */ - S_CONNECT_RECV, + S_CONNECT_RECV_BLACKLIST, /** - * received ACK or payload + * CONNECT request from other peer was SESSION_ACK'ed, waiting for + * SESSION_ACK. + */ + S_CONNECT_RECV_ACK, + + /** + * Got our CONNECT_ACK/SESSION_ACK, connection is up. */ S_CONNECTED, /** - * connection ended, fast reconnect + * Connection got into trouble, rest of the system still believes + * it to be up, but we're getting a new address from ATS. + */ + S_RECONNECT_ATS, + + /** + * Connection got into trouble, rest of the system still believes + * it to be up; we are checking the new address against the blacklist. + */ + S_RECONNECT_BLACKLIST, + + /** + * Sent CONNECT over new address (either by ATS telling us to switch + * addresses or from RECONNECT_ATS); if this fails, we need to tell + * the rest of the system about a disconnect. + */ + S_RECONNECT_SENT, + + /** + * We have some primary connection, but ATS suggested we switch + * to some alternative; we're now checking the alternative against + * the blacklist. + */ + S_CONNECTED_SWITCHING_BLACKLIST, + + /** + * We have some primary connection, but ATS suggested we switch + * to some alternative; we now sent a CONNECT message for the + * alternative session to the other peer and waiting for a + * CONNECT_ACK to make this our primary connection. + */ + S_CONNECTED_SWITCHING_CONNECT_SENT, + + /** + * Disconnect in progress (we're sending the DISCONNECT message to the + * other peer; after that is finished, the state will be cleaned up). */ - S_FAST_RECONNECT, + S_DISCONNECT, /** - * Disconnect in progress + * We're finished with the disconnect; clean up state now! */ - S_DISCONNECT + S_DISCONNECT_FINISHED }; -enum Address_State + +/** + * A possible address we could use to communicate with a neighbour. + */ +struct NeighbourAddress { - USED, - UNUSED, - FRESH, + + /** + * Active session for this address. + */ + struct Session *session; + + /** + * Network-level address information. + */ + struct GNUNET_HELLO_Address *address; + + /** + * Timestamp of the 'SESSION_CONNECT' message we sent to the other + * peer for this address. Use to check that the ACK is in response + * to our most recent 'CONNECT'. + */ + struct GNUNET_TIME_Absolute connect_timestamp; + + /** + * Inbound bandwidth from ATS for this address. + */ + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; + + /** + * Outbound bandwidth from ATS for this address. + */ + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out; + + /** + * Did we tell ATS that this is our 'active' address? + */ + int ats_active; + }; @@ -255,14 +434,15 @@ struct NeighbourMapEntry struct MessageQueue *is_active; /** - * Active session for communicating with the peer. + * Primary address we currently use to communicate with the neighbour. */ - struct Session *session; + struct NeighbourAddress primary_address; /** - * Address we currently use. + * Alternative address currently under consideration for communicating + * with the neighbour. */ - struct GNUNET_HELLO_Address *address; + struct NeighbourAddress alternative_address; /** * Identity of this neighbour. @@ -270,92 +450,132 @@ struct NeighbourMapEntry struct GNUNET_PeerIdentity id; /** - * ID of task scheduled to run when this peer is about to - * time out (will free resources associated with the peer). + * Main task that drives this peer (timeouts, keepalives, etc.). + * Always runs the 'master_task'. */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; + GNUNET_SCHEDULER_TaskIdentifier task; /** - * ID of task scheduled to send keepalives. + * At what time should we sent the next keep-alive message? */ - GNUNET_SCHEDULER_TaskIdentifier keepalive_task; + struct GNUNET_TIME_Absolute keep_alive_time; /** - * ID of task scheduled to run when we should try transmitting - * the head of the message queue. + * At what time did we sent the last keep-alive message? Used + * to calculate round-trip time ("latency"). */ - GNUNET_SCHEDULER_TaskIdentifier transmission_task; + struct GNUNET_TIME_Absolute last_keep_alive_time; /** - * Tracker for inbound bandwidth. + * Timestamp we should include in our next CONNECT_ACK message. + * (only valid if 'send_connect_ack' is GNUNET_YES). Used to build + * our CONNECT_ACK message. */ - struct GNUNET_BANDWIDTH_Tracker in_tracker; + struct GNUNET_TIME_Absolute connect_ack_timestamp; /** - * Inbound bandwidth from ATS, activated when connection is up + * Time where we should cut the connection (timeout) if we don't + * make progress in the state machine (or get a KEEPALIVE_RESPONSE + * if we are in S_CONNECTED). */ - struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; + struct GNUNET_TIME_Absolute timeout; /** - * Inbound bandwidth from ATS, activated when connection is up + * Latest calculated latency value */ - struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out; + struct GNUNET_TIME_Relative latency; /** - * Timestamp of the 'SESSION_CONNECT' message we got from the other peer + * Tracker for inbound bandwidth. */ - struct GNUNET_TIME_Absolute connect_ts; + struct GNUNET_BANDWIDTH_Tracker in_tracker; /** - * When did we sent the last keep-alive message? + * How often has the other peer (recently) violated the inbound + * traffic limit? Incremented by 10 per violation, decremented by 1 + * per non-violation (for each time interval). */ - struct GNUNET_TIME_Absolute keep_alive_sent; + unsigned int quota_violation_count; /** - * Latest calculated latency value + * The current state of the peer. */ - struct GNUNET_TIME_Relative latency; + enum State state; /** - * Timeout for ATS - * We asked ATS for a new address for this peer + * Did we sent an KEEP_ALIVE message and are we expecting a response? */ - GNUNET_SCHEDULER_TaskIdentifier ats_suggest; + int expect_latency_response; /** - * Task the resets the peer state after due to an pending - * unsuccessful connection setup + * Flag to set if we still need to send a CONNECT_ACK message to the other peer + * (once we have an address to use and the peer has been allowed by our + * blacklist). Set to 1 if we need to send a CONNECT_ACK. Set to 2 if we + * did send a CONNECT_ACK and should go to 'S_CONNECTED' upon receiving + * a 'SESSION_ACK' (regardless of what our own state machine might say). */ - GNUNET_SCHEDULER_TaskIdentifier state_reset; + int send_connect_ack; + +}; +/** + * Context for blacklist checks and the 'handle_test_blacklist_cont' + * function. Stores information about ongoing blacklist checks. + */ +struct BlackListCheckContext +{ + /** - * How often has the other peer (recently) violated the inbound - * traffic limit? Incremented by 10 per violation, decremented by 1 - * per non-violation (for each time interval). + * We keep blacklist checks in a DLL. */ - unsigned int quota_violation_count; + struct BlackListCheckContext *next; + + /** + * We keep blacklist checks in a DLL. + */ + struct BlackListCheckContext *prev; + /** + * Address that is being checked. + */ + struct NeighbourAddress na; + + /** + * ATS information about the address. + */ + struct GNUNET_ATS_Information *ats; /** - * The current state of the peer - * Element of enum State + * Handle to the ongoing blacklist check. */ - int state; + struct GST_BlacklistCheck *bc; /** - * Did we sent an KEEP_ALIVE message and are we expecting a response? + * Size of the 'ats' array. */ - int expect_latency_response; - int address_state; + uint32_t ats_count; + }; /** - * All known neighbours and their HELLOs. + * Hash map from peer identities to the respective 'struct NeighbourMapEntry'. */ static struct GNUNET_CONTAINER_MultiHashMap *neighbours; +/** + * We keep blacklist checks in a DLL so that we can find + * the 'sessions' in their 'struct NeighbourAddress' if + * a session goes down. + */ +static struct BlackListCheckContext *bc_head; + +/** + * We keep blacklist checks in a DLL. + */ +static struct BlackListCheckContext *bc_tail; + /** * Closure for connect_notify_cb, disconnect_notify_cb and address_change_cb */ @@ -379,7 +599,13 @@ static GNUNET_TRANSPORT_PeerIterateCallback address_change_cb; /** * counter for connected neighbours */ -static int neighbours_connected; +static unsigned int neighbours_connected; + +/** + * Number of bytes we have currently queued for transmission. + */ +static unsigned long long bytes_in_send_queue; + /** * Lookup a neighbour entry in the neighbours hash map. @@ -390,468 +616,395 @@ static int neighbours_connected; static struct NeighbourMapEntry * lookup_neighbour (const struct GNUNET_PeerIdentity *pid) { + if (NULL == neighbours) + return NULL; return GNUNET_CONTAINER_multihashmap_get (neighbours, &pid->hashPubKey); } -/** - * Disconnect from the given neighbour, clean up the record. - * - * @param n neighbour to disconnect from - */ -static void -disconnect_neighbour (struct NeighbourMapEntry *n); - -#define change_state(n, state, ...) change (n, state, __LINE__) - -static int -is_connecting (struct NeighbourMapEntry *n) -{ - if ((n->state > S_NOT_CONNECTED) && (n->state < S_CONNECTED)) - return GNUNET_YES; - return GNUNET_NO; -} - -static int -is_connected (struct NeighbourMapEntry *n) -{ - if (n->state == S_CONNECTED) - return GNUNET_YES; - return GNUNET_NO; -} - -static int -is_disconnecting (struct NeighbourMapEntry *n) -{ - if (n->state == S_DISCONNECT) - return GNUNET_YES; - return GNUNET_NO; -} - static const char * print_state (int state) { + switch (state) { - case S_CONNECTED: - return "S_CONNECTED"; + case S_NOT_CONNECTED: + return "S_NOT_CONNECTED"; break; - case S_CONNECT_RECV: - return "S_CONNECT_RECV"; + case S_INIT_ATS: + return "S_INIT_ATS"; + break; + case S_INIT_BLACKLIST: + return "S_INIT_BLACKLIST"; break; case S_CONNECT_SENT: return "S_CONNECT_SENT"; break; + case S_CONNECT_RECV_ATS: + return "S_CONNECT_RECV_ATS"; + break; + case S_CONNECT_RECV_BLACKLIST: + return "S_CONNECT_RECV_BLACKLIST"; + break; + case S_CONNECT_RECV_ACK: + return "S_CONNECT_RECV_ACK"; + break; + case S_CONNECTED: + return "S_CONNECTED"; + break; + case S_RECONNECT_ATS: + return "S_RECONNECT_ATS"; + break; + case S_RECONNECT_BLACKLIST: + return "S_RECONNECT_BLACKLIST"; + break; + case S_RECONNECT_SENT: + return "S_RECONNECT_SENT"; + break; + case S_CONNECTED_SWITCHING_BLACKLIST: + return "S_CONNECTED_SWITCHING_BLACKLIST"; + break; + case S_CONNECTED_SWITCHING_CONNECT_SENT: + return "S_CONNECTED_SWITCHING_CONNECT_SENT"; + break; case S_DISCONNECT: return "S_DISCONNECT"; break; - case S_NOT_CONNECTED: - return "S_NOT_CONNECTED"; - break; - case S_FAST_RECONNECT: - return "S_FAST_RECONNECT"; + case S_DISCONNECT_FINISHED: + return "S_DISCONNECT_FINISHED"; break; default: + return "UNDEFINED"; GNUNET_break (0); break; } - return NULL; + GNUNET_break (0); + return "UNDEFINED"; } +/** + * Test if we're connected to the given peer. + * + * @param n neighbour entry of peer to test + * @return GNUNET_YES if we are connected, GNUNET_NO if not + */ static int -change (struct NeighbourMapEntry *n, int state, int line); - -static void -ats_suggest_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - +test_connected (struct NeighbourMapEntry *n) +{ + if (NULL == n) + return GNUNET_NO; + switch (n->state) + { + case S_NOT_CONNECTED: + case S_INIT_ATS: + case S_INIT_BLACKLIST: + case S_CONNECT_SENT: + case S_CONNECT_RECV_ATS: + case S_CONNECT_RECV_BLACKLIST: + case S_CONNECT_RECV_ACK: + return GNUNET_NO; + case S_CONNECTED: + case S_RECONNECT_ATS: + case S_RECONNECT_BLACKLIST: + case S_RECONNECT_SENT: + case S_CONNECTED_SWITCHING_BLACKLIST: + case S_CONNECTED_SWITCHING_CONNECT_SENT: + return GNUNET_YES; + case S_DISCONNECT: + case S_DISCONNECT_FINISHED: + return GNUNET_NO; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + break; + } + return GNUNET_SYSERR; +} +/** + * Send information about a new outbound quota to our clients. + * + * @param target affected peer + * @param quota new quota + */ static void -reset_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +send_outbound_quota (const struct GNUNET_PeerIdentity *target, + struct GNUNET_BANDWIDTH_Value32NBO quota) { - struct NeighbourMapEntry *n = cls; - - if (n == NULL) - return; - - n->state_reset = GNUNET_SCHEDULER_NO_TASK; - if (n->state == S_CONNECTED) - return; + struct QuotaSetMessage q_msg; -#if DEBUG_TRANSPORT - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# failed connection attempts due to timeout"), 1, - GNUNET_NO); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending outbound quota of %u Bps for peer `%s' to all clients\n", + ntohl (quota.value__), GNUNET_i2s (target)); + q_msg.header.size = htons (sizeof (struct QuotaSetMessage)); + q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA); + q_msg.quota = quota; + q_msg.peer = (*target); + GST_clients_broadcast (&q_msg.header, GNUNET_NO); +} - /* resetting state */ - if (n->state == S_FAST_RECONNECT) +/** + * We don't need a given neighbour address any more. + * Release its resources and give appropriate notifications + * to ATS and other subsystems. + * + * @param na address we are done with; 'na' itself must NOT be 'free'd, only the contents! + */ +static void +free_address (struct NeighbourAddress *na) +{ + if (GNUNET_YES == na->ats_active) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Fast reconnect time out, disconnecting peer `%s'\n", - GNUNET_i2s (&n->id)); - disconnect_neighbour(n); - return; + GST_validation_set_address_use (na->address, na->session, GNUNET_NO, __LINE__); + GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, GNUNET_NO); } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n", - GNUNET_i2s (&n->id), n, print_state(n->state), "S_NOT_CONNECTED", __LINE__); - - n->state = S_NOT_CONNECTED; - - /* destroying address */ - if (n->address != NULL) + na->ats_active = GNUNET_NO; + if (NULL != na->address) { - GNUNET_assert (strlen (n->address->transport_name) > 0); - GNUNET_ATS_address_destroyed (GST_ats, n->address, n->session); + GNUNET_HELLO_address_free (na->address); + na->address = NULL; } - - /* request new address */ - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = - GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, - n); - GNUNET_ATS_suggest_address (GST_ats, &n->id); + na->session = NULL; } -static int -change (struct NeighbourMapEntry *n, int state, int line) -{ - int previous_state; - /* allowed transitions */ - int allowed = GNUNET_NO; - previous_state = n->state; +/** + * Initialize the 'struct NeighbourAddress'. + * + * @param na neighbour address to initialize + * @param address address of the other peer, NULL if other peer + * connected to us + * @param session session to use (or NULL, in which case an + * address must be setup) + * @param bandwidth_in inbound quota to be used when connection is up + * @param bandwidth_out outbound quota to be used when connection is up + * @param is_active GNUNET_YES to mark this as the active address with ATS + */ +static void +set_address (struct NeighbourAddress *na, + const struct GNUNET_HELLO_Address *address, + struct Session *session, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, + int is_active) +{ + struct GNUNET_TRANSPORT_PluginFunctions *papi; - switch (n->state) + if (NULL == (papi = GST_plugins_find (address->transport_name))) { - case S_NOT_CONNECTED: - if ((state == S_CONNECT_RECV) || (state == S_CONNECT_SENT) || - (state == S_DISCONNECT)) - allowed = GNUNET_YES; - break; - case S_CONNECT_RECV: - allowed = GNUNET_YES; - break; - case S_CONNECT_SENT: - allowed = GNUNET_YES; - break; - case S_CONNECTED: - if ((state == S_DISCONNECT) || (state == S_FAST_RECONNECT)) - allowed = GNUNET_YES; - break; - case S_DISCONNECT: - break; - case S_FAST_RECONNECT: - if ((state == S_CONNECTED) || (state == S_DISCONNECT)) - allowed = GNUNET_YES; - break; - default: - GNUNET_break (0); - break; - } - if (allowed == GNUNET_NO) - { - char *old = GNUNET_strdup (print_state (n->state)); - char *new = GNUNET_strdup (print_state (state)); - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Illegal state transition from `%s' to `%s' in line %u \n", old, - new, line); GNUNET_break (0); - GNUNET_free (old); - GNUNET_free (new); - return GNUNET_SYSERR; - } - { - char *old = GNUNET_strdup (print_state (n->state)); - char *new = GNUNET_strdup (print_state (state)); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n", - GNUNET_i2s (&n->id), n, old, new, line); - GNUNET_free (old); - GNUNET_free (new); + return; } - n->state = state; - - switch (n->state) + if (session == na->session) { - case S_FAST_RECONNECT: - case S_CONNECT_RECV: - case S_CONNECT_SENT: - if (n->state_reset != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->state_reset); - n->state_reset = - GNUNET_SCHEDULER_add_delayed (SETUP_CONNECTION_TIMEOUT, &reset_task, n); - break; - case S_CONNECTED: - case S_NOT_CONNECTED: - case S_DISCONNECT: - if (GNUNET_SCHEDULER_NO_TASK != n->state_reset) + na->bandwidth_in = bandwidth_in; + na->bandwidth_out = bandwidth_out; + if (is_active != na->ats_active) { -#if DEBUG_TRANSPORT - char *old = GNUNET_strdup (print_state (n->state)); - char *new = GNUNET_strdup (print_state (state)); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Removed reset task for peer `%s' %s failed in state transition `%s' -> `%s' \n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address), old, new); - GNUNET_free (old); - GNUNET_free (new); -#endif - GNUNET_assert (n->state_reset != GNUNET_SCHEDULER_NO_TASK); - GNUNET_SCHEDULER_cancel (n->state_reset); - n->state_reset = GNUNET_SCHEDULER_NO_TASK; + na->ats_active = is_active; + GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, is_active); + GST_validation_set_address_use (na->address, na->session, is_active, __LINE__); } - break; - - default: - GNUNET_assert (0); + if (GNUNET_YES == is_active) + { + /* FIXME: is this the right place to set quotas? */ + GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in); + send_outbound_quota (&address->peer, bandwidth_out); + } + return; } - - if (NULL != address_change_cb) + free_address (na); + if (NULL == session) + session = papi->get_session (papi->cls, address); + if (NULL == session) { - if (n->state == S_CONNECTED) - address_change_cb (callback_cls, &n->id, n->address); - else if (previous_state == S_CONNECTED) - address_change_cb (callback_cls, &n->id, NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Failed to obtain new session for peer `%s' and address '%s'\n", + GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); + GNUNET_ATS_address_destroyed (GST_ats, address, NULL); + return; } - - return GNUNET_OK; -} - -static ssize_t -send_with_session (struct NeighbourMapEntry *n, - const char *msgbuf, size_t msgbuf_size, - uint32_t priority, - struct GNUNET_TIME_Relative timeout, - GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) -{ - struct GNUNET_TRANSPORT_PluginFunctions *papi; - size_t ret = GNUNET_SYSERR; - - GNUNET_assert (n != NULL); - GNUNET_assert (n->session != NULL); - - papi = GST_plugins_find (n->address->transport_name); - if (papi == NULL) + na->address = GNUNET_HELLO_address_copy (address); + na->bandwidth_in = bandwidth_in; + na->bandwidth_out = bandwidth_out; + na->session = session; + na->ats_active = is_active; + if (GNUNET_YES == is_active) { - if (cont != NULL) - cont (cont_cls, &n->id, GNUNET_SYSERR); - return GNUNET_SYSERR; - } - - ret = papi->send (papi->cls, - n->session, - msgbuf, msgbuf_size, - 0, - timeout, - cont, cont_cls); - - if ((ret == -1) && (cont != NULL)) - cont (cont_cls, &n->id, GNUNET_SYSERR); - return ret; -} - -/** - * Task invoked to start a transmission to another peer. - * - * @param cls the 'struct NeighbourMapEntry' - * @param tc scheduler context - */ -static void -transmission_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - - -/** - * We're done with our transmission attempt, continue processing. - * - * @param cls the 'struct MessageQueue' of the message - * @param receiver intended receiver - * @param success whether it worked or not - */ -static void -transmit_send_continuation (void *cls, - const struct GNUNET_PeerIdentity *receiver, - int success) -{ - struct MessageQueue *mq = cls; - struct NeighbourMapEntry *n; - struct NeighbourMapEntry *tmp; + /* Telling ATS about new session */ + GNUNET_ATS_address_update (GST_ats, na->address, na->session, NULL, 0); + GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, GNUNET_YES); + GST_validation_set_address_use (na->address, na->session, GNUNET_YES, __LINE__); - tmp = lookup_neighbour (receiver); - n = mq->n; - if ((NULL != n) && (tmp != NULL) && (tmp == n)) - { - GNUNET_assert (n->is_active == mq); - n->is_active = NULL; - if (success == GNUNET_YES) - { - GNUNET_assert (n->transmission_task == GNUNET_SCHEDULER_NO_TASK); - n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n); - } + /* FIXME: is this the right place to set quotas? */ + GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in); + send_outbound_quota (&address->peer, bandwidth_out); } -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message of type %u was %s\n", - ntohs (((struct GNUNET_MessageHeader *) mq->message_buf)->type), - (success == GNUNET_OK) ? "successful" : "FAILED"); -#endif - if (NULL != mq->cont) - mq->cont (mq->cont_cls, success); - GNUNET_free (mq); } /** - * Check the ready list for the given neighbour and if a plugin is - * ready for transmission (and if we have a message), do so! + * Free a neighbour map entry. * - * @param n target peer for which to transmit + * @param n entry to free + * @param keep_sessions GNUNET_NO to tell plugin to terminate sessions, + * GNUNET_YES to keep all sessions */ static void -try_transmission_to_peer (struct NeighbourMapEntry *n) +free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) { struct MessageQueue *mq; - struct GNUNET_TIME_Relative timeout; - ssize_t ret; + struct GNUNET_TRANSPORT_PluginFunctions *papi; - if (n->is_active != NULL) - { - GNUNET_break (0); - return; /* transmission already pending */ - } - if (n->transmission_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_break (0); - return; /* currently waiting for bandwidth */ - } + n->is_active = NULL; /* always free'd by its own continuation! */ + + /* fail messages currently in the queue */ while (NULL != (mq = n->messages_head)) { - timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout); - if (timeout.rel_value > 0) - break; GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); - n->is_active = mq; - mq->n = n; - transmit_send_continuation (mq, &n->id, GNUNET_SYSERR); /* timeout */ + if (NULL != mq->cont) + mq->cont (mq->cont_cls, GNUNET_SYSERR); + GNUNET_free (mq); } - if (NULL == mq) - return; /* no more messages */ - - if (n->address == NULL) + /* It is too late to send other peer disconnect notifications, but at + least internally we need to get clean... */ + if (GNUNET_YES == test_connected (n)) { -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No address for peer `%s'\n", - GNUNET_i2s (&n->id)); -#endif - GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); - transmit_send_continuation (mq, &n->id, GNUNET_SYSERR); - GNUNET_assert (n->transmission_task == GNUNET_SCHEDULER_NO_TASK); - n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n); - return; + GNUNET_STATISTICS_set (GST_stats, + gettext_noop ("# peers connected"), + --neighbours_connected, + GNUNET_NO); + disconnect_notify_cb (callback_cls, &n->id); } - if (GST_plugins_find (n->address->transport_name) == NULL) - { - GNUNET_break (0); - return; - } - GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); - n->is_active = mq; - mq->n = n; + /* FIXME-PLUGIN-API: This does not seem to guarantee that all + transport sessions eventually get killed due to inactivity; they + MUST have their own timeout logic (but at least TCP doesn't have + one yet). Are we sure that EVERY 'session' of a plugin is + actually cleaned up this way!? Note that if we are switching + between two TCP sessions to the same peer, the existing plugin + API gives us not even the means to selectively kill only one of + them! Killing all sessions like this seems to be very, very + wrong. */ + if ((GNUNET_NO == keep_sessions) && + (NULL != n->primary_address.address) && + (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name)))) + papi->disconnect (papi->cls, &n->id); - if ((n->address->address_length == 0) && (n->session == NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No address for peer `%s'\n", - GNUNET_i2s (&n->id)); - transmit_send_continuation (mq, &n->id, GNUNET_SYSERR); - GNUNET_assert (n->transmission_task == GNUNET_SCHEDULER_NO_TASK); - n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n); - return; - } + n->state = S_DISCONNECT_FINISHED; + + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (neighbours, + &n->id.hashPubKey, n)); - ret = send_with_session(n, - mq->message_buf, mq->message_buf_size, - 0, timeout, - &transmit_send_continuation, mq); + /* cut transport-level connection */ + free_address (&n->primary_address); + free_address (&n->alternative_address); - if (ret == -1) + // FIXME-ATS-API: we might want to be more specific about + // which states we do this from in the future (ATS should + // have given us a 'suggest_address' handle, and if we have + // such a handle, we should cancel the operation here! + GNUNET_ATS_suggest_address_cancel (GST_ats, &n->id); + + if (GNUNET_SCHEDULER_NO_TASK != n->task) { - /* failure, but 'send' would not call continuation in this case, - * so we need to do it here! */ - transmit_send_continuation (mq, &n->id, GNUNET_SYSERR); + GNUNET_SCHEDULER_cancel (n->task); + n->task = GNUNET_SCHEDULER_NO_TASK; } - + /* free rest of memory */ + GNUNET_free (n); } /** - * Task invoked to start a transmission to another peer. + * Transmit a message using the current session of the given + * neighbour. * - * @param cls the 'struct NeighbourMapEntry' - * @param tc scheduler context + * @param n entry for the recipient + * @param msgbuf buffer to transmit + * @param msgbuf_size number of bytes in buffer + * @param priority transmission priority + * @param timeout transmission timeout + * @param cont continuation to call when finished (can be NULL) + * @param cont_cls closure for cont */ static void -transmission_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +send_with_session (struct NeighbourMapEntry *n, + const char *msgbuf, size_t msgbuf_size, + uint32_t priority, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_TransmitContinuation cont, + void *cont_cls) { - struct NeighbourMapEntry *n = cls; + struct GNUNET_TRANSPORT_PluginFunctions *papi; - GNUNET_assert (NULL != lookup_neighbour (&n->id)); - n->transmission_task = GNUNET_SCHEDULER_NO_TASK; - try_transmission_to_peer (n); + GNUNET_assert (n->primary_address.session != NULL); + if ( ( (NULL == (papi = GST_plugins_find (n->primary_address.address->transport_name))) || + (-1 == papi->send (papi->cls, + n->primary_address.session, + msgbuf, msgbuf_size, + priority, + timeout, + cont, cont_cls))) && + (NULL != cont) ) + cont (cont_cls, &n->id, GNUNET_SYSERR); + GNUNET_break (NULL != papi); } /** - * Initialize the neighbours subsystem. + * Master task run for every neighbour. Performs all of the time-related + * activities (keep alive, send next message, disconnect if idle, finish + * clean up after disconnect). * - * @param cls closure for callbacks - * @param connect_cb function to call if we connect to a peer - * @param disconnect_cb function to call if we disconnect from a peer - * @param peer_address_cb function to call if we change an active address - * of a neighbour + * @param cls the 'struct NeighbourMapEntry' for which we are running + * @param tc scheduler context (unused) */ -void -GST_neighbours_start (void *cls, - GNUNET_TRANSPORT_NotifyConnect connect_cb, - GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, - GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb) -{ - callback_cls = cls; - connect_notify_cb = connect_cb; - disconnect_notify_cb = disconnect_cb; - address_change_cb = peer_address_cb; - neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE); -} +static void +master_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc); +/** + * Function called when the 'DISCONNECT' message has been sent by the + * plugin. Frees the neighbour --- if the entry still exists. + * + * @param cls NULL + * @param target identity of the neighbour that was disconnected + * @param result GNUNET_OK if the disconnect got out successfully + */ static void send_disconnect_cont (void *cls, const struct GNUNET_PeerIdentity *target, int result) { -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending DISCONNECT message to peer `%4s': %i\n", - GNUNET_i2s (target), result); -#endif + struct NeighbourMapEntry *n; + + n = lookup_neighbour (target); + if (NULL == n) + return; /* already gone */ + if (S_DISCONNECT != n->state) + return; /* have created a fresh entry since */ + n->state = S_DISCONNECT; + if (GNUNET_SCHEDULER_NO_TASK != n->task) + GNUNET_SCHEDULER_cancel (n->task); + n->task = GNUNET_SCHEDULER_add_now (&master_task, n); } -static int -send_disconnect (struct NeighbourMapEntry * n) +/** + * Transmit a DISCONNECT message to the other peer. + * + * @param n neighbour to send DISCONNECT message. + */ +static void +send_disconnect (struct NeighbourMapEntry *n) { - size_t ret; struct SessionDisconnectMessage disconnect_msg; -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending DISCONNECT message to peer `%4s'\n", GNUNET_i2s (&n->id)); -#endif - disconnect_msg.header.size = htons (sizeof (struct SessionDisconnectMessage)); disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT); @@ -870,19 +1023,14 @@ send_disconnect (struct NeighbourMapEntry * n) &disconnect_msg.purpose, &disconnect_msg.signature)); - ret = send_with_session (n, - (const char *) &disconnect_msg, sizeof (disconnect_msg), - UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, - &send_disconnect_cont, NULL); - - if (ret == GNUNET_SYSERR) - return GNUNET_SYSERR; - + send_with_session (n, + (const char *) &disconnect_msg, sizeof (disconnect_msg), + UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, + &send_disconnect_cont, NULL); GNUNET_STATISTICS_update (GST_stats, gettext_noop - ("# peers disconnected due to external request"), 1, + ("# DISCONNECT messages sent"), 1, GNUNET_NO); - return GNUNET_OK; } @@ -894,780 +1042,541 @@ send_disconnect (struct NeighbourMapEntry * n) static void disconnect_neighbour (struct NeighbourMapEntry *n) { - struct MessageQueue *mq; - int previous_state; - - previous_state = n->state; - - if (is_disconnecting (n)) - return; - - /* send DISCONNECT MESSAGE */ - if (previous_state == S_CONNECTED) - { - if (GNUNET_OK == send_disconnect (n)) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent DISCONNECT_MSG to `%s'\n", - GNUNET_i2s (&n->id)); - else - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Could not send DISCONNECT_MSG to `%s'\n", - GNUNET_i2s (&n->id)); - } - - change_state (n, S_DISCONNECT); - - if (previous_state == S_CONNECTED) - { - GNUNET_assert (NULL != n->address); - if (n->address_state == USED) - { - GST_validation_set_address_use (n->address, n->session, GNUNET_NO); - GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO); - n->address_state = UNUSED; - } - } - - if (n->address != NULL) - { - struct GNUNET_TRANSPORT_PluginFunctions *papi; - - papi = GST_plugins_find (n->address->transport_name); - if (papi != NULL) - papi->disconnect (papi->cls, &n->id); - } - while (NULL != (mq = n->messages_head)) - { - GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); - if (NULL != mq->cont) - mq->cont (mq->cont_cls, GNUNET_SYSERR); - GNUNET_free (mq); - } - if (NULL != n->is_active) - { - n->is_active->n = NULL; - n->is_active = NULL; - } - - switch (previous_state) + /* depending on state, notify neighbour and/or upper layers of this peer + about disconnect */ + switch (n->state) { + case S_NOT_CONNECTED: + case S_INIT_ATS: + case S_INIT_BLACKLIST: + /* other peer is completely unaware of us, no need to send DISCONNECT */ + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + case S_CONNECT_SENT: + send_disconnect (n); + n->state = S_DISCONNECT; + break; + case S_CONNECT_RECV_ATS: + case S_CONNECT_RECV_BLACKLIST: + /* we never ACK'ed the other peer's request, no need to send DISCONNECT */ + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + case S_CONNECT_RECV_ACK: + /* we DID ACK the other peer's request, must send DISCONNECT */ + send_disconnect (n); + n->state = S_DISCONNECT; + break; case S_CONNECTED: - GNUNET_assert (neighbours_connected > 0); - neighbours_connected--; - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task); - GNUNET_SCHEDULER_cancel (n->keepalive_task); - n->keepalive_task = GNUNET_SCHEDULER_NO_TASK; - n->expect_latency_response = GNUNET_NO; - GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), -1, - GNUNET_NO); + case S_RECONNECT_BLACKLIST: + case S_RECONNECT_SENT: + case S_CONNECTED_SWITCHING_BLACKLIST: + case S_CONNECTED_SWITCHING_CONNECT_SENT: + /* we are currently connected, need to send disconnect and do + internal notifications and update statistics */ + send_disconnect (n); + GNUNET_STATISTICS_set (GST_stats, + gettext_noop ("# peers connected"), + --neighbours_connected, + GNUNET_NO); disconnect_notify_cb (callback_cls, &n->id); + n->state = S_DISCONNECT; break; - case S_FAST_RECONNECT: - GNUNET_STATISTICS_update (GST_stats, - gettext_noop ("# fast reconnects failed"), 1, - GNUNET_NO); + case S_RECONNECT_ATS: + /* ATS address request timeout, disconnect without sending disconnect message */ + GNUNET_STATISTICS_set (GST_stats, + gettext_noop ("# peers connected"), + --neighbours_connected, + GNUNET_NO); disconnect_notify_cb (callback_cls, &n->id); + n->state = S_DISCONNECT; + break; + case S_DISCONNECT: + /* already disconnected, ignore */ + break; + case S_DISCONNECT_FINISHED: + /* already cleaned up, how did we get here!? */ + GNUNET_assert (0); break; default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); break; } - - GNUNET_ATS_suggest_address_cancel (GST_ats, &n->id); - - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (neighbours, - &n->id.hashPubKey, n)); - if (GNUNET_SCHEDULER_NO_TASK != n->ats_suggest) - { - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = GNUNET_SCHEDULER_NO_TASK; - } - if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task) - { - GNUNET_SCHEDULER_cancel (n->timeout_task); - n->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - if (GNUNET_SCHEDULER_NO_TASK != n->transmission_task) - { - GNUNET_SCHEDULER_cancel (n->transmission_task); - n->transmission_task = GNUNET_SCHEDULER_NO_TASK; - } - if (NULL != n->address) - { - GNUNET_HELLO_address_free (n->address); - n->address = NULL; - } - n->session = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting peer `%4s', %X\n", - GNUNET_i2s (&n->id), n); - GNUNET_free (n); + /* schedule timeout to clean up */ + if (GNUNET_SCHEDULER_NO_TASK != n->task) + GNUNET_SCHEDULER_cancel (n->task); + n->task = GNUNET_SCHEDULER_add_delayed (DISCONNECT_SENT_TIMEOUT, + &master_task, n); } /** - * Peer has been idle for too long. Disconnect. + * We're done with our transmission attempt, continue processing. * - * @param cls the 'struct NeighbourMapEntry' of the neighbour that went idle - * @param tc scheduler context + * @param cls the 'struct MessageQueue' of the message + * @param receiver intended receiver + * @param success whether it worked or not */ static void -neighbour_timeout_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +transmit_send_continuation (void *cls, + const struct GNUNET_PeerIdentity *receiver, + int success) { - struct NeighbourMapEntry *n = cls; - - n->timeout_task = GNUNET_SCHEDULER_NO_TASK; + struct MessageQueue *mq = cls; + struct NeighbourMapEntry *n; - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# peers disconnected due to timeout"), 1, - GNUNET_NO); - disconnect_neighbour (n); + if (NULL == (n = lookup_neighbour (receiver))) + { + GNUNET_free (mq); + return; /* disconnect or other error while transmitting, can happen */ + } + if (n->is_active == mq) + { + /* this is still "our" neighbour, remove us from its queue + and allow it to send the next message now */ + n->is_active = NULL; + if (GNUNET_SCHEDULER_NO_TASK != n->task) + GNUNET_SCHEDULER_cancel (n->task); + n->task = GNUNET_SCHEDULER_add_now (&master_task, n); + } + GNUNET_assert (bytes_in_send_queue >= mq->message_buf_size); + bytes_in_send_queue -= mq->message_buf_size; + GNUNET_STATISTICS_set (GST_stats, + gettext_noop + ("# bytes in message queue for other peers"), + bytes_in_send_queue, GNUNET_NO); + if (GNUNET_OK == success) + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# messages transmitted to other peers"), + 1, GNUNET_NO); + else + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# transmission failures for messages to other peers"), + 1, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending message to `%s' of type %u was a %s\n", + GNUNET_i2s (receiver), + ntohs (((struct GNUNET_MessageHeader *) mq->message_buf)->type), + (success == GNUNET_OK) ? "success" : "FAILURE"); + if (NULL != mq->cont) + mq->cont (mq->cont_cls, success); + GNUNET_free (mq); } /** - * Send another keepalive message. + * Check the message list for the given neighbour and if we can + * send a message, do so. This function should only be called + * if the connection is at least generally ready for transmission. + * While we will only send one message at a time, no bandwidth + * quota management is performed here. If a message was given to + * the plugin, the continuation will automatically re-schedule + * the 'master' task once the next message might be transmitted. * - * @param cls the 'struct NeighbourMapEntry' of the neighbour that went idle - * @param tc scheduler context + * @param n target peer for which to transmit */ static void -neighbour_keepalive_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +try_transmission_to_peer (struct NeighbourMapEntry *n) { - struct NeighbourMapEntry *n = cls; - struct GNUNET_MessageHeader m; - int ret; - - GNUNET_assert (S_CONNECTED == n->state); - n->keepalive_task = - GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY, - &neighbour_keepalive_task, n); - - GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# keepalives sent"), 1, - GNUNET_NO); - m.size = htons (sizeof (struct GNUNET_MessageHeader)); - m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); - - ret = send_with_session (n, - (const void *) &m, sizeof (m), - UINT32_MAX /* priority */ , - GNUNET_TIME_UNIT_FOREVER_REL, - NULL, NULL); + struct MessageQueue *mq; + struct GNUNET_TIME_Relative timeout; - n->expect_latency_response = GNUNET_NO; - n->keep_alive_sent = GNUNET_TIME_absolute_get_zero (); - if (ret != GNUNET_SYSERR) + if (NULL == n->primary_address.address) + { + /* no address, why are we here? */ + GNUNET_break (0); + return; + } + if ((0 == n->primary_address.address->address_length) && + (NULL == n->primary_address.session)) + { + /* no address, why are we here? */ + GNUNET_break (0); + return; + } + if (NULL != n->is_active) { - n->expect_latency_response = GNUNET_YES; - n->keep_alive_sent = GNUNET_TIME_absolute_get (); + /* transmission already pending */ + return; } + /* timeout messages from the queue that are past their due date */ + while (NULL != (mq = n->messages_head)) + { + timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout); + if (timeout.rel_value > 0) + break; + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# messages timed out while in transport queue"), + 1, GNUNET_NO); + GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); + n->is_active = mq; + transmit_send_continuation (mq, &n->id, GNUNET_SYSERR); /* timeout */ + } + if (NULL == mq) + return; /* no more messages */ + GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); + n->is_active = mq; + send_with_session (n, + mq->message_buf, mq->message_buf_size, + 0 /* priority */, timeout, + &transmit_send_continuation, mq); } /** - * Disconnect from the given neighbour. + * Send keepalive message to the neighbour. Must only be called + * if we are on 'connected' state. Will internally determine + * if a keepalive is truly needed (so can always be called). * - * @param cls unused - * @param key hash of neighbour's public key (not used) - * @param value the 'struct NeighbourMapEntry' of the neighbour + * @param n neighbour that went idle and needs a keepalive */ -static int -disconnect_all_neighbours (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct NeighbourMapEntry *n = value; - -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s', %s\n", - GNUNET_i2s (&n->id), "SHUTDOWN_TASK"); -#endif - if (S_CONNECTED == n->state) - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# peers disconnected due to global disconnect"), - 1, GNUNET_NO); - disconnect_neighbour (n); - return GNUNET_OK; -} - - static void -ats_suggest_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +send_keepalive (struct NeighbourMapEntry *n) { - struct NeighbourMapEntry *n = cls; - - n->ats_suggest = GNUNET_SCHEDULER_NO_TASK; - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "ATS did not suggested address to connect to peer `%s'\n", - GNUNET_i2s (&n->id)); + struct GNUNET_MessageHeader m; - disconnect_neighbour (n); + GNUNET_assert (S_CONNECTED == n->state); + if (GNUNET_TIME_absolute_get_remaining (n->keep_alive_time).rel_value > 0) + return; /* no keepalive needed at this time */ + m.size = htons (sizeof (struct GNUNET_MessageHeader)); + m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); + send_with_session (n, + (const void *) &m, sizeof (m), + UINT32_MAX /* priority */, + KEEPALIVE_FREQUENCY, + NULL, NULL); + GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# keepalives sent"), 1, + GNUNET_NO); + n->expect_latency_response = GNUNET_YES; + n->last_keep_alive_time = GNUNET_TIME_absolute_get (); + n->keep_alive_time = GNUNET_TIME_relative_to_absolute (KEEPALIVE_FREQUENCY); } + /** - * Cleanup the neighbours subsystem. + * Keep the connection to the given neighbour alive longer, + * we received a KEEPALIVE (or equivalent); send a response. + * + * @param neighbour neighbour to keep alive (by sending keep alive response) */ void -GST_neighbours_stop () +GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour) { - // This can happen during shutdown - if (neighbours == NULL) + struct NeighbourMapEntry *n; + struct GNUNET_MessageHeader m; + + if (NULL == (n = lookup_neighbour (neighbour))) { + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# KEEPALIVE messages discarded (peer unknown)"), + 1, GNUNET_NO); return; } - - GNUNET_CONTAINER_multihashmap_iterate (neighbours, &disconnect_all_neighbours, - NULL); - GNUNET_CONTAINER_multihashmap_destroy (neighbours); -// GNUNET_assert (neighbours_connected == 0); - neighbours = NULL; - callback_cls = NULL; - connect_notify_cb = NULL; - disconnect_notify_cb = NULL; - address_change_cb = NULL; + if (NULL == n->primary_address.session) + { + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# KEEPALIVE messages discarded (no session)"), + 1, GNUNET_NO); + return; + } + /* send reply to allow neighbour to measure latency */ + m.size = htons (sizeof (struct GNUNET_MessageHeader)); + m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE); + send_with_session(n, + (const void *) &m, sizeof (m), + UINT32_MAX /* priority */, + KEEPALIVE_FREQUENCY, + NULL, NULL); } -struct ContinutionContext -{ - struct GNUNET_HELLO_Address *address; - - struct Session *session; -}; - -static void -send_outbound_quota (const struct GNUNET_PeerIdentity *target, - struct GNUNET_BANDWIDTH_Value32NBO quota) -{ - struct QuotaSetMessage q_msg; - -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending outbound quota of %u Bps for peer `%s' to all clients\n", - ntohl (quota.value__), GNUNET_i2s (target)); -#endif - q_msg.header.size = htons (sizeof (struct QuotaSetMessage)); - q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA); - q_msg.quota = quota; - q_msg.peer = (*target); - GST_clients_broadcast (&q_msg.header, GNUNET_NO); -} /** - * We tried to send a SESSION_CONNECT message to another peer. If this - * succeeded, we change the state. If it failed, we should tell - * ATS to not use this address anymore (until it is re-validated). + * We received a KEEP_ALIVE_RESPONSE message and use this to calculate + * latency to this peer. Pass the updated information (existing ats + * plus calculated latency) to ATS. * - * @param cls the 'struct GNUNET_HELLO_Address' of the address that was tried - * @param target peer to send the message to - * @param success GNUNET_OK on success + * @param neighbour neighbour to keep alive + * @param ats performance data + * @param ats_count number of entries in ats */ -static void -send_connect_continuation (void *cls, const struct GNUNET_PeerIdentity *target, - int success) +void +GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) { - struct ContinutionContext *cc = cls; - struct NeighbourMapEntry *n = lookup_neighbour (&cc->address->peer); + struct NeighbourMapEntry *n; + uint32_t latency; + struct GNUNET_ATS_Information ats_new[ats_count + 1]; - if (GNUNET_YES != success) - { - GNUNET_assert (strlen (cc->address->transport_name) > 0); - GNUNET_ATS_address_destroyed (GST_ats, cc->address, cc->session); - } - if ((NULL == neighbours) || (NULL == n) || (n->state == S_DISCONNECT)) + if (NULL == (n = lookup_neighbour (neighbour))) { - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# KEEPALIVE_RESPONSE messages discarded (not connected)"), + 1, GNUNET_NO); return; } - - if ((GNUNET_YES == success) && - ((n->state == S_NOT_CONNECTED) || (n->state == S_CONNECT_SENT))) + if ( (S_CONNECTED != n->state) || + (GNUNET_YES != n->expect_latency_response) ) { - change_state (n, S_CONNECT_SENT); - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# KEEPALIVE_RESPONSE messages discarded (not expected)"), + 1, GNUNET_NO); return; } - - if ((GNUNET_NO == success) && - ((n->state == S_NOT_CONNECTED) || (n->state == S_CONNECT_SENT))) - { -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to send CONNECT_MSG to peer `%4s' with address '%s' session %p, asking ATS for new address \n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address), n->session); -#endif - change_state (n, S_NOT_CONNECTED); - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = - GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, &ats_suggest_cancel, - n); - GNUNET_ATS_suggest_address (GST_ats, &n->id); - } - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); + n->expect_latency_response = GNUNET_NO; + n->latency = GNUNET_TIME_absolute_get_duration (n->last_keep_alive_time); + n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Latency for peer `%s' is %llu ms\n", + GNUNET_i2s (&n->id), n->latency.rel_value); + memcpy (ats_new, ats, sizeof (struct GNUNET_ATS_Information) * ats_count); + /* append latency */ + ats_new[ats_count].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); + if (n->latency.rel_value > UINT32_MAX) + latency = UINT32_MAX; + else + latency = n->latency.rel_value; + ats_new[ats_count].value = htonl (latency); + GNUNET_ATS_address_update (GST_ats, + n->primary_address.address, + n->primary_address.session, ats_new, + ats_count + 1); } /** - * We tried to switch addresses with an peer already connected. If it failed, - * we should tell ATS to not use this address anymore (until it is re-validated). + * We have received a message from the given sender. How long should + * we delay before receiving more? (Also used to keep the peer marked + * as live). * - * @param cls the 'struct NeighbourMapEntry' - * @param target peer to send the message to - * @param success GNUNET_OK on success + * @param sender sender of the message + * @param size size of the message + * @param do_forward set to GNUNET_YES if the message should be forwarded to clients + * GNUNET_NO if the neighbour is not connected or violates the quota, + * GNUNET_SYSERR if the connection is not fully up yet + * @return how long to wait before reading more from this sender */ -static void -send_switch_address_continuation (void *cls, - const struct GNUNET_PeerIdentity *target, - int success) +struct GNUNET_TIME_Relative +GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity + *sender, ssize_t size, int *do_forward) { - struct ContinutionContext *cc = cls; struct NeighbourMapEntry *n; - - if (neighbours == NULL) + struct GNUNET_TIME_Relative ret; + + if (NULL == neighbours) { - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); - return; /* neighbour is going away */ + *do_forward = GNUNET_NO; + return GNUNET_TIME_UNIT_FOREVER_REL; /* This can happen during shutdown */ } - - n = lookup_neighbour (&cc->address->peer); - if ((n == NULL) || (is_disconnecting (n))) + if (NULL == (n = lookup_neighbour (sender))) + { + GST_neighbours_try_connect (sender); + if (NULL == (n = lookup_neighbour (sender))) + { + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# messages discarded due to lack of neighbour record"), + 1, GNUNET_NO); + *do_forward = GNUNET_NO; + return GNUNET_TIME_UNIT_ZERO; + } + } + if (! test_connected (n)) { - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); - return; /* neighbour is going away */ + *do_forward = GNUNET_SYSERR; + return GNUNET_TIME_UNIT_ZERO; } - - GNUNET_assert ((n->state == S_CONNECTED) || (n->state == S_FAST_RECONNECT)); - if (GNUNET_YES != success) + if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, size)) { -#if DEBUG_TRANSPORT + n->quota_violation_count++; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to switch connected peer `%s' to address '%s' session %X, asking ATS for new address \n", - GNUNET_i2s (&n->id), GST_plugins_a2s (cc->address), cc->session); -#endif - GNUNET_assert (strlen (cc->address->transport_name) > 0); - GNUNET_ATS_address_destroyed (GST_ats, cc->address, cc->session); - - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = - GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, - n); - GNUNET_ATS_suggest_address (GST_ats, &n->id); - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); - return; + "Bandwidth quota (%u b/s) violation detected (total of %u).\n", + n->in_tracker.available_bytes_per_s__, + n->quota_violation_count); + /* Discount 32k per violation */ + GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, -32 * 1024); } - /* Tell ATS that switching addresses was successful */ - switch (n->state) + else { - case S_CONNECTED: - if (n->address_state == FRESH) + if (n->quota_violation_count > 0) { - GST_validation_set_address_use (cc->address, cc->session, GNUNET_YES); - GNUNET_ATS_address_update (GST_ats, cc->address, cc->session, NULL, 0); - if (cc->session != n->session) - GNUNET_break (0); - GNUNET_ATS_address_in_use (GST_ats, cc->address, cc->session, GNUNET_YES); - n->address_state = USED; + /* try to add 32k back */ + GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, 32 * 1024); + n->quota_violation_count--; } - break; - case S_FAST_RECONNECT: -#if DEBUG_TRANSPORT + } + if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD) + { + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# bandwidth quota violations by other peers"), + 1, GNUNET_NO); + *do_forward = GNUNET_NO; + return GNUNET_CONSTANTS_QUOTA_VIOLATION_TIMEOUT; + } + *do_forward = GNUNET_YES; + ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 32 * 1024); + if (ret.rel_value > 0) + { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Successful fast reconnect to peer `%s'\n", - GNUNET_i2s (&n->id)); -#endif - change_state (n, S_CONNECTED); - neighbours_connected++; - GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, - GNUNET_NO); - - if (n->address_state == FRESH) - { - GST_validation_set_address_use (cc->address, cc->session, GNUNET_YES); - GNUNET_ATS_address_update (GST_ats, cc->address, cc->session, NULL, 0); - GNUNET_ATS_address_in_use (GST_ats, cc->address, cc->session, GNUNET_YES); - n->address_state = USED; - } - - if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK) - n->keepalive_task = - GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n); - - /* Updating quotas */ - GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in); - send_outbound_quota (target, n->bandwidth_out); - - default: - break; + "Throttling read (%llu bytes excess at %u b/s), waiting %llu ms before reading more.\n", + (unsigned long long) n->in_tracker. + consumption_since_last_update__, + (unsigned int) n->in_tracker.available_bytes_per_s__, + (unsigned long long) ret.rel_value); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop ("# ms throttling suggested"), + (int64_t) ret.rel_value, GNUNET_NO); } - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); + return ret; } /** - * We tried to send a SESSION_CONNECT message to another peer. If this - * succeeded, we change the state. If it failed, we should tell - * ATS to not use this address anymore (until it is re-validated). + * Transmit a message to the given target using the active connection. * - * @param cls the 'struct NeighbourMapEntry' - * @param target peer to send the message to - * @param success GNUNET_OK on success + * @param target destination + * @param msg message to send + * @param msg_size number of bytes in msg + * @param timeout when to fail with timeout + * @param cont function to call when done + * @param cont_cls closure for 'cont' */ -static void -send_connect_ack_continuation (void *cls, - const struct GNUNET_PeerIdentity *target, - int success) +void +GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, + size_t msg_size, struct GNUNET_TIME_Relative timeout, + GST_NeighbourSendContinuation cont, void *cont_cls) { - struct ContinutionContext *cc = cls; struct NeighbourMapEntry *n; + struct MessageQueue *mq; - if (neighbours == NULL) + /* All ove these cases should never happen; they are all API violations. + But we check anyway, just to be sure. */ + if (NULL == (n = lookup_neighbour (target))) { - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); - return; /* neighbour is going away */ + GNUNET_break (0); + if (NULL != cont) + cont (cont_cls, GNUNET_SYSERR); + return; } - - n = lookup_neighbour (&cc->address->peer); - if ((n == NULL) || (is_disconnecting (n))) + if (GNUNET_YES != test_connected (n)) { - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); - return; /* neighbour is going away */ + GNUNET_break (0); + if (NULL != cont) + cont (cont_cls, GNUNET_SYSERR); + return; } - - if (GNUNET_YES == success) - { - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); - return; /* sending successful */ - } - - /* sending failed, ask for next address */ -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to send CONNECT_MSG to peer `%4s' with address '%s' session %X, asking ATS for new address \n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address), n->session); -#endif - change_state (n, S_NOT_CONNECTED); - GNUNET_assert (strlen (cc->address->transport_name) > 0); - GNUNET_ATS_address_destroyed (GST_ats, cc->address, cc->session); - - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = - GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, - n); - GNUNET_ATS_suggest_address (GST_ats, &n->id); - GNUNET_HELLO_address_free (cc->address); - GNUNET_free (cc); -} + bytes_in_send_queue += msg_size; + GNUNET_STATISTICS_set (GST_stats, + gettext_noop + ("# bytes in message queue for other peers"), + bytes_in_send_queue, GNUNET_NO); + mq = GNUNET_malloc (sizeof (struct MessageQueue) + msg_size); + mq->cont = cont; + mq->cont_cls = cont_cls; + memcpy (&mq[1], msg, msg_size); + mq->message_buf = (const char *) &mq[1]; + mq->message_buf_size = msg_size; + mq->timeout = GNUNET_TIME_relative_to_absolute (timeout); + GNUNET_CONTAINER_DLL_insert_tail (n->messages_head, n->messages_tail, mq); + if ( (NULL != n->is_active) || + ( (NULL == n->primary_address.session) && (NULL == n->primary_address.address)) ) + return; + if (GNUNET_SCHEDULER_NO_TASK != n->task) + GNUNET_SCHEDULER_cancel (n->task); + n->task = GNUNET_SCHEDULER_add_now (&master_task, n); +} /** - * For an existing neighbour record, set the active connection to - * use the given address. + * Send a SESSION_CONNECT message via the given address. * - * @param peer identity of the peer to switch the address for - * @param address address of the other peer, NULL if other peer - * connected to us - * @param session session to use (or NULL) - * @param ats performance data - * @param ats_count number of entries in ats - * @param bandwidth_in inbound quota to be used when connection is up - * @param bandwidth_out outbound quota to be used when connection is up - * @return GNUNET_YES if we are currently connected, GNUNET_NO if the - * connection is not up (yet) + * @param na address to use */ -int -GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address - *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count, - struct GNUNET_BANDWIDTH_Value32NBO - bandwidth_in, - struct GNUNET_BANDWIDTH_Value32NBO - bandwidth_out) +static void +send_session_connect (struct NeighbourAddress *na) { - struct NeighbourMapEntry *n; - struct SessionConnectMessage connect_msg; - struct ContinutionContext *cc; - size_t msg_len; - size_t ret; - - if (neighbours == NULL) - { - /* This can happen during shutdown */ - return GNUNET_NO; - } - n = lookup_neighbour (peer); - if (NULL == n) - return GNUNET_NO; - if (n->state == S_DISCONNECT) - { - /* We are disconnecting, nothing to do here */ - return GNUNET_NO; - } - GNUNET_assert (address->transport_name != NULL); - if ((session == NULL) && (0 == address->address_length)) - { - GNUNET_break_op (0); - /* FIXME: is this actually possible? When does this happen? */ - if (strlen (address->transport_name) > 0) - GNUNET_ATS_address_destroyed (GST_ats, address, session); - GNUNET_ATS_suggest_address (GST_ats, peer); - return GNUNET_NO; - } - - /* checks successful and neighbour != NULL */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "ATS tells us to switch to address '%s' session %p for peer `%s' in state `%s'\n", - (address->address_length != 0) ? GST_plugins_a2s (address): "", - session, - GNUNET_i2s (peer), - print_state (n->state)); - - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = GNUNET_SCHEDULER_NO_TASK; - } - /* do not switch addresses just update quotas */ -/* - if (n->state == S_FAST_RECONNECT) - { - if (0 == GNUNET_HELLO_address_cmp(address, n->address)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "FAST RECONNECT to peer `%s' and address '%s' with identical ADDRESS\n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address)); - } - } -*/ - if ((n->state == S_CONNECTED) && (NULL != n->address) && - (0 == GNUNET_HELLO_address_cmp (address, n->address)) && - (n->session == session)) - { - n->bandwidth_in = bandwidth_in; - n->bandwidth_out = bandwidth_out; - GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in); - send_outbound_quota (peer, n->bandwidth_out); - return GNUNET_NO; - } - if (n->state == S_CONNECTED) - { - /* mark old address as no longer used */ - GNUNET_assert (NULL != n->address); - if (n->address_state == USED) - { - GST_validation_set_address_use (n->address, n->session, GNUNET_NO); - GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO); - n->address_state = UNUSED; - } - } - - /* set new address */ - if (NULL != n->address) - GNUNET_HELLO_address_free (n->address); - n->address = GNUNET_HELLO_address_copy (address); - n->address_state = FRESH; - n->bandwidth_in = bandwidth_in; - n->bandwidth_out = bandwidth_out; - GNUNET_SCHEDULER_cancel (n->timeout_task); - n->timeout_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, - &neighbour_timeout_task, n); - - if (NULL != address_change_cb && n->state == S_CONNECTED) - address_change_cb (callback_cls, &n->id, n->address); - - /* Obtain an session for this address from plugin */ struct GNUNET_TRANSPORT_PluginFunctions *papi; - papi = GST_plugins_find (address->transport_name); - - if (papi == NULL) - { - /* we don't have the plugin for this address */ - GNUNET_ATS_address_destroyed (GST_ats, n->address, NULL); - - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, - ats_suggest_cancel, - n); - GNUNET_ATS_suggest_address (GST_ats, &n->id); - GNUNET_HELLO_address_free (n->address); - n->address = NULL; - n->session = NULL; - return GNUNET_NO; - } - - if (session == NULL) - { - n->session = papi->get_session (papi->cls, address); - /* Session could not be initiated */ - if (n->session == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to obtain new session %p for peer `%s' and address '%s'\n", - n->session, GNUNET_i2s (&n->id), GST_plugins_a2s (n->address)); - - GNUNET_ATS_address_destroyed (GST_ats, n->address, NULL); - - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, - ats_suggest_cancel, - n); - GNUNET_ATS_suggest_address (GST_ats, &n->id); - GNUNET_HELLO_address_free (n->address); - n->address = NULL; - n->session = NULL; - return GNUNET_NO; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Obtained new session %p for peer `%s' and address '%s'\n", - n->session, GNUNET_i2s (&n->id), GST_plugins_a2s (n->address)); - /* Telling ATS about new session */ - GNUNET_ATS_address_update (GST_ats, n->address, n->session, NULL, 0); - } - else + struct SessionConnectMessage connect_msg; + + if (NULL == (papi = GST_plugins_find (na->address->transport_name))) { - n->session = session; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Using existing session %p for peer `%s' and address '%s'\n", - n->session, - GNUNET_i2s (&n->id), - (address->address_length != 0) ? GST_plugins_a2s (address): ""); + GNUNET_break (0); + return; } - - switch (n->state) + if (NULL == na->session) + na->session = papi->get_session (papi->cls, na->address); + if (NULL == na->session) { - case S_NOT_CONNECTED: - case S_CONNECT_SENT: - msg_len = sizeof (struct SessionConnectMessage); - connect_msg.header.size = htons (msg_len); - connect_msg.header.type = - htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT); - connect_msg.reserved = htonl (0); - connect_msg.timestamp = - GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); - - cc = GNUNET_malloc (sizeof (struct ContinutionContext)); - cc->session = n->session; - cc->address = GNUNET_HELLO_address_copy (address); - - ret = send_with_session (n, - (const char *) &connect_msg, msg_len, - UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, - &send_connect_continuation, cc); - - return GNUNET_NO; - case S_CONNECT_RECV: - /* We received a CONNECT message and asked ATS for an address */ - msg_len = sizeof (struct SessionConnectMessage); - connect_msg.header.size = htons (msg_len); - connect_msg.header.type = - htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT_ACK); - connect_msg.reserved = htonl (0); - connect_msg.timestamp = - GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); - cc = GNUNET_malloc (sizeof (struct ContinutionContext)); - cc->session = n->session; - cc->address = GNUNET_HELLO_address_copy (address); - - ret = send_with_session(n, - (const void *) &connect_msg, msg_len, - UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, - &send_connect_ack_continuation, - cc); - return GNUNET_NO; - case S_CONNECTED: - case S_FAST_RECONNECT: - /* connected peer is switching addresses or tries fast reconnect */ - msg_len = sizeof (struct SessionConnectMessage); - connect_msg.header.size = htons (msg_len); - connect_msg.header.type = - htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT); - connect_msg.reserved = htonl (0); - connect_msg.timestamp = - GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); - cc = GNUNET_malloc (sizeof (struct ContinutionContext)); - cc->session = n->session; - cc->address = GNUNET_HELLO_address_copy (address); - ret = send_with_session(n, - (const void *) &connect_msg, msg_len, - UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, - &send_switch_address_continuation, cc); - if (ret == GNUNET_SYSERR) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to send CONNECT_MESSAGE to `%4s' using address '%s' session %X\n", - GNUNET_i2s (peer), GST_plugins_a2s (address), session); - } - return GNUNET_NO; - default: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Invalid connection state to switch addresses %u \n", n->state); - GNUNET_break_op (0); - return GNUNET_NO; + GNUNET_break (0); + return; } + na->connect_timestamp = GNUNET_TIME_absolute_get (); + connect_msg.header.size = htons (sizeof (struct SessionConnectMessage)); + connect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT); + connect_msg.reserved = htonl (0); + connect_msg.timestamp = GNUNET_TIME_absolute_hton (na->connect_timestamp); + (void) papi->send (papi->cls, + na->session, + (const char *) &connect_msg, sizeof (struct SessionConnectMessage), + UINT_MAX, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, NULL); } /** - * Obtain current latency information for the given neighbour. - * - * @param peer - * @return observed latency of the address, FOREVER if the address was - * never successfully validated - */ -struct GNUNET_TIME_Relative -GST_neighbour_get_latency (const struct GNUNET_PeerIdentity *peer) -{ - struct NeighbourMapEntry *n; - - n = lookup_neighbour (peer); - if ((NULL == n) || ((n->address == NULL) && (n->session == NULL))) - return GNUNET_TIME_UNIT_FOREVER_REL; - - return n->latency; -} - -/** - * Obtain current address information for the given neighbour. + * Send a SESSION_CONNECT_ACK message via the given address. * - * @param peer - * @return address currently used + * @param address address to use + * @param session session to use + * @param timestamp timestamp to use for the ACK message */ -struct GNUNET_HELLO_Address * -GST_neighbour_get_current_address (const struct GNUNET_PeerIdentity *peer) +static void +send_session_connect_ack_message (const struct GNUNET_HELLO_Address *address, + struct Session *session, + struct GNUNET_TIME_Absolute timestamp) { - struct NeighbourMapEntry *n; - - n = lookup_neighbour (peer); - if ((NULL == n) || ((n->address == NULL) && (n->session == NULL))) - return NULL; - - return n->address; + struct GNUNET_TRANSPORT_PluginFunctions *papi; + struct SessionConnectMessage connect_msg; + + if (NULL == (papi = GST_plugins_find (address->transport_name))) + { + GNUNET_break (0); + return; + } + if (NULL == session) + session = papi->get_session (papi->cls, address); + if (NULL == session) + { + GNUNET_break (0); + return; + } + connect_msg.header.size = htons (sizeof (struct SessionConnectMessage)); + connect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT_ACK); + connect_msg.reserved = htonl (0); + connect_msg.timestamp = GNUNET_TIME_absolute_hton (timestamp); + (void) papi->send (papi->cls, + session, + (const char *) &connect_msg, sizeof (struct SessionConnectMessage), + UINT_MAX, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, NULL); } - /** - * Create an entry in the neighbour map for the given peer + * Create a fresh entry in the neighbour map for the given peer * * @param peer peer to create an entry for * @return new neighbour map entry @@ -1677,20 +1586,17 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer) { struct NeighbourMapEntry *n; -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Unknown peer `%s', creating new neighbour\n", GNUNET_i2s (peer)); -#endif + "Creating new neighbour entry for `%s'\n", + GNUNET_i2s (peer)); n = GNUNET_malloc (sizeof (struct NeighbourMapEntry)); n->id = *peer; n->state = S_NOT_CONNECTED; - n->latency = GNUNET_TIME_relative_get_forever (); + n->latency = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_BANDWIDTH_tracker_init (&n->in_tracker, GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, MAX_BANDWIDTH_CARRY_S); - n->timeout_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, - &neighbour_timeout_task, n); + n->task = GNUNET_SCHEDULER_add_now (&master_task, n); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (neighbours, &n->id.hashPubKey, n, @@ -1699,6 +1605,32 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer) } +/** + * Check if the two given addresses are the same. + * Actually only checks if the sessions are non-NULL + * (which they should be) and then if they are identical; + * the actual addresses don't matter if the session + * pointers match anyway, and we must have session pointers + * at this time. + * + * @param a1 first address to compare + * @param a2 other address to compare + * @return GNUNET_NO if the addresses do not match, GNUNET_YES if they do match + */ +static int +address_matches (const struct NeighbourAddress *a1, + const struct NeighbourAddress *a2) +{ + if ( (NULL == a1->session) || + (NULL == a2->session) ) + { + GNUNET_break (0); + return 0; + } + return (a1->session == a2->session) ? GNUNET_YES : GNUNET_NO; +} + + /** * Try to create a connection to the given target (eventually). * @@ -1709,665 +1641,1133 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) { struct NeighbourMapEntry *n; - // This can happen during shutdown - if (neighbours == NULL) - { - return; - } -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to peer `%s'\n", + if (NULL == neighbours) + return; /* during shutdown, do nothing */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Asked to connect to peer `%s'\n", GNUNET_i2s (target)); -#endif if (0 == memcmp (target, &GST_my_identity, sizeof (struct GNUNET_PeerIdentity))) { - /* my own hello */ + /* refuse to connect to myself */ + /* FIXME: can this happen? Is this not an API violation? */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Refusing to try to connect to myself.\n"); return; } n = lookup_neighbour (target); - if (NULL != n) { - if ((S_CONNECTED == n->state) || (is_connecting (n))) - return; /* already connecting or connected */ - if (is_disconnecting (n)) - change_state (n, S_NOT_CONNECTED); + switch (n->state) + { + case S_NOT_CONNECTED: + /* this should not be possible */ + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); + break; + case S_INIT_ATS: + case S_INIT_BLACKLIST: + case S_CONNECT_SENT: + case S_CONNECT_RECV_ATS: + case S_CONNECT_RECV_BLACKLIST: + case S_CONNECT_RECV_ACK: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Ignoring request to try to connect to `%s', already trying!\n", + GNUNET_i2s (target)); + return; /* already trying */ + case S_CONNECTED: + case S_RECONNECT_ATS: + case S_RECONNECT_BLACKLIST: + case S_RECONNECT_SENT: + case S_CONNECTED_SWITCHING_BLACKLIST: + case S_CONNECTED_SWITCHING_CONNECT_SENT: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Ignoring request to try to connect, already connected to `%s'!\n", + GNUNET_i2s (target)); + return; /* already connected */ + case S_DISCONNECT: + /* get rid of remains, ready to re-try immediately */ + free_neighbour (n, GNUNET_NO); + break; + case S_DISCONNECT_FINISHED: + /* should not be possible */ + GNUNET_assert (0); + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); + break; + } } + n = setup_neighbour (target); + n->state = S_INIT_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); - - if (n == NULL) - n = setup_neighbour (target); -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Asking ATS for suggested address to connect to peer `%s'\n", - GNUNET_i2s (&n->id)); -#endif - - GNUNET_ATS_suggest_address (GST_ats, &n->id); + GNUNET_ATS_reset_backoff (GST_ats, target); + GNUNET_ATS_suggest_address (GST_ats, target); } + /** - * Test if we're connected to the given peer. + * Function called with the result of a blacklist check. * - * @param target peer to test - * @return GNUNET_YES if we are connected, GNUNET_NO if not + * @param cls closure with the 'struct BlackListCheckContext' + * @param peer peer this check affects + * @param result GNUNET_OK if the address is allowed */ -int -GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target) +static void +handle_test_blacklist_cont (void *cls, + const struct GNUNET_PeerIdentity *peer, + int result) { + struct BlackListCheckContext *bcc = cls; struct NeighbourMapEntry *n; - // This can happen during shutdown - if (neighbours == NULL) + bcc->bc = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to new address of peer `%s' based on blacklist is `%s'\n", + GNUNET_i2s (peer), + (GNUNET_OK == result) ? "allowed" : "FORBIDDEN"); + if (GNUNET_OK == result) { - return GNUNET_NO; + /* valid new address, let ATS know! */ + GNUNET_ATS_address_update (GST_ats, + bcc->na.address, + bcc->na.session, + bcc->ats, bcc->ats_count); } - - n = lookup_neighbour (target); - - if ((NULL == n) || (S_CONNECTED != n->state)) - return GNUNET_NO; /* not connected */ - return GNUNET_YES; + if (NULL == (n = lookup_neighbour (peer))) + goto cleanup; /* nobody left to care about new address */ + switch (n->state) + { + case S_NOT_CONNECTED: + /* this should not be possible */ + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); + break; + case S_INIT_ATS: + /* still waiting on ATS suggestion */ + break; + case S_INIT_BLACKLIST: + /* check if the address the blacklist was fine with matches + ATS suggestion, if so, we can move on! */ + if ( (GNUNET_OK == result) && + (1 == n->send_connect_ack) ) + { + n->send_connect_ack = 2; + send_session_connect_ack_message (bcc->na.address, + bcc->na.session, + n->connect_ack_timestamp); + } + if (GNUNET_YES != address_matches (&bcc->na, &n->primary_address)) + break; /* result for an address we currently don't care about */ + if (GNUNET_OK == result) + { + n->timeout = GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT); + n->state = S_CONNECT_SENT; + send_session_connect (&n->primary_address); + } + else + { + // FIXME: should also possibly destroy session with plugin!? + GNUNET_ATS_address_destroyed (GST_ats, + bcc->na.address, + NULL); + free_address (&n->primary_address); + n->state = S_INIT_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + // FIXME: do we need to ask ATS again for suggestions? + GNUNET_ATS_suggest_address (GST_ats, &n->id); + } + break; + case S_CONNECT_SENT: + /* waiting on CONNECT_ACK, send ACK if one is pending */ + if ( (GNUNET_OK == result) && + (1 == n->send_connect_ack) ) + { + n->send_connect_ack = 2; + send_session_connect_ack_message (n->primary_address.address, + n->primary_address.session, + n->connect_ack_timestamp); + } + break; + case S_CONNECT_RECV_ATS: + /* still waiting on ATS suggestion, don't care about blacklist */ + break; + case S_CONNECT_RECV_BLACKLIST: + if (GNUNET_YES != address_matches (&bcc->na, &n->primary_address)) + break; /* result for an address we currently don't care about */ + if (GNUNET_OK == result) + { + n->timeout = GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT); + n->state = S_CONNECT_RECV_ACK; + send_session_connect_ack_message (bcc->na.address, + bcc->na.session, + n->connect_ack_timestamp); + if (1 == n->send_connect_ack) + n->send_connect_ack = 2; + } + else + { + // FIXME: should also possibly destroy session with plugin!? + GNUNET_ATS_address_destroyed (GST_ats, + bcc->na.address, + NULL); + free_address (&n->primary_address); + n->state = S_INIT_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + // FIXME: do we need to ask ATS again for suggestions? + GNUNET_ATS_reset_backoff (GST_ats, peer); + GNUNET_ATS_suggest_address (GST_ats, &n->id); + } + break; + case S_CONNECT_RECV_ACK: + /* waiting on SESSION_ACK, send ACK if one is pending */ + if ( (GNUNET_OK == result) && + (1 == n->send_connect_ack) ) + { + n->send_connect_ack = 2; + send_session_connect_ack_message (n->primary_address.address, + n->primary_address.session, + n->connect_ack_timestamp); + } + break; + case S_CONNECTED: + /* already connected, don't care about blacklist */ + break; + case S_RECONNECT_ATS: + /* still waiting on ATS suggestion, don't care about blacklist */ + break; + case S_RECONNECT_BLACKLIST: + if ( (GNUNET_OK == result) && + (1 == n->send_connect_ack) ) + { + n->send_connect_ack = 2; + send_session_connect_ack_message (bcc->na.address, + bcc->na.session, + n->connect_ack_timestamp); + } + if (GNUNET_YES != address_matches (&bcc->na, &n->primary_address)) + break; /* result for an address we currently don't care about */ + if (GNUNET_OK == result) + { + send_session_connect (&n->primary_address); + n->timeout = GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT); + n->state = S_RECONNECT_SENT; + } + else + { + GNUNET_ATS_address_destroyed (GST_ats, + bcc->na.address, + NULL); + n->state = S_RECONNECT_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + // FIXME: do we need to ask ATS again for suggestions? + GNUNET_ATS_suggest_address (GST_ats, &n->id); + } + break; + case S_RECONNECT_SENT: + /* waiting on CONNECT_ACK, don't care about blacklist */ + if ( (GNUNET_OK == result) && + (1 == n->send_connect_ack) ) + { + n->send_connect_ack = 2; + send_session_connect_ack_message (n->primary_address.address, + n->primary_address.session, + n->connect_ack_timestamp); + } + break; + case S_CONNECTED_SWITCHING_BLACKLIST: + if (GNUNET_YES != address_matches (&bcc->na, &n->alternative_address)) + break; /* result for an address we currently don't care about */ + if (GNUNET_OK == result) + { + send_session_connect (&n->alternative_address); + n->state = S_CONNECTED_SWITCHING_CONNECT_SENT; + } + else + { + GNUNET_ATS_address_destroyed (GST_ats, + bcc->na.address, + NULL); + free_address (&n->alternative_address); + n->state = S_CONNECTED; + } + break; + case S_CONNECTED_SWITCHING_CONNECT_SENT: + /* waiting on CONNECT_ACK, don't care about blacklist */ + if ( (GNUNET_OK == result) && + (1 == n->send_connect_ack) ) + { + n->send_connect_ack = 2; + send_session_connect_ack_message (n->primary_address.address, + n->primary_address.session, + n->connect_ack_timestamp); + } + break; + case S_DISCONNECT: + /* Nothing to do here, ATS will already do what can be done */ + break; + case S_DISCONNECT_FINISHED: + /* should not be possible */ + GNUNET_assert (0); + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); + break; + } + cleanup: + GNUNET_HELLO_address_free (bcc->na.address); + GNUNET_CONTAINER_DLL_remove (bc_head, + bc_tail, + bcc); + GNUNET_free (bcc); } + /** - * A session was terminated. Take note. + * We want to know if connecting to a particular peer via + * a particular address is allowed. Check it! * - * @param peer identity of the peer where the session died - * @param session session that is gone + * @param peer identity of the peer to switch the address for + * @param ts time at which the check was initiated + * @param address address of the other peer, NULL if other peer + * connected to us + * @param session session to use (or NULL) + * @param ats performance data + * @param ats_count number of entries in ats (excluding 0-termination) */ -void -GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, - struct Session *session) +static void +check_blacklist (const struct GNUNET_PeerIdentity *peer, + struct GNUNET_TIME_Absolute ts, + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) { - struct NeighbourMapEntry *n; + struct BlackListCheckContext *bcc; + struct GST_BlacklistCheck *bc; - if (neighbours == NULL) - { - /* This can happen during shutdown */ - return; - } - -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %X to peer `%s' ended \n", - session, GNUNET_i2s (peer)); -#endif - - n = lookup_neighbour (peer); - if (NULL == n) - return; - if (session != n->session) - return; /* doesn't affect us */ - if (n->state == S_CONNECTED) - { - if (n->address_state == USED) - { - GST_validation_set_address_use (n->address, n->session, GNUNET_NO); - GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO); - n->address_state = UNUSED; - } - } - - if (NULL != n->address) - { - GNUNET_HELLO_address_free (n->address); - n->address = NULL; - } - n->session = NULL; - - /* not connected anymore anyway, shouldn't matter */ - if (S_CONNECTED != n->state) - return; - - if (n->keepalive_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (n->keepalive_task); - n->keepalive_task = GNUNET_SCHEDULER_NO_TASK; - n->expect_latency_response = GNUNET_NO; - } - - /* connected, try fast reconnect */ - /* statistics "transport" : "# peers connected" -= 1 - * neighbours_connected -= 1 - * BUT: no disconnect_cb to notify clients about disconnect - */ - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying fast reconnect to peer `%s'\n", - GNUNET_i2s (peer)); - - GNUNET_assert (neighbours_connected > 0); - change_state (n, S_FAST_RECONNECT); - neighbours_connected--; - GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), -1, - GNUNET_NO); - - - /* We are connected, so ask ATS to switch addresses */ - GNUNET_SCHEDULER_cancel (n->timeout_task); - n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT, - &neighbour_timeout_task, n); - /* try QUICKLY to re-establish a connection, reduce timeout! */ - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, - &ats_suggest_cancel, - n); - GNUNET_ATS_suggest_address (GST_ats, peer); -} - - -/** - * Transmit a message to the given target using the active connection. - * - * @param target destination - * @param msg message to send - * @param msg_size number of bytes in msg - * @param timeout when to fail with timeout - * @param cont function to call when done - * @param cont_cls closure for 'cont' - */ -void -GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, - size_t msg_size, struct GNUNET_TIME_Relative timeout, - GST_NeighbourSendContinuation cont, void *cont_cls) -{ - struct NeighbourMapEntry *n; - struct MessageQueue *mq; - - // This can happen during shutdown - if (neighbours == NULL) - { - return; - } - - n = lookup_neighbour (target); - if ((n == NULL) || (!is_connected (n))) - { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# messages not sent (no such peer or not connected)"), - 1, GNUNET_NO); -#if DEBUG_TRANSPORT - if (n == NULL) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Could not send message to peer `%s': unknown neighbour", - GNUNET_i2s (target)); - else if (!is_connected (n)) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Could not send message to peer `%s': not connected\n", - GNUNET_i2s (target)); -#endif - if (NULL != cont) - cont (cont_cls, GNUNET_SYSERR); - return; - } - - if ((n->session == NULL) && (n->address == NULL)) - { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# messages not sent (no such peer or not connected)"), - 1, GNUNET_NO); -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Could not send message to peer `%s': no address available\n", - GNUNET_i2s (target)); -#endif - - if (NULL != cont) - cont (cont_cls, GNUNET_SYSERR); - return; - } - - GNUNET_assert (msg_size >= sizeof (struct GNUNET_MessageHeader)); - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# bytes in message queue for other peers"), - msg_size, GNUNET_NO); - mq = GNUNET_malloc (sizeof (struct MessageQueue) + msg_size); - mq->cont = cont; - mq->cont_cls = cont_cls; - /* FIXME: this memcpy can be up to 7% of our total runtime! */ - memcpy (&mq[1], msg, msg_size); - mq->message_buf = (const char *) &mq[1]; - mq->message_buf_size = msg_size; - mq->timeout = GNUNET_TIME_relative_to_absolute (timeout); - GNUNET_CONTAINER_DLL_insert_tail (n->messages_head, n->messages_tail, mq); - - if ((GNUNET_SCHEDULER_NO_TASK == n->transmission_task) && - (NULL == n->is_active)) - n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n); -} + bcc = + GNUNET_malloc (sizeof (struct BlackListCheckContext) + + sizeof (struct GNUNET_ATS_Information) * ats_count); + bcc->ats_count = ats_count; + bcc->na.address = GNUNET_HELLO_address_copy (address); + bcc->na.session = session; + bcc->na.connect_timestamp = ts; + bcc->ats = (struct GNUNET_ATS_Information *) &bcc[1]; + memcpy (bcc->ats, ats, sizeof (struct GNUNET_ATS_Information) * ats_count); + GNUNET_CONTAINER_DLL_insert (bc_head, + bc_tail, + bcc); + if (NULL != (bc = GST_blacklist_test_allowed (peer, + address->transport_name, + &handle_test_blacklist_cont, bcc))) + bcc->bc = bc; + /* if NULL == bc, 'cont' was already called and 'bcc' already free'd, so + we must only store 'bc' if 'bc' is non-NULL... */ +} /** - * We have received a message from the given sender. How long should - * we delay before receiving more? (Also used to keep the peer marked - * as live). - * - * @param sender sender of the message - * @param size size of the message - * @param do_forward set to GNUNET_YES if the message should be forwarded to clients - * GNUNET_NO if the neighbour is not connected or violates the quota, - * GNUNET_SYSERR if the connection is not fully up yet - * @return how long to wait before reading more from this sender - */ -struct GNUNET_TIME_Relative -GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity - *sender, ssize_t size, int *do_forward) -{ - struct NeighbourMapEntry *n; - struct GNUNET_TIME_Relative ret; - - // This can happen during shutdown - if (neighbours == NULL) - { - return GNUNET_TIME_UNIT_FOREVER_REL; - } - - n = lookup_neighbour (sender); - if (n == NULL) - { - GST_neighbours_try_connect (sender); - n = lookup_neighbour (sender); - if (NULL == n) - { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# messages discarded due to lack of neighbour record"), - 1, GNUNET_NO); - *do_forward = GNUNET_NO; - return GNUNET_TIME_UNIT_ZERO; - } - } - if (!is_connected (n)) - { - *do_forward = GNUNET_SYSERR; - return GNUNET_TIME_UNIT_ZERO; - } - if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, size)) - { - n->quota_violation_count++; -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Bandwidth quota (%u b/s) violation detected (total of %u).\n", - n->in_tracker.available_bytes_per_s__, - n->quota_violation_count); -#endif - /* Discount 32k per violation */ - GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, -32 * 1024); - } - else - { - if (n->quota_violation_count > 0) - { - /* try to add 32k back */ - GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, 32 * 1024); - n->quota_violation_count--; - } - } - if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD) - { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# bandwidth quota violations by other peers"), - 1, GNUNET_NO); - *do_forward = GNUNET_NO; - return GNUNET_CONSTANTS_QUOTA_VIOLATION_TIMEOUT; - } - *do_forward = GNUNET_YES; - ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 32 * 1024); - if (ret.rel_value > 0) - { -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Throttling read (%llu bytes excess at %u b/s), waiting %llu ms before reading more.\n", - (unsigned long long) n->in_tracker. - consumption_since_last_update__, - (unsigned int) n->in_tracker.available_bytes_per_s__, - (unsigned long long) ret.rel_value); -#endif - GNUNET_STATISTICS_update (GST_stats, - gettext_noop ("# ms throttling suggested"), - (int64_t) ret.rel_value, GNUNET_NO); - } - return ret; -} - - -/** - * Keep the connection to the given neighbour alive longer, - * we received a KEEPALIVE (or equivalent). + * We received a 'SESSION_CONNECT' message from the other peer. + * Consider switching to it. * - * @param neighbour neighbour to keep alive + * @param message possibly a 'struct SessionConnectMessage' (check format) + * @param peer identity of the peer to switch the address for + * @param address address of the other peer, NULL if other peer + * connected to us + * @param session session to use (or NULL) + * @param ats performance data + * @param ats_count number of entries in ats (excluding 0-termination) */ void -GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour) +GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) { + const struct SessionConnectMessage *scm; struct NeighbourMapEntry *n; + struct GNUNET_TIME_Absolute ts; - // This can happen during shutdown - if (neighbours == NULL) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received CONNECT message from peer `%s'\n", + GNUNET_i2s (peer)); + if (ntohs (message->size) != sizeof (struct SessionConnectMessage)) { + GNUNET_break_op (0); return; } - - n = lookup_neighbour (neighbour); + if (NULL == neighbours) + return; /* we're shutting down */ + scm = (const struct SessionConnectMessage *) message; + GNUNET_break_op (0 == ntohl (scm->reserved)); + ts = GNUNET_TIME_absolute_ntoh (scm->timestamp); + n = lookup_neighbour (peer); if (NULL == n) - { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# KEEPALIVE messages discarded (not connected)"), - 1, GNUNET_NO); - return; + n = setup_neighbour (peer); + n->send_connect_ack = 1; + n->connect_ack_timestamp = ts; + switch (n->state) + { + case S_NOT_CONNECTED: + n->state = S_CONNECT_RECV_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + GNUNET_ATS_reset_backoff (GST_ats, peer); + GNUNET_ATS_suggest_address (GST_ats, peer); + check_blacklist (peer, ts, address, session, ats, ats_count); + break; + case S_INIT_ATS: + case S_INIT_BLACKLIST: + case S_CONNECT_SENT: + case S_CONNECT_RECV_ATS: + case S_CONNECT_RECV_BLACKLIST: + case S_CONNECT_RECV_ACK: + /* It can never hurt to have an alternative address in the above cases, + see if it is allowed */ + check_blacklist (peer, ts, address, session, ats, ats_count); + break; + case S_CONNECTED: + /* we are already connected and can thus send the ACK immediately; + still, it can never hurt to have an alternative address, so also + tell ATS about it */ + GNUNET_assert (NULL != n->primary_address.address); + GNUNET_assert (NULL != n->primary_address.session); + n->send_connect_ack = 0; + send_session_connect_ack_message (n->primary_address.address, + n->primary_address.session, ts); + check_blacklist (peer, ts, address, session, ats, ats_count); + break; + case S_RECONNECT_ATS: + case S_RECONNECT_BLACKLIST: + case S_RECONNECT_SENT: + /* It can never hurt to have an alternative address in the above cases, + see if it is allowed */ + check_blacklist (peer, ts, address, session, ats, ats_count); + break; + case S_CONNECTED_SWITCHING_BLACKLIST: + case S_CONNECTED_SWITCHING_CONNECT_SENT: + /* we are already connected and can thus send the ACK immediately; + still, it can never hurt to have an alternative address, so also + tell ATS about it */ + GNUNET_assert (NULL != n->primary_address.address); + GNUNET_assert (NULL != n->primary_address.session); + n->send_connect_ack = 0; + send_session_connect_ack_message (n->primary_address.address, + n->primary_address.session, ts); + check_blacklist (peer, ts, address, session, ats, ats_count); + break; + case S_DISCONNECT: + /* get rid of remains without terminating sessions, ready to re-try */ + free_neighbour (n, GNUNET_YES); + n = setup_neighbour (peer); + n->state = S_CONNECT_RECV_ATS; + GNUNET_ATS_reset_backoff (GST_ats, peer); + GNUNET_ATS_suggest_address (GST_ats, peer); + break; + case S_DISCONNECT_FINISHED: + /* should not be possible */ + GNUNET_assert (0); + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); + break; } - GNUNET_SCHEDULER_cancel (n->timeout_task); - n->timeout_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, - &neighbour_timeout_task, n); - - /* send reply to measure latency */ - if (S_CONNECTED != n->state) - return; - - struct GNUNET_MessageHeader m; - - m.size = htons (sizeof (struct GNUNET_MessageHeader)); - m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE); - - send_with_session(n, - (const void *) &m, sizeof (m), - UINT32_MAX, - GNUNET_TIME_UNIT_FOREVER_REL, - NULL, NULL); } + /** - * We received a KEEP_ALIVE_RESPONSE message and use this to calculate latency - * to this peer + * For an existing neighbour record, set the active connection to + * use the given address. * - * @param neighbour neighbour to keep alive + * @param peer identity of the peer to switch the address for + * @param address address of the other peer, NULL if other peer + * connected to us + * @param session session to use (or NULL) * @param ats performance data * @param ats_count number of entries in ats + * @param bandwidth_in inbound quota to be used when connection is up + * @param bandwidth_out outbound quota to be used when connection is up */ void -GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) +GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count, + struct GNUNET_BANDWIDTH_Value32NBO + bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO + bandwidth_out) { struct NeighbourMapEntry *n; - struct GNUNET_ATS_Information *ats_new; - uint32_t latency; + struct GNUNET_TRANSPORT_PluginFunctions *papi; - if (neighbours == NULL) - { - // This can happen during shutdown + GNUNET_assert (address->transport_name != NULL); + if (NULL == (n = lookup_neighbour (peer))) return; - } - n = lookup_neighbour (neighbour); - if ((NULL == n) || (n->state != S_CONNECTED)) + /* Obtain an session for this address from plugin */ + if (NULL == (papi = GST_plugins_find (address->transport_name))) { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# KEEPALIVE_RESPONSE messages discarded (not connected)"), - 1, GNUNET_NO); + /* we don't have the plugin for this address */ + GNUNET_ATS_address_destroyed (GST_ats, address, NULL); return; } - if (n->expect_latency_response != GNUNET_YES) + if ((NULL == session) && (0 == address->address_length)) { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# KEEPALIVE_RESPONSE messages discarded (not expected)"), - 1, GNUNET_NO); + GNUNET_break (0); + if (strlen (address->transport_name) > 0) + GNUNET_ATS_address_destroyed (GST_ats, address, session); return; } - n->expect_latency_response = GNUNET_NO; - - GNUNET_assert (n->keep_alive_sent.abs_value != - GNUNET_TIME_absolute_get_zero ().abs_value); - n->latency = - GNUNET_TIME_absolute_get_difference (n->keep_alive_sent, - GNUNET_TIME_absolute_get ()); -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Latency for peer `%s' is %llu ms\n", - GNUNET_i2s (&n->id), n->latency.rel_value); -#endif - - - if (n->latency.rel_value == GNUNET_TIME_relative_get_forever ().rel_value) - { - GNUNET_ATS_address_update (GST_ats, n->address, n->session, ats, ats_count); - } - else - { - ats_new = - GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) * - (ats_count + 1)); - memcpy (ats_new, ats, sizeof (struct GNUNET_ATS_Information) * ats_count); - - /* add latency */ - ats_new[ats_count].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); - if (n->latency.rel_value > UINT32_MAX) - latency = UINT32_MAX; - else - latency = n->latency.rel_value; - ats_new[ats_count].value = htonl (latency); - - GNUNET_ATS_address_update (GST_ats, n->address, n->session, ats_new, - ats_count + 1); - GNUNET_free (ats_new); - } -} - - -/** - * Change the incoming quota for the given peer. - * - * @param neighbour identity of peer to change qutoa for - * @param quota new quota - */ -void -GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour, - struct GNUNET_BANDWIDTH_Value32NBO quota) -{ - struct NeighbourMapEntry *n; - - // This can happen during shutdown - if (neighbours == NULL) + if (NULL == session) + session = papi->get_session (papi->cls, address); + if (NULL == session) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Failed to obtain new session for peer `%s' and address '%s'\n", + GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); + GNUNET_ATS_address_destroyed (GST_ats, address, NULL); return; } - - n = lookup_neighbour (neighbour); - if (n == NULL) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "ATS tells us to switch to address '%s' for peer `%s'\n", + (address->address_length != 0) ? GST_plugins_a2s (address): "", + GNUNET_i2s (peer)); + switch (n->state) { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# SET QUOTA messages ignored (no such peer)"), - 1, GNUNET_NO); + case S_NOT_CONNECTED: + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); return; - } -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Setting inbound quota of %u Bps for peer `%s' to all clients\n", - ntohl (quota.value__), GNUNET_i2s (&n->id)); -#endif - GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, quota); - if (0 != ntohl (quota.value__)) + case S_INIT_ATS: + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->state = S_INIT_BLACKLIST; + n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); + check_blacklist (&n->id, + n->connect_ack_timestamp, + address, session, ats, ats_count); + break; + case S_INIT_BLACKLIST: + /* ATS suggests a different address, switch again */ + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); + check_blacklist (&n->id, + n->connect_ack_timestamp, + address, session, ats, ats_count); + break; + case S_CONNECT_SENT: + /* ATS suggests a different address, switch again */ + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->state = S_INIT_BLACKLIST; + n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); + check_blacklist (&n->id, + n->connect_ack_timestamp, + address, session, ats, ats_count); + break; + case S_CONNECT_RECV_ATS: + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->state = S_CONNECT_RECV_BLACKLIST; + n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); + check_blacklist (&n->id, + n->connect_ack_timestamp, + address, session, ats, ats_count); + break; + case S_CONNECT_RECV_BLACKLIST: + case S_CONNECT_RECV_ACK: + /* ATS asks us to switch while we were trying to connect; switch to new + address and check blacklist again */ + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); + check_blacklist (&n->id, + n->connect_ack_timestamp, + address, session, ats, ats_count); + break; + case S_CONNECTED: + GNUNET_assert (NULL != n->primary_address.address); + GNUNET_assert (NULL != n->primary_address.session); + if (n->primary_address.session == session) + { + /* not an address change, just a quota change */ + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_YES); + break; + } + /* ATS asks us to switch a life connection; see if we can get + a CONNECT_ACK on it before we actually do this! */ + set_address (&n->alternative_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->state = S_CONNECTED_SWITCHING_BLACKLIST; + check_blacklist (&n->id, + GNUNET_TIME_absolute_get (), + address, session, ats, ats_count); + break; + case S_RECONNECT_ATS: + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->state = S_RECONNECT_BLACKLIST; + n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); + check_blacklist (&n->id, + n->connect_ack_timestamp, + address, session, ats, ats_count); + break; + case S_RECONNECT_BLACKLIST: + /* ATS asks us to switch while we were trying to reconnect; switch to new + address and check blacklist again */ + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); + check_blacklist (&n->id, + n->connect_ack_timestamp, + address, session, ats, ats_count); + break; + case S_RECONNECT_SENT: + /* ATS asks us to switch while we were trying to reconnect; switch to new + address and check blacklist again */ + set_address (&n->primary_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->state = S_RECONNECT_BLACKLIST; + n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); + check_blacklist (&n->id, + n->connect_ack_timestamp, + address, session, ats, ats_count); + break; + case S_CONNECTED_SWITCHING_BLACKLIST: + if (n->primary_address.session == session) + { + /* ATS switches back to still-active session */ + free_address (&n->alternative_address); + n->state = S_CONNECTED; + break; + } + /* ATS asks us to switch a life connection, update blacklist check */ + set_address (&n->alternative_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + check_blacklist (&n->id, + GNUNET_TIME_absolute_get (), + address, session, ats, ats_count); + break; + case S_CONNECTED_SWITCHING_CONNECT_SENT: + if (n->primary_address.session == session) + { + /* ATS switches back to still-active session */ + free_address (&n->alternative_address); + n->state = S_CONNECTED; + break; + } + /* ATS asks us to switch a life connection, update blacklist check */ + set_address (&n->alternative_address, + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); + n->state = S_CONNECTED_SWITCHING_BLACKLIST; + check_blacklist (&n->id, + GNUNET_TIME_absolute_get (), + address, session, ats, ats_count); + break; + case S_DISCONNECT: + /* not going to switch addresses while disconnecting */ return; -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s' due to `%s'\n", - GNUNET_i2s (&n->id), "SET_QUOTA"); -#endif - if (is_connected (n)) - GNUNET_STATISTICS_update (GST_stats, - gettext_noop ("# disconnects due to quota of 0"), - 1, GNUNET_NO); - disconnect_neighbour (n); + case S_DISCONNECT_FINISHED: + GNUNET_assert (0); + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + break; + } } /** - * Closure for the neighbours_iterate function. - */ -struct IteratorContext -{ - /** - * Function to call on each connected neighbour. - */ - GST_NeighbourIterator cb; - - /** - * Closure for 'cb'. - */ - void *cb_cls; -}; - - -/** - * Call the callback from the closure for each connected neighbour. + * Master task run for every neighbour. Performs all of the time-related + * activities (keep alive, send next message, disconnect if idle, finish + * clean up after disconnect). * - * @param cls the 'struct IteratorContext' - * @param key the hash of the public key of the neighbour - * @param value the 'struct NeighbourMapEntry' - * @return GNUNET_OK (continue to iterate) + * @param cls the 'struct NeighbourMapEntry' for which we are running + * @param tc scheduler context (unused) */ -static int -neighbours_iterate (void *cls, const GNUNET_HashCode * key, void *value) +static void +master_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct IteratorContext *ic = cls; - struct NeighbourMapEntry *n = value; - - if (!is_connected (n)) - return GNUNET_OK; + struct NeighbourMapEntry *n = cls; + struct GNUNET_TIME_Relative delay; - ic->cb (ic->cb_cls, &n->id, NULL, 0, n->address); - return GNUNET_OK; + n->task = GNUNET_SCHEDULER_NO_TASK; + delay = GNUNET_TIME_absolute_get_remaining (n->timeout); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "master task runs for neighbour `%s' in state %d with timeout in %llu ms\n", + GNUNET_i2s (&n->id), + n->state, + (unsigned long long) delay.rel_value); + switch (n->state) + { + case S_NOT_CONNECTED: + /* invalid state for master task, clean up */ + GNUNET_break (0); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + case S_INIT_ATS: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out waiting for ATS to provide address\n", + GNUNET_i2s (&n->id)); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + } + break; + case S_INIT_BLACKLIST: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out waiting for BLACKLIST to approve address\n", + GNUNET_i2s (&n->id)); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + } + break; + case S_CONNECT_SENT: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out waiting for other peer to send CONNECT_ACK\n", + GNUNET_i2s (&n->id)); + disconnect_neighbour (n); + return; + } + break; + case S_CONNECT_RECV_ATS: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out waiting ATS to provide address to use for CONNECT_ACK\n", + GNUNET_i2s (&n->id)); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + } + break; + case S_CONNECT_RECV_BLACKLIST: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out waiting BLACKLIST to approve address to use for CONNECT_ACK\n", + GNUNET_i2s (&n->id)); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + } + break; + case S_CONNECT_RECV_ACK: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out waiting for other peer to send SESSION_ACK\n", + GNUNET_i2s (&n->id)); + disconnect_neighbour (n); + return; + } + break; + case S_CONNECTED: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs\n", + GNUNET_i2s (&n->id)); + disconnect_neighbour (n); + return; + } + try_transmission_to_peer (n); + send_keepalive (n); + break; + case S_RECONNECT_ATS: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out, waiting for ATS replacement address\n", + GNUNET_i2s (&n->id)); + disconnect_neighbour (n); + return; + } + break; + case S_RECONNECT_BLACKLIST: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out, waiting for BLACKLIST to approve replacement address\n", + GNUNET_i2s (&n->id)); + disconnect_neighbour (n); + return; + } + break; + case S_RECONNECT_SENT: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out, waiting for other peer to CONNECT_ACK replacement address\n", + GNUNET_i2s (&n->id)); + disconnect_neighbour (n); + return; + } + break; + case S_CONNECTED_SWITCHING_BLACKLIST: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs\n", + GNUNET_i2s (&n->id)); + disconnect_neighbour (n); + return; + } + try_transmission_to_peer (n); + send_keepalive (n); + break; + case S_CONNECTED_SWITCHING_CONNECT_SENT: + if (0 == delay.rel_value) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs (after trying to CONNECT on alternative address)\n", + GNUNET_i2s (&n->id)); + disconnect_neighbour (n); + return; + } + try_transmission_to_peer (n); + send_keepalive (n); + break; + case S_DISCONNECT: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Cleaning up connection to `%s' after sending DISCONNECT\n", + GNUNET_i2s (&n->id)); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return; + case S_DISCONNECT_FINISHED: + /* how did we get here!? */ + GNUNET_assert (0); + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + break; + } + if ( (S_CONNECTED_SWITCHING_CONNECT_SENT == n->state) || + (S_CONNECTED_SWITCHING_BLACKLIST == n->state) || + (S_CONNECTED == n->state) ) + { + /* if we are *now* in one of these three states, we're sending + keep alive messages, so we need to consider the keepalive + delay, not just the connection timeout */ + delay = GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining (n->keep_alive_time), + delay); + } + if (GNUNET_SCHEDULER_NO_TASK == n->task) + n->task = GNUNET_SCHEDULER_add_delayed (delay, + &master_task, + n); } /** - * Iterate over all connected neighbours. + * Send a SESSION_ACK message to the neighbour to confirm that we + * got his CONNECT_ACK. * - * @param cb function to call - * @param cb_cls closure for cb + * @param n neighbour to send the SESSION_ACK to */ -void -GST_neighbours_iterate (GST_NeighbourIterator cb, void *cb_cls) +static void +send_session_ack_message (struct NeighbourMapEntry *n) { - struct IteratorContext ic; - - // This can happen during shutdown - if (neighbours == NULL) - { - return; - } + struct GNUNET_MessageHeader msg; - ic.cb = cb; - ic.cb_cls = cb_cls; - GNUNET_CONTAINER_multihashmap_iterate (neighbours, &neighbours_iterate, &ic); + msg.size = htons (sizeof (struct GNUNET_MessageHeader)); + msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK); + (void) send_with_session(n, + (const char *) &msg, sizeof (struct GNUNET_MessageHeader), + UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, + NULL, NULL); } + /** - * If we have an active connection to the given target, it must be shutdown. + * We received a 'SESSION_CONNECT_ACK' message from the other peer. + * Consider switching to it. * - * @param target peer to disconnect from + * @param message possibly a 'struct SessionConnectMessage' (check format) + * @param peer identity of the peer to switch the address for + * @param address address of the other peer, NULL if other peer + * connected to us + * @param session session to use (or NULL) + * @param ats performance data + * @param ats_count number of entries in ats */ void -GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) +GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) { + const struct SessionConnectMessage *scm; + struct GNUNET_TIME_Absolute ts; struct NeighbourMapEntry *n; - // This can happen during shutdown - if (neighbours == NULL) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received CONNECT_ACK message from peer `%s'\n", + GNUNET_i2s (peer)); + if (ntohs (message->size) != sizeof (struct SessionConnectMessage)) { + GNUNET_break_op (0); return; } - - n = lookup_neighbour (target); - if (NULL == n) - return; /* not active */ - disconnect_neighbour (n); + scm = (const struct SessionConnectMessage *) message; + GNUNET_break_op (ntohl (scm->reserved) == 0); + if (NULL == (n = lookup_neighbour (peer))) + { + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# unexpected CONNECT_ACK messages (no peer)"), + 1, GNUNET_NO); + return; + } + ts = GNUNET_TIME_absolute_ntoh (scm->timestamp); + switch (n->state) + { + case S_NOT_CONNECTED: + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); + return; + case S_INIT_ATS: + case S_INIT_BLACKLIST: + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# unexpected CONNECT_ACK messages (not ready)"), + 1, GNUNET_NO); + break; + case S_CONNECT_SENT: + if (ts.abs_value != n->primary_address.connect_timestamp.abs_value) + break; /* ACK does not match our original CONNECT message */ + n->state = S_CONNECTED; + n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); + GNUNET_STATISTICS_set (GST_stats, + gettext_noop ("# peers connected"), + ++neighbours_connected, + GNUNET_NO); + connect_notify_cb (callback_cls, &n->id, ats, ats_count); + set_address (&n->primary_address, + n->primary_address.address, + n->primary_address.session, + n->primary_address.bandwidth_in, + n->primary_address.bandwidth_out, + GNUNET_YES); + send_session_ack_message (n); + break; + case S_CONNECT_RECV_ATS: + case S_CONNECT_RECV_BLACKLIST: + case S_CONNECT_RECV_ACK: + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# unexpected CONNECT_ACK messages (not ready)"), + 1, GNUNET_NO); + break; + case S_CONNECTED: + /* duplicate CONNECT_ACK, let's answer by duplciate SESSION_ACK just in case */ + send_session_ack_message (n); + break; + case S_RECONNECT_ATS: + case S_RECONNECT_BLACKLIST: + /* we didn't expect any CONNECT_ACK, as we are waiting for ATS + to give us a new address... */ + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# unexpected CONNECT_ACK messages (waiting on ATS)"), + 1, GNUNET_NO); + break; + case S_RECONNECT_SENT: + /* new address worked; go back to connected! */ + n->state = S_CONNECTED; + send_session_ack_message (n); + break; + case S_CONNECTED_SWITCHING_BLACKLIST: + /* duplicate CONNECT_ACK, let's answer by duplciate SESSION_ACK just in case */ + send_session_ack_message (n); + break; + case S_CONNECTED_SWITCHING_CONNECT_SENT: + /* new address worked; adopt it and go back to connected! */ + n->state = S_CONNECTED; + n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); + GNUNET_break (GNUNET_NO == n->alternative_address.ats_active); + set_address (&n->primary_address, + n->alternative_address.address, + n->alternative_address.session, + n->alternative_address.bandwidth_in, + n->alternative_address.bandwidth_out, + GNUNET_YES); + free_address (&n->alternative_address); + send_session_ack_message (n); + break; + case S_DISCONNECT: + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# unexpected CONNECT_ACK messages (disconnecting)"), + 1, GNUNET_NO); + break; + case S_DISCONNECT_FINISHED: + GNUNET_assert (0); + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + break; + } } /** - * We received a disconnect message from the given peer, - * validate and process. + * A session was terminated. Take note; if needed, try to get + * an alternative address from ATS. * - * @param peer sender of the message - * @param msg the disconnect message + * @param peer identity of the peer where the session died + * @param session session that is gone */ void -GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity - *peer, - const struct GNUNET_MessageHeader - *msg) +GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, + struct Session *session) { struct NeighbourMapEntry *n; - const struct SessionDisconnectMessage *sdm; - GNUNET_HashCode hc; + struct BlackListCheckContext *bcc; + struct BlackListCheckContext *bcc_next; -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received DISCONNECT message from peer `%s'\n", - GNUNET_i2s (peer)); -#endif - - if (ntohs (msg->size) != sizeof (struct SessionDisconnectMessage)) + /* make sure to cancel all ongoing blacklist checks involving 'session' */ + bcc_next = bc_head; + while (NULL != (bcc = bcc_next)) { - // GNUNET_break_op (0); - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# disconnect messages ignored (old format)"), 1, - GNUNET_NO); - return; + bcc_next = bcc->next; + if (bcc->na.session == session) + { + GST_blacklist_test_cancel (bcc->bc); + GNUNET_HELLO_address_free (bcc->na.address); + GNUNET_CONTAINER_DLL_remove (bc_head, + bc_tail, + bcc); + GNUNET_free (bcc); + } } - sdm = (const struct SessionDisconnectMessage *) msg; - n = lookup_neighbour (peer); - if (NULL == n) - return; /* gone already */ - if (GNUNET_TIME_absolute_ntoh (sdm->timestamp).abs_value <= - n->connect_ts.abs_value) + if (NULL == (n = lookup_neighbour (peer))) + return; /* can't affect us */ + if (session != n->primary_address.session) { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# disconnect messages ignored (timestamp)"), 1, - GNUNET_NO); - return; + if (session == n->alternative_address.session) + { + free_address (&n->alternative_address); + if ( (S_CONNECTED_SWITCHING_BLACKLIST == n->state) || + (S_CONNECTED_SWITCHING_CONNECT_SENT == n->state) ) + n->state = S_CONNECTED; + else + GNUNET_break (0); + } + return; /* doesn't affect us further */ } - GNUNET_CRYPTO_hash (&sdm->public_key, - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &hc); - if (0 != memcmp (peer, &hc, sizeof (struct GNUNET_PeerIdentity))) + + n->expect_latency_response = GNUNET_NO; + + switch (n->state) { - GNUNET_break_op (0); + case S_NOT_CONNECTED: + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); return; - } - if (ntohl (sdm->purpose.size) != - sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + - sizeof (struct GNUNET_TIME_AbsoluteNBO)) - { - GNUNET_break_op (0); + case S_INIT_ATS: + GNUNET_break (0); + free_neighbour (n, GNUNET_NO); return; - } - if (GNUNET_OK != - GNUNET_CRYPTO_rsa_verify - (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT, &sdm->purpose, - &sdm->signature, &sdm->public_key)) - { - GNUNET_break_op (0); + case S_INIT_BLACKLIST: + case S_CONNECT_SENT: + free_address (&n->primary_address); + n->state = S_INIT_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + // FIXME: need to ask ATS for suggestions again? + GNUNET_ATS_suggest_address (GST_ats, &n->id); + break; + case S_CONNECT_RECV_ATS: + case S_CONNECT_RECV_BLACKLIST: + case S_CONNECT_RECV_ACK: + /* error on inbound session; free neighbour entirely */ + free_address (&n->primary_address); + free_neighbour (n, GNUNET_NO); return; + case S_CONNECTED: + free_address (&n->primary_address); + n->state = S_RECONNECT_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + /* FIXME: is this ATS call needed? */ + GNUNET_ATS_suggest_address (GST_ats, &n->id); + break; + case S_RECONNECT_ATS: + /* we don't have an address, how can it go down? */ + GNUNET_break (0); + break; + case S_RECONNECT_BLACKLIST: + case S_RECONNECT_SENT: + n->state = S_RECONNECT_ATS; + n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + // FIXME: need to ask ATS for suggestions again? + GNUNET_ATS_suggest_address (GST_ats, &n->id); + break; + case S_CONNECTED_SWITCHING_BLACKLIST: + /* primary went down while we were checking secondary against + blacklist, adopt secondary as primary */ + free_address (&n->primary_address); + n->primary_address = n->alternative_address; + memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress)); + n->timeout = GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT); + n->state = S_RECONNECT_BLACKLIST; + break; + case S_CONNECTED_SWITCHING_CONNECT_SENT: + /* primary went down while we were waiting for CONNECT_ACK on secondary; + secondary as primary */ + free_address (&n->primary_address); + n->primary_address = n->alternative_address; + memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress)); + n->timeout = GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT); + n->state = S_RECONNECT_SENT; + break; + case S_DISCONNECT: + free_address (&n->primary_address); + break; + case S_DISCONNECT_FINISHED: + /* neighbour was freed and plugins told to terminate session */ + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + break; } - GST_neighbours_force_disconnect (peer); + if (GNUNET_SCHEDULER_NO_TASK != n->task) + GNUNET_SCHEDULER_cancel (n->task); + n->task = GNUNET_SCHEDULER_add_now (&master_task, n); } /** - * We received a 'SESSION_CONNECT_ACK' message from the other peer. - * Consider switching to it. + * We received a 'SESSION_ACK' message from the other peer. + * If we sent a 'CONNECT_ACK' last, this means we are now + * connected. Otherwise, do nothing. * * @param message possibly a 'struct SessionConnectMessage' (check format) * @param peer identity of the peer to switch the address for @@ -2378,343 +2778,369 @@ GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity * @param ats_count number of entries in ats */ void -GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) +GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) { - const struct SessionConnectMessage *scm; - struct GNUNET_MessageHeader msg; struct NeighbourMapEntry *n; - size_t msg_len; - size_t ret; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received CONNECT_ACK message from peer `%s'\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received SESSION_ACK message from peer `%s'\n", GNUNET_i2s (peer)); - - if (ntohs (message->size) != sizeof (struct SessionConnectMessage)) + if (ntohs (message->size) != sizeof (struct GNUNET_MessageHeader)) { GNUNET_break_op (0); return; } - scm = (const struct SessionConnectMessage *) message; - GNUNET_break_op (ntohl (scm->reserved) == 0); - n = lookup_neighbour (peer); - if (NULL == n) + if (NULL == (n = lookup_neighbour (peer))) + return; + /* check if we are in a plausible state for having sent + a CONNECT_ACK. If not, return, otherwise break */ + if ( ( (S_CONNECT_RECV_ACK != n->state) && + (S_CONNECT_SENT != n->state) ) || + (2 != n->send_connect_ack) ) { - /* we did not send 'CONNECT' -- at least not recently */ GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# unexpected CONNECT_ACK messages (no peer)"), - 1, GNUNET_NO); + gettext_noop ("# unexpected SESSION ACK messages"), 1, + GNUNET_NO); return; } + n->state = S_CONNECTED; + n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); + GNUNET_STATISTICS_set (GST_stats, + gettext_noop ("# peers connected"), + ++neighbours_connected, + GNUNET_NO); + connect_notify_cb (callback_cls, &n->id, ats, ats_count); + set_address (&n->primary_address, + n->primary_address.address, + n->primary_address.session, + n->primary_address.bandwidth_in, + n->primary_address.bandwidth_out, + GNUNET_YES); +} - /* Additional check - * - * ((n->state != S_CONNECT_RECV) && (n->address != NULL)): - * - * We also received an CONNECT message, switched from SENDT to RECV and - * ATS already suggested us an address after a successful blacklist check - */ - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received CONNECT_ACK message from peer `%s' in state `%s'\n", - GNUNET_i2s (peer), - print_state(n->state)); - if ((n->address != NULL) && (n->state == S_CONNECTED)) - { - /* After fast reconnect: send ACK (ACK) even when we are connected */ - msg_len = sizeof (msg); - msg.size = htons (msg_len); - msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK); +/** + * Test if we're connected to the given peer. + * + * @param target peer to test + * @return GNUNET_YES if we are connected, GNUNET_NO if not + */ +int +GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target) +{ + return test_connected (lookup_neighbour (target)); +} - ret = send_with_session(n, - (const char *) &msg, msg_len, - UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, - NULL, NULL); - if (ret == GNUNET_SYSERR) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to send SESSION_ACK to `%4s' using address '%s' session %X\n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address), n->session); - return; - } +/** + * Change the incoming quota for the given peer. + * + * @param neighbour identity of peer to change qutoa for + * @param quota new quota + */ +void +GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour, + struct GNUNET_BANDWIDTH_Value32NBO quota) +{ + struct NeighbourMapEntry *n; - if ((n->state != S_CONNECT_SENT) && - ((n->state != S_CONNECT_RECV) && (n->address != NULL))) + if (NULL == (n = lookup_neighbour (neighbour))) { GNUNET_STATISTICS_update (GST_stats, gettext_noop - ("# unexpected CONNECT_ACK messages"), 1, - GNUNET_NO); + ("# SET QUOTA messages ignored (no such peer)"), + 1, GNUNET_NO); return; } - if (n->state != S_CONNECTED) - change_state (n, S_CONNECTED); - - if (NULL != session) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "transport-ats", - "Giving ATS session %p of plugin %s for peer %s\n", - session, address->transport_name, GNUNET_i2s (peer)); - } - GNUNET_ATS_address_update (GST_ats, address, session, ats, ats_count); - GNUNET_assert (NULL != n->address); - - if ((n->address_state == FRESH) && (0 == GNUNET_HELLO_address_cmp(address, n->address))) - { - GST_validation_set_address_use (n->address, n->session, GNUNET_YES); - GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_YES); - n->address_state = USED; - } - - GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in); - - /* send ACK (ACK) */ - msg_len = sizeof (msg); - msg.size = htons (msg_len); - msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK); - - ret = send_with_session(n, - (const char *) &msg, msg_len, - UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, - NULL, NULL); - - if (ret == GNUNET_SYSERR) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to send SESSION_ACK to `%4s' using address '%s' session %X\n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address), n->session); - - - if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK) - n->keepalive_task = GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n); - - neighbours_connected++; - GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, - GNUNET_NO); -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Notify about connect of `%4s' using address '%s' session %X LINE %u\n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address), n->session, - __LINE__); -#endif - connect_notify_cb (callback_cls, &n->id, ats, ats_count); - send_outbound_quota (peer, n->bandwidth_out); - + "Setting inbound quota of %u Bps for peer `%s' to all clients\n", + ntohl (quota.value__), GNUNET_i2s (&n->id)); + GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, quota); + if (0 != ntohl (quota.value__)) + return; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s' due to `%s'\n", + GNUNET_i2s (&n->id), "SET_QUOTA"); + if (GNUNET_YES == test_connected (n)) + GNUNET_STATISTICS_update (GST_stats, + gettext_noop ("# disconnects due to quota of 0"), + 1, GNUNET_NO); + disconnect_neighbour (n); } +/** + * We received a disconnect message from the given peer, + * validate and process. + * + * @param peer sender of the message + * @param msg the disconnect message + */ void -GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) +GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity + *peer, + const struct GNUNET_MessageHeader + *msg) { struct NeighbourMapEntry *n; + const struct SessionDisconnectMessage *sdm; + GNUNET_HashCode hc; -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ACK message from peer `%s'\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received DISCONNECT message from peer `%s'\n", GNUNET_i2s (peer)); -#endif - - if (ntohs (message->size) != sizeof (struct GNUNET_MessageHeader)) + if (ntohs (msg->size) != sizeof (struct SessionDisconnectMessage)) { - GNUNET_break_op (0); + // GNUNET_break_op (0); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# disconnect messages ignored (old format)"), 1, + GNUNET_NO); return; } - n = lookup_neighbour (peer); - if (NULL == n) + sdm = (const struct SessionDisconnectMessage *) msg; + if (NULL == (n = lookup_neighbour (peer))) + return; /* gone already */ + if (GNUNET_TIME_absolute_ntoh (sdm->timestamp).abs_value <= n->connect_ack_timestamp.abs_value) { - GNUNET_break (0); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# disconnect messages ignored (timestamp)"), 1, + GNUNET_NO); return; } - if (S_CONNECTED == n->state) + GNUNET_CRYPTO_hash (&sdm->public_key, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &hc); + if (0 != memcmp (peer, &hc, sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_break_op (0); return; - if (!is_connecting (n)) + } + if (ntohl (sdm->purpose.size) != + sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + + sizeof (struct GNUNET_TIME_AbsoluteNBO)) { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop ("# unexpected ACK messages"), 1, - GNUNET_NO); + GNUNET_break_op (0); return; } - change_state (n, S_CONNECTED); - if (NULL != session) - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "transport-ats", - "Giving ATS session %p of plugin %s for peer %s\n", - session, address->transport_name, GNUNET_i2s (peer)); - GNUNET_ATS_address_update (GST_ats, address, session, ats, ats_count); - GNUNET_assert (n->address != NULL); - - if ((n->address_state == FRESH) && (0 == GNUNET_HELLO_address_cmp(address, n->address))) + if (GNUNET_OK != + GNUNET_CRYPTO_rsa_verify + (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT, &sdm->purpose, + &sdm->signature, &sdm->public_key)) { - GST_validation_set_address_use (n->address, n->session, GNUNET_YES); - GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_YES); - n->address_state = USED; + GNUNET_break_op (0); + return; } + if (GNUNET_YES == test_connected (n)) + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# other peer asked to disconnect from us"), 1, + GNUNET_NO); + disconnect_neighbour (n); +} - neighbours_connected++; - GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, - GNUNET_NO); +/** + * Closure for the neighbours_iterate function. + */ +struct IteratorContext +{ + /** + * Function to call on each connected neighbour. + */ + GST_NeighbourIterator cb; - GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in); - if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK) - n->keepalive_task = GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n); -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Notify about connect of `%4s' using address '%s' session %X LINE %u\n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address), n->session, - __LINE__); -#endif - connect_notify_cb (callback_cls, &n->id, ats, ats_count); - send_outbound_quota (peer, n->bandwidth_out); -} + /** + * Closure for 'cb'. + */ + void *cb_cls; +}; -struct BlackListCheckContext + +/** + * Call the callback from the closure for each connected neighbour. + * + * @param cls the 'struct IteratorContext' + * @param key the hash of the public key of the neighbour + * @param value the 'struct NeighbourMapEntry' + * @return GNUNET_OK (continue to iterate) + */ +static int +neighbours_iterate (void *cls, const GNUNET_HashCode * key, void *value) { - struct GNUNET_ATS_Information *ats; + struct IteratorContext *ic = cls; + struct NeighbourMapEntry *n = value; - uint32_t ats_count; + if (GNUNET_YES == test_connected (n)) + ic->cb (ic->cb_cls, &n->id, NULL, 0, n->primary_address.address); + return GNUNET_OK; +} - struct Session *session; - struct GNUNET_HELLO_Address *address; +/** + * Iterate over all connected neighbours. + * + * @param cb function to call + * @param cb_cls closure for cb + */ +void +GST_neighbours_iterate (GST_NeighbourIterator cb, void *cb_cls) +{ + struct IteratorContext ic; - struct GNUNET_TIME_Absolute ts; -}; + if (NULL == neighbours) + return; /* can happen during shutdown */ + ic.cb = cb; + ic.cb_cls = cb_cls; + GNUNET_CONTAINER_multihashmap_iterate (neighbours, &neighbours_iterate, &ic); +} -static void -handle_connect_blacklist_cont (void *cls, - const struct GNUNET_PeerIdentity *peer, - int result) +/** + * If we have an active connection to the given target, it must be shutdown. + * + * @param target peer to disconnect from + */ +void +GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) { struct NeighbourMapEntry *n; - struct BlackListCheckContext *bcc = cls; -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklist check due to CONNECT message: `%s'\n", - GNUNET_i2s (peer), - (result == GNUNET_OK) ? "ALLOWED" : "FORBIDDEN"); -#endif + if (NULL == (n = lookup_neighbour (target))) + return; /* not active */ + if (GNUNET_YES == test_connected (n)) + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# disconnected from peer upon explicit request"), 1, + GNUNET_NO); + disconnect_neighbour (n); +} - /* not allowed */ - if (GNUNET_OK != result) - { - GNUNET_HELLO_address_free (bcc->address); - GNUNET_free (bcc); - return; - } - n = lookup_neighbour (peer); - if (NULL == n) - n = setup_neighbour (peer); +/** + * Obtain current latency information for the given neighbour. + * + * @param peer to get the latency for + * @return observed latency of the address, FOREVER if the + * the connection is not up + */ +struct GNUNET_TIME_Relative +GST_neighbour_get_latency (const struct GNUNET_PeerIdentity *peer) +{ + struct NeighbourMapEntry *n; - if (bcc->ts.abs_value > n->connect_ts.abs_value) + n = lookup_neighbour (peer); + if (NULL == n) + return GNUNET_TIME_UNIT_FOREVER_REL; + switch (n->state) { - if (NULL != bcc->session) - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "transport-ats", - "Giving ATS session %p of address `%s' for peer %s\n", - bcc->session, GST_plugins_a2s (bcc->address), - GNUNET_i2s (peer)); - /* Tell ATS about the session, so ATS can suggest it if it likes it. */ - - GNUNET_ATS_address_update (GST_ats, bcc->address, bcc->session, bcc->ats, - bcc->ats_count); - n->connect_ts = bcc->ts; + case S_CONNECTED: + case S_RECONNECT_SENT: + case S_RECONNECT_ATS: + return n->latency; + case S_NOT_CONNECTED: + case S_INIT_BLACKLIST: + case S_INIT_ATS: + case S_CONNECT_SENT: + case S_CONNECT_RECV_BLACKLIST: + case S_DISCONNECT: + case S_DISCONNECT_FINISHED: + return GNUNET_TIME_UNIT_FOREVER_REL; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); + GNUNET_break (0); + break; } + return GNUNET_TIME_UNIT_FOREVER_REL; +} - GNUNET_HELLO_address_free (bcc->address); - GNUNET_free (bcc); - - if (n->state != S_CONNECT_RECV) - change_state (n, S_CONNECT_RECV); +/** + * Obtain current address information for the given neighbour. + * + * @param peer + * @return address currently used + */ +struct GNUNET_HELLO_Address * +GST_neighbour_get_current_address (const struct GNUNET_PeerIdentity *peer) +{ + struct NeighbourMapEntry *n; - /* Ask ATS for an address to connect via that address */ - if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = - GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, - n); - GNUNET_ATS_suggest_address (GST_ats, peer); + n = lookup_neighbour (peer); + if (NULL == n) + return NULL; + return n->primary_address.address; } + /** - * We received a 'SESSION_CONNECT' message from the other peer. - * Consider switching to it. + * Initialize the neighbours subsystem. * - * @param message possibly a 'struct SessionConnectMessage' (check format) - * @param peer identity of the peer to switch the address for - * @param address address of the other peer, NULL if other peer - * connected to us - * @param session session to use (or NULL) - * @param ats performance data - * @param ats_count number of entries in ats (excluding 0-termination) + * @param cls closure for callbacks + * @param connect_cb function to call if we connect to a peer + * @param disconnect_cb function to call if we disconnect from a peer + * @param peer_address_cb function to call if we change an active address + * of a neighbour */ void -GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) +GST_neighbours_start (void *cls, + GNUNET_TRANSPORT_NotifyConnect connect_cb, + GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, + GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb) { - const struct SessionConnectMessage *scm; - struct BlackListCheckContext *bcc = NULL; - struct NeighbourMapEntry *n; + callback_cls = cls; + connect_notify_cb = connect_cb; + disconnect_notify_cb = disconnect_cb; + address_change_cb = peer_address_cb; + neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE); +} -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received CONNECT message from peer `%s'\n", GNUNET_i2s (peer)); -#endif - if (ntohs (message->size) != sizeof (struct SessionConnectMessage)) - { - GNUNET_break_op (0); - return; - } +/** + * Disconnect from the given neighbour. + * + * @param cls unused + * @param key hash of neighbour's public key (not used) + * @param value the 'struct NeighbourMapEntry' of the neighbour + * @return GNUNET_OK (continue to iterate) + */ +static int +disconnect_all_neighbours (void *cls, const GNUNET_HashCode * key, void *value) +{ + struct NeighbourMapEntry *n = value; - scm = (const struct SessionConnectMessage *) message; - GNUNET_break_op (ntohl (scm->reserved) == 0); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Disconnecting peer `%4s', %s\n", + GNUNET_i2s (&n->id), "SHUTDOWN_TASK"); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); + return GNUNET_OK; +} - GNUNET_ATS_address_update (GST_ats, address, session, ats, ats_count); - n = lookup_neighbour (peer); - if ((n != NULL) && ((S_CONNECTED == n->state) || (S_FAST_RECONNECT == n->state))) - { - /* connected peer switches addresses or is trying to do a fast reconnect*/ +/** + * Cleanup the neighbours subsystem. + */ +void +GST_neighbours_stop () +{ + if (NULL == neighbours) return; - } - - - /* we are not connected to this peer */ - /* do blacklist check */ - bcc = - GNUNET_malloc (sizeof (struct BlackListCheckContext) + - sizeof (struct GNUNET_ATS_Information) * (ats_count + 1)); - bcc->ts = GNUNET_TIME_absolute_ntoh (scm->timestamp); - bcc->ats_count = ats_count + 1; - bcc->address = GNUNET_HELLO_address_copy (address); - bcc->session = session; - bcc->ats = (struct GNUNET_ATS_Information *) &bcc[1]; - memcpy (bcc->ats, ats, sizeof (struct GNUNET_ATS_Information) * ats_count); - bcc->ats[ats_count].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); - bcc->ats[ats_count].value = - htonl ((uint32_t) GST_neighbour_get_latency (peer).rel_value); - GST_blacklist_test_allowed (peer, address->transport_name, - &handle_connect_blacklist_cont, bcc); + GNUNET_CONTAINER_multihashmap_iterate (neighbours, + &disconnect_all_neighbours, + NULL); + GNUNET_CONTAINER_multihashmap_destroy (neighbours); + neighbours = NULL; + callback_cls = NULL; + connect_notify_cb = NULL; + disconnect_notify_cb = NULL; + address_change_cb = NULL; } diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h index 33fa1da..23091b7 100644 --- a/src/transport/gnunet-service-transport_neighbours.h +++ b/src/transport/gnunet-service-transport_neighbours.h @@ -127,6 +127,7 @@ GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity void GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour); + /** * We received a KEEP_ALIVE_RESPONSE message and use this to calculate latency * to this peer @@ -212,10 +213,8 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, * @param ats_count number of entries in ats * @param bandwidth_in inbound quota to be used when connection is up * @param bandwidth_out outbound quota to be used when connection is up - * @return GNUNET_YES if we are currently connected, GNUNET_NO if the - * connection is not up (yet) */ -int +void GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address, struct Session *session, @@ -266,13 +265,26 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, const struct GNUNET_ATS_Information *ats, uint32_t ats_count); + +/** + * We received a 'SESSION_ACK' message from the other peer. + * FIXME: describe what this means! + * + * @param message possibly a 'struct SessionConnectMessage' (check format) + * @param peer identity of the peer to switch the address for + * @param address address of the other peer, NULL if other peer + * connected to us + * @param session session to use (or NULL) + * @param ats performance data + * @param ats_count number of entries in ats + */ void -GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); +GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count); /** diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index a6d9424..8421969 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -251,6 +251,10 @@ struct ValidationEntry * Are we expecting a PONG message for this validation entry? */ int expecting_pong; + + /* FIXME: DEBUGGING */ + int last_line_set_to_no; + int last_line_set_to_yes; }; @@ -600,6 +604,9 @@ find_validation_entry (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded if (public_key == NULL) return NULL; ve = GNUNET_malloc (sizeof (struct ValidationEntry)); + ve->in_use = GNUNET_SYSERR; /* not defined */ + ve->last_line_set_to_no = 0; + ve->last_line_set_to_yes = 0; ve->address = GNUNET_HELLO_address_copy (address); ve->public_key = *public_key; ve->pid = address->peer; @@ -863,10 +870,8 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, PONG_SIGNATURE_LIFETIME.rel_value / 4) { /* create / update cached sig */ -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating PONG signature to indicate ownership.\n"); -#endif *sig_cache_exp = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME); pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); GNUNET_assert (GNUNET_OK == @@ -1076,13 +1081,10 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, GNUNET_NO); return; } -#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Address validated for peer `%s' with plugin `%s': `%s'\n", - GNUNET_i2s (sender), tname, GST_plugins_a2s (tname, addr, - addrlen)); -#endif + GNUNET_i2s (sender), tname, GST_plugins_a2s (ve->address)); /* validity achieved, remember it! */ ve->expecting_pong = GNUNET_NO; ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); @@ -1097,7 +1099,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, /* build HELLO to store in PEERINFO */ ve->copied = GNUNET_NO; hello = GNUNET_HELLO_create (&ve->public_key, &add_valid_peer_address, ve); - GNUNET_PEERINFO_add_peer (GST_peerinfo, hello); + GNUNET_PEERINFO_add_peer (GST_peerinfo, hello, NULL, NULL); GNUNET_free (hello); } @@ -1128,7 +1130,7 @@ GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) return; /* Add peer identity without addresses to peerinfo service */ h = GNUNET_HELLO_create (&vac.public_key, NULL, NULL); - GNUNET_PEERINFO_add_peer (GST_peerinfo, h); + GNUNET_PEERINFO_add_peer (GST_peerinfo, h, NULL, NULL); #if VERBOSE_VALIDATION GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Adding `%s' without addresses for peer `%s'\n"), "HELLO", @@ -1211,11 +1213,13 @@ GST_validation_get_addresses (const struct GNUNET_PeerIdentity *target, * @param session the session * @param in_use GNUNET_YES if we are now using the address for a connection, * GNUNET_NO if we are no longer using the address for a connection + * @param line line of caller just for DEBUGGING! */ void GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, struct Session *session, - int in_use) + int in_use, + int line) { struct ValidationEntry *ve; @@ -1229,10 +1233,33 @@ GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, return; } if (ve->in_use == in_use) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "GST_validation_set_address_use: %s %s: ve->in_use %i <-> in_use %i\n", - GNUNET_i2s (&address->peer), GST_plugins_a2s (address), ve->in_use, - in_use); + { + + if (GNUNET_YES == in_use) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error setting address in use for peer `%s' `%s' to USED: set last time by %i, called now by %i\n", + GNUNET_i2s (&address->peer), GST_plugins_a2s (address), + ve->last_line_set_to_yes, line); + } + if (GNUNET_NO == in_use) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error setting address in use for peer `%s' `%s' to NOT_USED: set last time by %i, called now by %i\n", + GNUNET_i2s (&address->peer), GST_plugins_a2s (address), + ve->last_line_set_to_no, line); + } + } + + if (GNUNET_YES == in_use) + { + ve->last_line_set_to_yes = line; + } + if (GNUNET_NO == in_use) + { + ve->last_line_set_to_no = line; + } + GNUNET_break (ve->in_use != in_use); /* should be different... */ ve->in_use = in_use; if (in_use == GNUNET_YES) diff --git a/src/transport/gnunet-service-transport_validation.h b/src/transport/gnunet-service-transport_validation.h index 9b1063b..dd5bcd6 100644 --- a/src/transport/gnunet-service-transport_validation.h +++ b/src/transport/gnunet-service-transport_validation.h @@ -52,13 +52,16 @@ GST_validation_stop (void); * address more or less often. * * @param address the address - * @param session session + * @param session the session * @param in_use GNUNET_YES if we are now using the address for a connection, * GNUNET_NO if we are no longer using the address for a connection + * @param line line of caller just for DEBUGGING! */ void GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, - struct Session *session, int in_use); + struct Session *session, + int in_use, + int line); /** diff --git a/src/transport/gnunet-transport-certificate-creation b/src/transport/gnunet-transport-certificate-creation index a38a7b7..b5cffb2 100755 --- a/src/transport/gnunet-transport-certificate-creation +++ b/src/transport/gnunet-transport-certificate-creation @@ -32,7 +32,7 @@ DUALCASE=1; export DUALCASE # for MKS sh # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -relink_command="(cd /home/grothoff/svn/gnunet/src/transport; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; LD_LIBRARY_PATH=/usr/lib/debug:/home/grothoff/lib; export LD_LIBRARY_PATH; PATH=/opt/jdk1.6.0_22/bin:/usr/lib/jvm/java-6-sun//bin:.:/home/grothoff/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games; export PATH; gcc -fno-strict-aliasing -Wall -g -Wall -Werror -O0 -I/home/grothoff//include -o \$progdir/\$file gnunet-transport-certificate-creation.o -L/home/grothoff//lib ../../src/util/.libs/libgnunetutil.so -ldl -Wl,-rpath -Wl,/home/grothoff/svn/gnunet/src/util/.libs -Wl,-rpath -Wl,/home/grothoff/lib)" +relink_command="(cd /home/grothoff/gnunet-0.9.3/src/transport; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; LD_LIBRARY_PATH=/usr/lib/debug:/home/grothoff/lib; export LD_LIBRARY_PATH; PATH=/opt/jdk1.6.0_22/bin:/usr/lib/jvm/java-6-sun//bin:.:/home/grothoff/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games; export PATH; gcc -fno-strict-aliasing -Wall -g -Wall -Werror -O0 -I/home/grothoff//include -o \$progdir/\$file gnunet-transport-certificate-creation.o -L/home/grothoff//lib ../../src/util/.libs/libgnunetutil.so -ldl -Wl,-rpath -Wl,/home/grothoff/gnunet-0.9.3/src/util/.libs)" # This environment variable determines our operation mode. if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then diff --git a/src/transport/gnunet-transport-certificate-creation.c b/src/transport/gnunet-transport-certificate-creation.c index 2ec8d36..c4c13dc 100644 --- a/src/transport/gnunet-transport-certificate-creation.c +++ b/src/transport/gnunet-transport-certificate-creation.c @@ -62,7 +62,7 @@ main (int argc, char **argv) if (openssl == NULL) return 2; GNUNET_assert (GNUNET_OS_process_wait (openssl) == GNUNET_OK); - GNUNET_OS_process_close (openssl); + GNUNET_OS_process_destroy (openssl); /* Create a self-signed certificate in batch mode using rsa key */ /* openssl req -batch -days 365 -out $2 -new -x509 -key $1 2> /dev/null */ @@ -73,7 +73,7 @@ main (int argc, char **argv) if (openssl == NULL) return 3; GNUNET_assert (GNUNET_OS_process_wait (openssl) == GNUNET_OK); - GNUNET_OS_process_close (openssl); + GNUNET_OS_process_destroy (openssl); CHMOD (argv[1], S_IRUSR); CHMOD (argv[2], S_IRUSR); return 0; diff --git a/src/transport/gnunet-transport-wlan-sender.c b/src/transport/gnunet-transport-wlan-sender.c index 9f06b63..daa8f02 100644 --- a/src/transport/gnunet-transport-wlan-sender.c +++ b/src/transport/gnunet-transport-wlan-sender.c @@ -46,35 +46,22 @@ #define IEEE80211_FC0_TYPE_CTL 0x04 #define IEEE80211_FC0_TYPE_DATA 0x08 -GNUNET_NETWORK_STRUCT_BEGIN - -/* - * generic definitions for IEEE 802.11 frames - */ -struct ieee80211_frame -{ - u_int8_t i_fc[2]; - u_int8_t i_dur[2]; - u_int8_t i_addr1[IEEE80211_ADDR_LEN]; - u_int8_t i_addr2[IEEE80211_ADDR_LEN]; - u_int8_t i_addr3[IEEE80211_ADDR_LEN]; - u_int8_t i_seq[2]; - u_int8_t llc[4]; -} GNUNET_PACKED; -GNUNET_NETWORK_STRUCT_END /** * function to fill the radiotap header * @param header pointer to the radiotap header + * @param size total message size * @return GNUNET_YES at success */ static int -getRadiotapHeader (struct Radiotap_Send *header) +getRadiotapHeader (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header, + uint16_t size) { + header->header.size = htons (size); + header->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER); header->rate = 255; header->tx_power = 0; header->antenna = 0; - return GNUNET_YES; } @@ -87,23 +74,21 @@ getRadiotapHeader (struct Radiotap_Send *header) * @return GNUNET_YES if there was no error */ static int -getWlanHeader (struct ieee80211_frame *Header, const char *to_mac_addr, - const char *mac, unsigned int size) +getWlanHeader (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *Header, + const struct GNUNET_TRANSPORT_WLAN_MacAddress *to_mac_addr, + const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac, unsigned int size) { - uint16_t *tmp16; const int rate = 11000000; - Header->i_fc[0] = IEEE80211_FC0_TYPE_DATA; - Header->i_fc[1] = 0x00; - memcpy (&Header->i_addr3, &mac_bssid_gnunet, sizeof (mac_bssid_gnunet)); - memcpy (&Header->i_addr2, mac, sizeof (mac_bssid_gnunet)); - memcpy (&Header->i_addr1, to_mac_addr, sizeof (mac_bssid_gnunet)); - - tmp16 = (uint16_t *) Header->i_dur; - *tmp16 = (uint16_t) GNUNET_htole16 ((size * 1000000) / rate + 290); + Header->frame_control = htons (IEEE80211_FC0_TYPE_DATA); + Header->addr3 = mac_bssid_gnunet; + Header->addr2 = *mac; + Header->addr1 = *to_mac_addr; + Header->duration = GNUNET_htole16 ((size * 1000000) / rate + 290); Header->llc[0] = WLAN_LLC_DSAP_FIELD; Header->llc[1] = WLAN_LLC_SSAP_FIELD; - + Header->llc[2] = 0; // FIXME + Header->llc[3] = 0; // FIXME return GNUNET_YES; } @@ -112,13 +97,10 @@ int main (int argc, char *argv[]) { char msg_buf[WLAN_MTU]; - struct GNUNET_MessageHeader *msg; - struct ieee80211_frame *wlan_header; - struct Radiotap_Send *radiotap; - + struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radiotap; unsigned int temp[6]; - char inmac[6]; - char outmac[6]; + struct GNUNET_TRANSPORT_WLAN_MacAddress inmac; + struct GNUNET_TRANSPORT_WLAN_MacAddress outmac; int pos; long long count; double bytes_per_s; @@ -136,7 +118,7 @@ main (int argc, char *argv[]) return 1; } if (6 != - sscanf (argv[3], "%x-%x-%x-%x-%x-%x", &temp[0], &temp[1], &temp[2], + SSCANF (argv[3], "%x-%x-%x-%x-%x-%x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5])) { fprintf (stderr, @@ -144,8 +126,10 @@ main (int argc, char *argv[]) "e.g. mon0 11-22-33-44-55-66 12-34-56-78-90-ab\n"); return 1; } + for (i = 0; i < 6; i++) + outmac.mac[i] = temp[i]; if (6 != - sscanf (argv[2], "%x-%x-%x-%x-%x-%x", &temp[0], &temp[1], &temp[2], + SSCANF (argv[2], "%x-%x-%x-%x-%x-%x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5])) { fprintf (stderr, @@ -154,9 +138,7 @@ main (int argc, char *argv[]) return 1; } for (i = 0; i < 6; i++) - inmac[i] = temp[i]; - for (i = 0; i < 6; i++) - outmac[i] = temp[i]; + inmac.mac[i] = temp[i]; pid_t pid; int commpipe[2]; /* This holds the fd for the input & output of the pipe */ @@ -185,22 +167,16 @@ main (int argc, char *argv[]) setvbuf (stdout, (char *) NULL, _IONBF, 0); /* Set non-buffered output on stdout */ - msg = (struct GNUNET_MessageHeader *) msg_buf; - msg->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); - msg->size = htons (WLAN_MTU); - radiotap = (struct Radiotap_Send *) &msg[1]; - wlan_header = (struct ieee80211_frame *) &radiotap[1]; + radiotap = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) msg_buf; + getRadiotapHeader (radiotap, WLAN_MTU); pos = 0; - - getRadiotapHeader (radiotap); - getWlanHeader (wlan_header, outmac, inmac, - WLAN_MTU - sizeof (struct GNUNET_MessageHeader)); - + getWlanHeader (&radiotap->frame, &outmac, &inmac, + WLAN_MTU); start = time (NULL); count = 0; while (1) { - pos += write (commpipe[1], msg, WLAN_MTU - pos); + pos += write (commpipe[1], msg_buf, WLAN_MTU - pos); if (pos % WLAN_MTU == 0) { pos = 0; diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c index ee977f5..3b6b7e4 100644 --- a/src/transport/gnunet-transport.c +++ b/src/transport/gnunet-transport.c @@ -37,8 +37,10 @@ /** * How long do we wait for the NAT test to report success? + * Should match NAT_SERVER_TIMEOUT in 'nat_test.c'. */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) +#define RESOLUTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) /** * Which peer should we connect to? @@ -121,6 +123,8 @@ static struct GNUNET_PeerIdentity pid; */ static GNUNET_SCHEDULER_TaskIdentifier end; +static struct GNUNET_CONTAINER_MultiHashMap *peers; + /** * Selected level of verbosity. */ @@ -193,7 +197,7 @@ display_test_result (struct TestContext *tc, int result) if ((0 == resolver_users) && (NULL != resolver)) { GNUNET_break (0 == GNUNET_OS_process_kill (resolver, SIGTERM)); - GNUNET_OS_process_close (resolver); + GNUNET_OS_process_destroy (resolver); resolver = NULL; } } @@ -443,19 +447,32 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, traffic_received += ntohs (message->size); } -void +struct ResolutionContext +{ + struct GNUNET_HELLO_Address *addrcp; + + int printed; +}; + + +static void process_string (void *cls, const char *address) { - struct GNUNET_HELLO_Address *addrcp = cls; + struct ResolutionContext *rc = cls; + struct GNUNET_HELLO_Address *addrcp = rc->addrcp; - if ((address != NULL)) + if (address != NULL) { FPRINTF (stdout, _("Peer `%s': %s %s\n"), GNUNET_i2s (&addrcp->peer), addrcp->transport_name, address); + rc->printed = GNUNET_YES; } else { /* done */ - GNUNET_free (addrcp); + if (GNUNET_NO == rc->printed) + FPRINTF (stdout, _("Peer `%s': %s \n"), GNUNET_i2s (&addrcp->peer), addrcp->transport_name); + GNUNET_free (rc->addrcp); + GNUNET_free (rc); } } @@ -471,6 +488,7 @@ process_address (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; + struct ResolutionContext *rc; if (peer == NULL) { @@ -484,10 +502,16 @@ process_address (void *cls, const struct GNUNET_PeerIdentity *peer, return; } + rc = GNUNET_malloc(sizeof (struct ResolutionContext)); + rc->addrcp = GNUNET_HELLO_address_copy(address); + rc->printed = GNUNET_NO; + + GNUNET_assert (NULL != rc); + /* Resolve address to string */ GNUNET_TRANSPORT_address_to_string (cfg, address, numeric, - GNUNET_TIME_UNIT_MINUTES, &process_string, - GNUNET_HELLO_address_copy(address)); + RESOLUTION_TIMEOUT, &process_string, + rc); } @@ -504,7 +528,13 @@ shutdown_task (void *cls, { struct GNUNET_TRANSPORT_PeerIterateContext *pic = cls; - GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pic); + GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pic); + + if (NULL != peers) + { + GNUNET_CONTAINER_multihashmap_destroy (peers); + peers = NULL; + } } @@ -561,8 +591,9 @@ run (void *cls, char *const *args, const char *cfgfile, } if (iterate_connections) { + peers = GNUNET_CONTAINER_multihashmap_create (20); GNUNET_TRANSPORT_peer_get_active_addresses (cfg, NULL, GNUNET_YES, - GNUNET_TIME_UNIT_MINUTES, + TIMEOUT, &process_address, (void *) cfg); } if (monitor_connections) diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index f88ff33..d99f531 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c @@ -106,7 +106,23 @@ struct PrettyPrinterContext */ struct Plugin; +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s); +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s); + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s); /** * Append our port and forward the result. @@ -151,6 +167,9 @@ append_port (void *cls, const char *hostname) } + + + /** * Convert the transports address to a nice, human-readable * format. @@ -209,6 +228,12 @@ http_plugin_address_pretty_printer (void *cls, const char *type, sbs = sizeof (struct sockaddr_in); port = ntohs (a4->u4_port); } + else if (0 == addrlen) + { + asc (asc_cls, ""); + asc (asc_cls, NULL); + return; + } else { /* invalid address */ @@ -243,13 +268,10 @@ http_plugin_address_pretty_printer (void *cls, const char *type, static int http_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) { - struct Plugin *plugin = cls; struct IPv4HttpAddressWrapper *w_tv4 = plugin->ipv4_addr_head; struct IPv6HttpAddressWrapper *w_tv6 = plugin->ipv6_addr_head; - - GNUNET_assert (cls != NULL); if ((addrlen != sizeof (struct sockaddr_in)) || (addrlen != sizeof (struct sockaddr_in6))) @@ -311,6 +333,8 @@ http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer, atsi[1].value = session->ats_address_network_type; GNUNET_break (session->ats_address_network_type != ntohl (GNUNET_ATS_NET_UNSPECIFIED)); + reschedule_session_timeout (session); + delay = plugin->env->receive (plugin->env->cls, &s->target, message, (const struct GNUNET_ATS_Information *) &atsi, @@ -318,6 +342,104 @@ http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer, return delay; } + +/** + * Function called to convert a string address to + * a binary address. + * + * @param cls closure ('struct Plugin*') + * @param addr string address + * @param addrlen length of the address + * @param buf location to store the buffer + * If the function returns GNUNET_SYSERR, its contents are undefined. + * @param added length of created address + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int +http_string_to_address (void *cls, + const char *addr, + uint16_t addrlen, + void **buf, + size_t *added) +{ +#if !BUILD_HTTPS + char *protocol = "http"; +#else + char *protocol = "https"; +#endif + char *addr_str = NULL; + struct sockaddr_in addr_4; + struct sockaddr_in6 addr_6; + struct IPv4HttpAddress * http_4addr; + struct IPv6HttpAddress * http_6addr; + + if ((NULL == addr) || (addrlen == 0)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + if ('\0' != addr[addrlen - 1]) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + if (strlen (addr) != addrlen - 1) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + /* protocoll + "://" + ":" */ + if (addrlen <= (strlen (protocol) + 4)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid address string `%s' to convert to address\n", + addr); + GNUNET_break (0); + return GNUNET_SYSERR; + } + + if (NULL == (addr_str = strstr(addr, "://"))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid address string `%s' to convert to address\n", + addr); + GNUNET_break (0); + return GNUNET_SYSERR; + } + addr_str = &addr_str[3]; + + if (addr_str[strlen(addr_str)-1] == '/') + addr_str[strlen(addr_str)-1] = '\0'; + + if (GNUNET_OK == GNUNET_STRINGS_to_address_ipv4(addr_str, strlen(addr_str), &addr_4)) + { + http_4addr = GNUNET_malloc (sizeof (struct IPv4HttpAddress)); + http_4addr->u4_port = addr_4.sin_port; + http_4addr->ipv4_addr = (uint32_t) addr_4.sin_addr.s_addr; + (*buf) = http_4addr; + (*added) = sizeof (struct IPv4HttpAddress); + return GNUNET_OK; + } + if (GNUNET_OK == GNUNET_STRINGS_to_address_ipv6(addr_str, strlen(addr_str), &addr_6)) + { + http_6addr = GNUNET_malloc (sizeof (struct IPv6HttpAddress)); + http_6addr->u6_port = addr_6.sin6_port; + http_6addr->ipv6_addr = addr_6.sin6_addr; + (*buf) = http_6addr; + (*added) = sizeof (struct IPv6HttpAddress); + return GNUNET_OK; + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid address string `%s' to convert to address\n", + addr_str); + GNUNET_break (0); + return GNUNET_SYSERR; +} + + /** * Function called for a quick conversion of the binary address to * a numeric address. Note that the caller must not free the @@ -385,6 +507,7 @@ http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) return rbuf; } + struct Session * lookup_session_old (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, struct Session *session, const void *addr, size_t addrlen, @@ -398,11 +521,11 @@ lookup_session_old (struct Plugin *plugin, const struct GNUNET_PeerIdentity *tar { #if 0 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - "Comparing peer `%s' address `%s' len %i session %X to \n", + "Comparing peer `%s' address `%s' len %i session %p to \n", GNUNET_i2s (target), GNUNET_a2s (addr, addrlen), addrlen, session); GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, - "peer `%s' address `%s' len %i session %X \n\n", + "peer `%s' address `%s' len %i session %p \n\n", GNUNET_i2s (&t->target), GNUNET_a2s (t->addr, t->addrlen), t->addrlen, t); GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, "memcmp %i \n", @@ -430,6 +553,7 @@ lookup_session_old (struct Plugin *plugin, const struct GNUNET_PeerIdentity *tar return NULL; } + struct Session * lookup_session (struct Plugin *plugin, const struct GNUNET_HELLO_Address *address) @@ -445,9 +569,28 @@ lookup_session (struct Plugin *plugin, } +int +exist_session (struct Plugin *plugin, struct Session *s) +{ + struct Session * head; + + GNUNET_assert (NULL != plugin); + GNUNET_assert (NULL != s); + + for (head = plugin->head; head != NULL; head = head->next) + { + if (head == s) + return GNUNET_YES; + } + return GNUNET_NO; +} + + void delete_session (struct Session *s) { + stop_session_timeout(s); + if (s->msg_tk != NULL) { GNUNET_SERVER_mst_destroy (s->msg_tk); @@ -459,10 +602,10 @@ delete_session (struct Session *s) GNUNET_free (s); } + struct Session * create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, - const void *addr, size_t addrlen, - GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) + const void *addr, size_t addrlen) { struct Session *s = NULL; @@ -474,12 +617,12 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, s->addr = GNUNET_malloc (addrlen); memcpy (s->addr, addr, addrlen); s->addrlen = addrlen; - s->next = NULL; - s->next_receive = GNUNET_TIME_absolute_get_zero (); s->ats_address_network_type = htonl (GNUNET_ATS_NET_UNSPECIFIED); + start_session_timeout(s); return s; } + void notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, struct Session *s) @@ -491,6 +634,7 @@ notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, delete_session (s); } + /** * Creates a new outbound session the transport service will use to send data to the * peer @@ -499,7 +643,6 @@ notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, * @param address the address * @return the session or NULL of max connections exceeded */ - static struct Session * http_get_session (void *cls, const struct GNUNET_HELLO_Address *address) @@ -535,16 +678,7 @@ http_get_session (void *cls, GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) || (addrlen == sizeof (struct IPv4HttpAddress))); - s = GNUNET_malloc (sizeof (struct Session)); - memcpy (&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity)); - s->plugin = plugin; - s->addr = GNUNET_malloc (address->address_length); - memcpy (s->addr, address->address, address->address_length); - s->addrlen = addrlen; - s->next = NULL; - s->next_receive = GNUNET_TIME_absolute_get_zero (); - s->inbound = GNUNET_NO; - s->ats_address_network_type = htonl (GNUNET_ATS_NET_UNSPECIFIED); + s = create_session (plugin, &address->peer, address->address, address->address_length); /* Get ATS type */ if (addrlen == sizeof (struct IPv4HttpAddress)) @@ -592,6 +726,7 @@ http_get_session (void *cls, return s; } + /** * Function that can be used by the transport service to transmit * a message using the plugin. Note that in the case of a @@ -653,7 +788,6 @@ http_plugin_send (void *cls, } /* create new message and schedule */ - msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); msg->next = NULL; msg->size = msgbuf_size; @@ -663,25 +797,21 @@ http_plugin_send (void *cls, msg->transmit_cont_cls = cont_cls; memcpy (msg->buf, msgbuf, msgbuf_size); + reschedule_session_timeout (session); + if (session->inbound == GNUNET_NO) { -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Using outbound client session %p to send to `%session'\n", session, + "Using outbound client session %p to send to `%s'\n", session, GNUNET_i2s (&session->target)); -#endif - client_send (session, msg); res = msgbuf_size; } if (session->inbound == GNUNET_YES) { -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Using inbound server %p session to send to `%session'\n", session, + "Using inbound server %p session to send to `%s'\n", session, GNUNET_i2s (&session->target)); -#endif - server_send (session, msg); res = msgbuf_size; } @@ -741,14 +871,13 @@ http_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) } } -static void -nat_add_address (void *cls, int add_remove, const struct sockaddr *addr, - socklen_t addrlen) + +static void * +find_address (struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen) { - struct Plugin *plugin = cls; + int af; struct IPv4HttpAddressWrapper *w_t4 = NULL; struct IPv6HttpAddressWrapper *w_t6 = NULL; - int af; af = addr->sa_family; switch (af) @@ -773,25 +902,7 @@ nat_add_address (void *cls, int add_remove, const struct sockaddr *addr, break; w_t4 = w_t4->next; } - if (w_t4 == NULL) - { - w_t4 = GNUNET_malloc (sizeof (struct IPv4HttpAddressWrapper)); - memcpy (&w_t4->addr.ipv4_addr, &a4->sin_addr, sizeof (struct in_addr)); - w_t4->addr.u4_port = a4->sin_port; - - GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head, - plugin->ipv4_addr_tail, w_t4); - } -#if DEBUG_HTTP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Notifying transport to add IPv4 address `%s'\n", - http_plugin_address_to_string (NULL, &w_t4->addr, - sizeof (struct - IPv4HttpAddress))); -#endif - plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr, - sizeof (struct IPv4HttpAddress)); - + return w_t4; break; case AF_INET6: w_t6 = plugin->ipv6_addr_head; @@ -811,25 +922,68 @@ nat_add_address (void *cls, int add_remove, const struct sockaddr *addr, break; w_t6 = w_t6->next; } + return w_t6; + break; + default: + return NULL; + } + return NULL; +} + + +static void +nat_add_address (void *cls, int add_remove, const struct sockaddr *addr, + socklen_t addrlen) +{ + struct Plugin *plugin = cls; + struct IPv4HttpAddressWrapper *w_t4 = NULL; + struct IPv6HttpAddressWrapper *w_t6 = NULL; + int af; + + af = addr->sa_family; + switch (af) + { + case AF_INET: + w_t4 = find_address (plugin, addr, addrlen); + if (w_t4 == NULL) + { + struct sockaddr_in *a4 = (struct sockaddr_in *) addr; + w_t4 = GNUNET_malloc (sizeof (struct IPv4HttpAddressWrapper)); + memcpy (&w_t4->addr.ipv4_addr, &a4->sin_addr, sizeof (struct in_addr)); + w_t4->addr.u4_port = a4->sin_port; + + GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head, + plugin->ipv4_addr_tail, w_t4); + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Notifying transport to add IPv4 address `%s'\n", + http_plugin_address_to_string (NULL, &w_t4->addr, + sizeof (struct + IPv4HttpAddress))); + plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr, + sizeof (struct IPv4HttpAddress)); + } + break; + case AF_INET6: + w_t6 = find_address (plugin, addr, addrlen); if (w_t6 == NULL) { w_t6 = GNUNET_malloc (sizeof (struct IPv6HttpAddressWrapper)); - + struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) addr; memcpy (&w_t6->addr6.ipv6_addr, &a6->sin6_addr, sizeof (struct in6_addr)); w_t6->addr6.u6_port = a6->sin6_port; GNUNET_CONTAINER_DLL_insert (plugin->ipv6_addr_head, plugin->ipv6_addr_tail, w_t6); - } -#if DEBUG_HTTP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Notifying transport to add IPv6 address `%s'\n", http_plugin_address_to_string (NULL, &w_t6->addr6, sizeof (struct IPv6HttpAddress))); -#endif - plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6, + plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6, sizeof (struct IPv6HttpAddress)); + } break; default: return; @@ -837,6 +991,7 @@ nat_add_address (void *cls, int add_remove, const struct sockaddr *addr, } + static void nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr, socklen_t addrlen) @@ -850,35 +1005,16 @@ nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr, switch (af) { case AF_INET: - w_t4 = plugin->ipv4_addr_head; - struct sockaddr_in *a4 = (struct sockaddr_in *) addr; - - while (w_t4 != NULL) - { - int res = memcmp (&w_t4->addr.ipv4_addr, - &a4->sin_addr, - sizeof (struct in_addr)); - - if (res == 0) - { - if (a4->sin_port != w_t4->addr.u4_port) - res = -1; - } - - if (0 == res) - break; - w_t4 = w_t4->next; - } + w_t4 = find_address (plugin, addr, addrlen); if (w_t4 == NULL) return; -#if DEBUG_HTTP + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Notifying transport to remove IPv4 address `%s'\n", http_plugin_address_to_string (NULL, &w_t4->addr, sizeof (struct IPv4HttpAddress))); -#endif plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr, sizeof (struct IPv4HttpAddress)); @@ -887,32 +1023,16 @@ nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr, GNUNET_free (w_t4); break; case AF_INET6: - w_t6 = plugin->ipv6_addr_head; - struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) addr; - - while (w_t6) - { - int res = memcmp (&w_t6->addr6.ipv6_addr, &a6->sin6_addr, - sizeof (struct in6_addr)); - - if (res == 0) - { - if (a6->sin6_port != w_t6->addr6.u6_port) - res = -1; - } - if (0 == res) - break; - w_t6 = w_t6->next; - } + w_t6 = find_address (plugin, addr, addrlen); if (w_t6 == NULL) return; -#if DEBUG_HTTP + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Notifying transport to remove IPv6 address `%s'\n", http_plugin_address_to_string (NULL, &w_t6->addr6, sizeof (struct IPv6HttpAddress))); -#endif + plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6, sizeof (struct IPv6HttpAddress)); @@ -923,9 +1043,9 @@ nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr, default: return; } - } + /** * Our external IP address/port mapping has changed. * @@ -940,15 +1060,13 @@ nat_port_map_callback (void *cls, int add_remove, const struct sockaddr *addr, socklen_t addrlen) { GNUNET_assert (cls != NULL); -#if DEBUG_HTTP struct Plugin *plugin = cls; -#endif -#if DEBUG_HTTP + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "NPMC called %s to address `%s'\n", (add_remove == GNUNET_NO) ? "remove" : "add", GNUNET_a2s (addr, addrlen)); -#endif + switch (add_remove) { case GNUNET_YES: @@ -960,6 +1078,7 @@ nat_port_map_callback (void *cls, int add_remove, const struct sockaddr *addr, } } + void http_check_ipv6 (struct Plugin *plugin) { @@ -993,6 +1112,7 @@ http_check_ipv6 (struct Plugin *plugin) } } + int http_get_addresses (struct Plugin *plugin, const char *serviceName, const struct GNUNET_CONFIGURATION_Handle *cfg, @@ -1203,6 +1323,7 @@ start_report_addresses (struct Plugin *plugin) } } + static void stop_report_addresses (struct Plugin *plugin) { @@ -1230,6 +1351,7 @@ stop_report_addresses (struct Plugin *plugin) } } + static int configure_plugin (struct Plugin *plugin) { @@ -1362,6 +1484,91 @@ fail: return res; } + +/** + * Session was idle, so disconnect it + */ +static void +session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_assert (NULL != cls); + struct Session *s = cls; + + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p was idle for %llu, disconnecting\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + + /* call session destroy function */ + if (s->inbound == GNUNET_NO) + GNUNET_assert (GNUNET_OK == client_disconnect (s)); + else + GNUNET_assert (GNUNET_OK == server_disconnect (s)); + +} + + +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); + + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p set to %llu\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + + +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); + + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p set to %llu\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + + if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) + { + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p canceled\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p was not active\n", + s); + } +} + + /** * Entry point for the plugin. */ @@ -1373,14 +1580,29 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) struct Plugin *plugin; int res; + if (NULL == env->receive) + { + /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully + initialze the plugin or the API */ + api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); + api->cls = NULL; + api->address_pretty_printer = &http_plugin_address_pretty_printer; + api->address_to_string = &http_plugin_address_to_string; + api->string_to_address = &http_string_to_address; + return api; + } + plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->env = env; + plugin->outbound_sessions = 0; + plugin->inbound_sessions = 0; api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); api->cls = plugin; api->disconnect = &http_plugin_disconnect; api->address_pretty_printer = &http_plugin_address_pretty_printer; api->check_address = &http_plugin_address_suggested; api->address_to_string = &http_plugin_address_to_string; + api->string_to_address = &http_string_to_address; api->get_session = &http_get_session; api->send = &http_plugin_send; @@ -1435,11 +1657,8 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) /* Report addresses to transport service */ start_report_addresses (plugin); -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Plugin `%s' loaded\n", plugin->name); -#endif - return api; } @@ -1452,7 +1671,13 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) { struct GNUNET_TRANSPORT_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; - struct Session *s = NULL; + struct Session *s; + + if (NULL == plugin) + { + GNUNET_free (api); + return NULL; + } /* Stop reporting addresses to transport service */ stop_report_addresses (plugin); @@ -1461,10 +1686,8 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) s = plugin->head; while (s != NULL) { -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Disconnecting `%s' \n", GNUNET_i2s (&s->target)); -#endif if (s->inbound == GNUNET_NO) GNUNET_assert (GNUNET_OK == client_disconnect (s)); else @@ -1472,15 +1695,11 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) s = s->next; } -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Stopping server\n"); -#endif /* Stop server */ server_stop (plugin); -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Stopping client\n"); -#endif /* Stop client */ client_stop (plugin); @@ -1512,17 +1731,12 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) s = t; } - -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Plugin `%s' unloaded\n", plugin->name); -#endif - GNUNET_free_non_null (plugin->server_addr_v4); GNUNET_free_non_null (plugin->server_addr_v6); GNUNET_free (plugin); GNUNET_free (api); - return NULL; } diff --git a/src/transport/plugin_transport_http.h b/src/transport/plugin_transport_http.h index be8f93d..986d7d7 100644 --- a/src/transport/plugin_transport_http.h +++ b/src/transport/plugin_transport_http.h @@ -45,7 +45,7 @@ #define DEBUG_HTTP GNUNET_EXTRA_LOGGING #define VERBOSE_SERVER GNUNET_EXTRA_LOGGING #define VERBOSE_CLIENT GNUNET_EXTRA_LOGGING -#define VERBOSE_CURL GNUNET_EXTRA_LOGGING +#define VERBOSE_CURL GNUNET_NO #if BUILD_HTTPS #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_init @@ -159,6 +159,16 @@ struct Plugin */ int max_connections; + /** + * Number of outbound sessions + */ + unsigned int outbound_sessions; + + /** + * Number of inbound sessions + */ + unsigned int inbound_sessions; + /** * Plugin HTTPS SSL/TLS options * ---------------------------- @@ -215,6 +225,11 @@ struct Plugin */ GNUNET_SCHEDULER_TaskIdentifier server_v4_task; + /** + * The IPv4 server is scheduled to run asap + */ + int server_v4_immediately; + /** * MHD IPv6 daemon */ @@ -225,6 +240,12 @@ struct Plugin */ GNUNET_SCHEDULER_TaskIdentifier server_v6_task; + /** + * The IPv6 server is scheduled to run asap + */ + + int server_v6_immediately; + /** * IPv4 server socket to bind to */ @@ -295,6 +316,24 @@ struct IPv6HttpAddress }; GNUNET_NETWORK_STRUCT_END + +struct ServerConnection +{ + /* _RECV or _SEND */ + int direction; + + /* Should this connection get disconnected? GNUNET_YES/NO */ + int disconnect; + + /* The session this server connection belongs to */ + struct Session *session; + + /* The MHD connection */ + struct MHD_Connection *mhd_conn; +}; + + + /** * Session handle for connections. */ @@ -389,6 +428,11 @@ struct Session */ GNUNET_SCHEDULER_TaskIdentifier recv_wakeup_task; + /** + * Session timeout task + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + /** * Is client send handle paused since there are no data to send? * GNUNET_YES/NO @@ -402,12 +446,12 @@ struct Session /** * Client send handle */ - void *server_recv; + struct ServerConnection *server_recv; /** * Client send handle */ - void *server_send; + struct ServerConnection *server_send; }; /** @@ -453,13 +497,18 @@ struct HTTP_Message void *transmit_cont_cls; }; +struct Session * +create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, + const void *addr, size_t addrlen); + +int +exist_session (struct Plugin *plugin, struct Session *s); + void delete_session (struct Session *s); -struct Session * -create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, - const void *addr, size_t addrlen, - GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls); +int +exist_session (struct Plugin *plugin, struct Session *s); struct GNUNET_TIME_Relative http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer, diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index 4679e45..f55311f 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) + (C) 2002--2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -26,6 +26,8 @@ #include "plugin_transport_http.h" +static struct Plugin * p; + #if VERBOSE_CURL /** * Function to log curl debug messages with GNUNET_log @@ -53,10 +55,10 @@ client_log (CURL * curl, curl_infotype type, char *data, size_t size, void *cls) } #if BUILD_HTTPS GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-https", - "Client: %X - %s", cls, text); + "Client: %p - %s", cls, text); #else GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-http", - "Client: %X - %s", cls, text); + "Client: %p - %s", cls, text); #endif } return 0; @@ -71,6 +73,7 @@ client_log (CURL * curl, curl_infotype type, char *data, size_t size, void *cls) static void client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + /** * Function setting up file descriptors and scheduling task to run * @@ -97,7 +100,6 @@ client_schedule (struct Plugin *plugin, int now) GNUNET_SCHEDULER_cancel (plugin->client_perform_task); plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; } - max = -1; FD_ZERO (&rs); FD_ZERO (&ws); @@ -133,7 +135,7 @@ client_schedule (struct Plugin *plugin, int now) plugin->client_perform_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, timeout, grs, gws, + timeout, grs, gws, &client_run, plugin); GNUNET_NETWORK_fdset_destroy (gws); GNUNET_NETWORK_fdset_destroy (grs); @@ -145,27 +147,29 @@ int client_send (struct Session *s, struct HTTP_Message *msg) { GNUNET_assert (s != NULL); - GNUNET_CONTAINER_DLL_insert (s->msg_head, s->msg_tail, msg); + GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, s->msg_tail, msg); + if (GNUNET_YES != exist_session(p, s)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } if (s->client_put_paused == GNUNET_YES) { -#if VERBOSE_CLIENT GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, - "Client: %X was suspended, unpausing\n", s->client_put); -#endif + "Client: %p was suspended, unpausing\n", s->client_put); s->client_put_paused = GNUNET_NO; curl_easy_pause (s->client_put, CURLPAUSE_CONT); } - client_schedule (s->plugin, GNUNET_YES); return GNUNET_OK; } - /** * Task performing curl operations + * * @param cls plugin as closure * @param tc gnunet scheduler task context */ @@ -210,12 +214,19 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (CURLE_OK == curl_easy_getinfo (easy_h, CURLINFO_PRIVATE, &d)); s = (struct Session *) d; + + if (GNUNET_YES != exist_session(plugin, s)) + { + GNUNET_break (0); + return; + } + GNUNET_assert (s != NULL); if (msg->msg == CURLMSG_DONE) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %X connection to '%s' %s ended with reason %i: `%s'\n", + "Client: %p connection to '%s' %s ended with reason %i: `%s'\n", msg->easy_handle, GNUNET_i2s (&s->target), http_plugin_address_to_string (NULL, s->addr, s->addrlen), @@ -223,7 +234,11 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) curl_easy_strerror (msg->data.result)); client_disconnect (s); - //GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,"Notifying about ended session to peer `%s' `%s'\n", GNUNET_i2s (&s->target), http_plugin_address_to_string (plugin, s->addr, s->addrlen)); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, + plugin->name, + "Notifying about ended session to peer `%s' `%s'\n", + GNUNET_i2s (&s->target), + http_plugin_address_to_string (plugin, s->addr, s->addrlen)); notify_session_end (plugin, &s->target, s); } } @@ -232,6 +247,7 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) client_schedule (plugin, GNUNET_NO); } + int client_disconnect (struct Session *s) { @@ -241,15 +257,17 @@ client_disconnect (struct Session *s) struct HTTP_Message *msg; struct HTTP_Message *t; - + if (GNUNET_YES != exist_session(plugin, s)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } if (s->client_put != NULL) { -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %X Deleting outbound PUT session to peer `%s'\n", + "Client: %p Deleting outbound PUT session to peer `%s'\n", s->client_put, GNUNET_i2s (&s->target)); -#endif mret = curl_multi_remove_handle (plugin->client_mh, s->client_put); if (mret != CURLM_OK) @@ -271,11 +289,9 @@ client_disconnect (struct Session *s) if (s->client_get != NULL) { -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %X Deleting outbound GET session to peer `%s'\n", + "Client: %p Deleting outbound GET session to peer `%s'\n", s->client_get, GNUNET_i2s (&s->target)); -#endif mret = curl_multi_remove_handle (plugin->client_mh, s->client_get); if (mret != CURLM_OK) @@ -300,6 +316,14 @@ client_disconnect (struct Session *s) } plugin->cur_connections -= 2; + + GNUNET_assert (plugin->outbound_sessions > 0); + plugin->outbound_sessions --; + GNUNET_STATISTICS_set (plugin->env->stats, + "# HTTP outbound sessions", + plugin->outbound_sessions, + GNUNET_NO); + /* Re-schedule since handles have changed */ if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) { @@ -312,84 +336,86 @@ client_disconnect (struct Session *s) return res; } -static void +static int client_receive_mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message) { struct Session *s = cls; struct GNUNET_TIME_Relative delay; + if (GNUNET_YES != exist_session(p, s)) + { + GNUNET_break (0); + return GNUNET_OK; + } + delay = http_plugin_receive (s, &s->target, message, s, s->addr, s->addrlen); s->next_receive = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay); if (GNUNET_TIME_absolute_get ().abs_value < s->next_receive.abs_value) { -#if VERBOSE_CLIENT struct Plugin *plugin = s->plugin; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Client: peer `%s' address `%s' next read delayed for %llu ms\n", GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen), delay); -#endif } + return GNUNET_OK; } + static void client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Session *s = cls; + if (GNUNET_YES != exist_session(p, s)) + { + GNUNET_break (0); + return; + } s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, - "Client: %X Waking up receive handle\n", s->client_get); - + "Client: %p Waking up receive handle\n", s->client_get); if (s->client_get != NULL) curl_easy_pause (s->client_get, CURLPAUSE_CONT); - } + /** -* Callback method used with libcurl -* Method is called when libcurl needs to write data during sending -* @param stream pointer where to write data -* @param size size of an individual element -* @param nmemb count of elements that can be written to the buffer -* @param cls destination pointer, passed to the libcurl handle -* @return bytes read from stream -*/ + * Callback method used with libcurl + * Method is called when libcurl needs to write data during sending + * + * @param stream pointer where to write data + * @param size size of an individual element + * @param nmemb count of elements that can be written to the buffer + * @param cls destination pointer, passed to the libcurl handle + * @return bytes read from stream + */ static size_t client_receive (void *stream, size_t size, size_t nmemb, void *cls) { struct Session *s = cls; struct GNUNET_TIME_Absolute now; size_t len = size * nmemb; - - -#if VERBOSE_CLIENT struct Plugin *plugin = s->plugin; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Client: Received %Zu bytes from peer `%s'\n", len, GNUNET_i2s (&s->target)); -#endif - now = GNUNET_TIME_absolute_get (); if (now.abs_value < s->next_receive.abs_value) { struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference (now, s->next_receive); -#if DEBUG_CLIENT GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %X No inbound bandwidth available! Next read was delayed for %llu ms\n", + "Client: %p No inbound bandwidth available! Next read was delayed for %llu ms\n", s->client_get, delta.rel_value); -#endif if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); @@ -399,19 +425,17 @@ client_receive (void *stream, size_t size, size_t nmemb, void *cls) GNUNET_SCHEDULER_add_delayed (delta, &client_wake_up, s); return CURLPAUSE_ALL; } - - - if (s->msg_tk == NULL) + if (NULL == s->msg_tk) s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb, s); - GNUNET_SERVER_mst_receive (s->msg_tk, s, stream, len, GNUNET_NO, GNUNET_NO); - return len; } + /** * Callback method used with libcurl * Method is called when libcurl needs to read data during sending + * * @param stream pointer where to write data * @param size size of an individual element * @param nmemb count of elements that can be written to the buffer @@ -422,69 +446,45 @@ static size_t client_send_cb (void *stream, size_t size, size_t nmemb, void *cls) { struct Session *s = cls; - -#if VERBOSE_CLIENT struct Plugin *plugin = s->plugin; -#endif - size_t bytes_sent = 0; - size_t len; - struct HTTP_Message *msg = s->msg_head; + size_t len; - if (msg == NULL) + if (GNUNET_YES != exist_session(plugin, s)) + { + GNUNET_break (0); + return 0; + } + if (NULL == msg) { -#if VERBOSE_CLIENT GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %X Nothing to send! Suspending PUT handle!\n", + "Client: %p Nothing to send! Suspending PUT handle!\n", s->client_put); -#endif s->client_put_paused = GNUNET_YES; return CURL_READFUNC_PAUSE; } - - GNUNET_assert (msg != NULL); /* data to send */ - if (msg->pos < msg->size) - { - /* data fit in buffer */ - if ((msg->size - msg->pos) <= (size * nmemb)) - { - len = (msg->size - msg->pos); - memcpy (stream, &msg->buf[msg->pos], len); - msg->pos += len; - bytes_sent = len; - } - else - { - len = size * nmemb; - memcpy (stream, &msg->buf[msg->pos], len); - msg->pos += len; - bytes_sent = len; - } - } - /* no data to send */ - else - { - GNUNET_assert (0); - bytes_sent = 0; - } - + GNUNET_assert (msg->pos < msg->size); + /* calculate how much fits in buffer */ + len = GNUNET_MIN (msg->size - msg->pos, + size * nmemb); + memcpy (stream, &msg->buf[msg->pos], len); + msg->pos += len; if (msg->pos == msg->size) { -#if VERBOSE_CLIENT GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Client: %X Message with %u bytes sent, removing message from queue\n", + "Client: %p Message with %u bytes sent, removing message from queue\n", s->client_put, msg->size, msg->pos); -#endif /* Calling transmit continuation */ + GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); if (NULL != msg->transmit_cont) msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK); - GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); GNUNET_free (msg); } - return bytes_sent; + return len; } + int client_connect (struct Session *s) { @@ -493,15 +493,10 @@ client_connect (struct Session *s) char *url; CURLMcode mret; -#if VERBOSE_CLIENT -#endif GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Initiating outbound session peer `%s'\n", GNUNET_i2s (&s->target)); - - s->inbound = GNUNET_NO; - plugin->last_tag++; /* create url */ GNUNET_asprintf (&url, "%s%s;%u", @@ -595,6 +590,12 @@ client_connect (struct Session *s) /* Perform connect */ plugin->cur_connections += 2; + plugin->outbound_sessions ++; + GNUNET_STATISTICS_set (plugin->env->stats, + "# HTTP outbound sessions", + plugin->outbound_sessions, + GNUNET_NO); + /* Re-schedule since handles have changed */ if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) { @@ -606,10 +607,12 @@ client_connect (struct Session *s) return res; } + int client_start (struct Plugin *plugin) { int res = GNUNET_OK; + p = plugin; curl_global_init (CURL_GLOBAL_ALL); plugin->client_mh = curl_multi_init (); @@ -619,15 +622,17 @@ client_start (struct Plugin *plugin) GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, _ ("Could not initialize curl multi handle, failed to start %s plugin!\n"), - plugin->name); + plugin->name); res = GNUNET_SYSERR; } return res; } + void client_stop (struct Plugin *plugin) { + p = NULL; if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (plugin->client_perform_task); diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index 8ec5a5e..4b4f504 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c @@ -30,17 +30,7 @@ #define _RECEIVE 0 #define _SEND 1 -struct ServerConnection -{ - /* _RECV or _SEND */ - int direction; - - /* should this connection get disconnected? GNUNET_YES/NO */ - int disconnect; - - struct Session *session; - struct MHD_Connection *mhd_conn; -}; +static struct Plugin * p; /** * Function that queries MHD's select sets and @@ -95,12 +85,13 @@ static char * server_load_file (const char *file) { struct GNUNET_DISK_FileHandle *gn_file; - struct stat fstat; + uint64_t fsize; char *text = NULL; - if (0 != STAT (file, &fstat)) + if (GNUNET_OK != GNUNET_DISK_file_size (file, + &fsize, GNUNET_NO, GNUNET_YES)) return NULL; - text = GNUNET_malloc (fstat.st_size + 1); + text = GNUNET_malloc (fsize + 1); gn_file = GNUNET_DISK_file_open (file, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ); @@ -109,13 +100,13 @@ server_load_file (const char *file) GNUNET_free (text); return NULL; } - if (GNUNET_SYSERR == GNUNET_DISK_file_read (gn_file, text, fstat.st_size)) + if (GNUNET_SYSERR == GNUNET_DISK_file_read (gn_file, text, fsize)) { GNUNET_free (text); GNUNET_DISK_file_close (gn_file); return NULL; } - text[fstat.st_size] = '\0'; + text[fsize] = '\0'; GNUNET_DISK_file_close (gn_file); return text; } @@ -172,10 +163,8 @@ server_load_certificate (struct Plugin *plugin) GNUNET_free_non_null (plugin->cert); plugin->cert = NULL; -#if VERBOSE_SERVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No usable TLS certificate found, creating certificate\n"); -#endif errno = 0; cert_creation = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, @@ -200,7 +189,7 @@ server_load_certificate (struct Plugin *plugin) return GNUNET_SYSERR; } GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (cert_creation)); - GNUNET_OS_process_close (cert_creation); + GNUNET_OS_process_destroy (cert_creation); plugin->key = server_load_file (key_file); plugin->cert = server_load_file (cert_file); @@ -226,10 +215,7 @@ server_load_certificate (struct Plugin *plugin) } GNUNET_free (key_file); GNUNET_free (cert_file); -#if DEBUG_HTTP GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLS certificate loaded\n"); -#endif - return res; } #endif @@ -242,12 +228,17 @@ server_load_certificate (struct Plugin *plugin) * @param now GNUNET_YES to schedule execution immediately, GNUNET_NO to wait * until timeout */ - static void server_reschedule (struct Plugin *plugin, struct MHD_Daemon *server, int now) { if ((server == plugin->server_v4) && (plugin->server_v4 != NULL)) { + if (GNUNET_YES == plugin->server_v4_immediately) + return; /* No rescheduling, server will run asap */ + + if (GNUNET_YES == now) + plugin->server_v4_immediately = GNUNET_YES; + if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (plugin->server_v4_task); @@ -258,6 +249,12 @@ server_reschedule (struct Plugin *plugin, struct MHD_Daemon *server, int now) if ((server == plugin->server_v6) && (plugin->server_v6 != NULL)) { + if (GNUNET_YES == plugin->server_v6_immediately) + return; /* No rescheduling, server will run asap */ + + if (GNUNET_YES == now) + plugin->server_v6_immediately = GNUNET_YES; + if (plugin->server_v6_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (plugin->server_v6_task); @@ -273,11 +270,16 @@ server_reschedule (struct Plugin *plugin, struct MHD_Daemon *server, int now) * @param client clien * @param message the message to be forwarded to transport service */ -static void +static int server_receive_mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message) { struct Session *s = cls; + + GNUNET_assert (NULL != p); + if (GNUNET_NO == exist_session(p, s)) + return GNUNET_OK; + struct Plugin *plugin = s->plugin; struct GNUNET_TIME_Relative delay; @@ -294,8 +296,10 @@ server_receive_mst_cb (void *cls, void *client, http_plugin_address_to_string (NULL, s->addr, s->addrlen), delay); } + return GNUNET_OK; } + /** * Callback called by MHD when it needs data to send * @param cls current session @@ -308,47 +312,54 @@ static ssize_t server_send_callback (void *cls, uint64_t pos, char *buf, size_t max) { struct Session *s = cls; - + ssize_t bytes_read = 0; struct HTTP_Message *msg; - int bytes_read = 0; - //static int c = 0; + GNUNET_assert (NULL != p); + if (GNUNET_NO == exist_session(p, s)) + return 0; msg = s->msg_head; - if (msg != NULL) + if (NULL != msg) { /* sending */ - if ((msg->size - msg->pos) <= max) - { - memcpy (buf, &msg->buf[msg->pos], (msg->size - msg->pos)); - bytes_read = msg->size - msg->pos; - msg->pos += (msg->size - msg->pos); - } - else - { - memcpy (buf, &msg->buf[msg->pos], max); - msg->pos += max; - bytes_read = max; - } + bytes_read = GNUNET_MIN (msg->size - msg->pos, + max); + memcpy (buf, &msg->buf[msg->pos], bytes_read); + msg->pos += bytes_read; /* removing message */ if (msg->pos == msg->size) { + GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); if (NULL != msg->transmit_cont) msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK); - GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); GNUNET_free (msg); } } + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + "Server: %p: sent %u bytes\n", s, bytes_read); + return bytes_read; +} - struct Plugin *plugin = s->plugin; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: %X: sent %u bytes\n", s, bytes_read); - return bytes_read; +static struct Session * +server_lookup_session (struct Plugin *plugin, + struct ServerConnection * sc) +{ + struct Session *s; + + for (s = plugin->head; NULL != s; s = s->next) + if ((s->server_recv == sc) || (s->server_send == sc)) + return s; + for (s = plugin->server_semi_head; NULL != s; s = s->next) + if ((s->server_recv == sc) || (s->server_send == sc)) + return s; + return NULL; } + static struct ServerConnection * -server_lookup_session (struct Plugin *plugin, +server_lookup_serverconnection (struct Plugin *plugin, struct MHD_Connection *mhd_connection, const char *url, const char *method) { @@ -368,12 +379,11 @@ server_lookup_session (struct Plugin *plugin, uint32_t tag = 0; int direction = GNUNET_SYSERR; - conn_info = - MHD_get_connection_info (mhd_connection, + conn_info = MHD_get_connection_info (mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); if ((conn_info->client_addr->sa_family != AF_INET) && (conn_info->client_addr->sa_family != AF_INET6)) - return MHD_NO; + return NULL; if ((strlen (&url[1]) >= 105) && (url[104] == ';')) { @@ -408,12 +418,12 @@ server_lookup_session (struct Plugin *plugin, plugin->cur_connections++; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: New inbound connection from %s with tag %u\n", + "Server: New %s connection from %s with tag %u\n", + method, GNUNET_i2s (&target), tag); - /* find duplicate session */ + /* find duplicate session */ t = plugin->head; - while (t != NULL) { if ((t->inbound) && @@ -469,6 +479,12 @@ server_lookup_session (struct Plugin *plugin, "Server: Found matching semi-session, merging session for peer `%s'\n", GNUNET_i2s (&target)); + plugin->inbound_sessions ++; + GNUNET_STATISTICS_set (plugin->env->stats, + "# HTTP inbound sessions", + plugin->inbound_sessions, + GNUNET_NO); + GNUNET_assert (NULL != s); goto found; } if ((direction == _RECEIVE) && (t->server_recv != NULL)) @@ -487,6 +503,12 @@ server_lookup_session (struct Plugin *plugin, GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Server: Found matching semi-session, merging session for peer `%s'\n", GNUNET_i2s (&target)); + plugin->inbound_sessions ++; + GNUNET_STATISTICS_set (plugin->env->stats, + "# HTTP inbound sessions", + plugin->inbound_sessions, + GNUNET_NO); + GNUNET_assert (NULL != s); goto found; } @@ -517,16 +539,15 @@ create: GNUNET_break (0); goto error; } - s = create_session (plugin, &target, a, a_len, NULL, NULL); + s = create_session (plugin, &target, a, a_len); + GNUNET_assert (NULL != s); s->ats_address_network_type = ats.value; - s->inbound = GNUNET_YES; - s->next_receive = GNUNET_TIME_absolute_get_zero (); + s->next_receive = GNUNET_TIME_UNIT_ZERO_ABS; s->tag = tag; - if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) - s->server_recv = s; - if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) - s->server_send = s; + s->server_recv = NULL; + s->server_send = NULL; + GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, plugin->server_semi_tail, s); goto found; @@ -550,7 +571,7 @@ found: int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Setting timeout for %X to %u sec.\n", sc, to); + "Server: Setting timeout for %p to %u sec.\n", sc, to); MHD_set_connection_option (mhd_connection, MHD_CONNECTION_OPTION_TIMEOUT, to); struct MHD_Daemon *d = NULL; @@ -578,19 +599,17 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, const char *upload_data, size_t * upload_data_size, void **httpSessionCache) { - struct Plugin *plugin = cls; struct ServerConnection *sc = *httpSessionCache; - struct Session *s = NULL; - - int res = MHD_YES; + struct Session *s; struct MHD_Response *response; + int res = MHD_YES; GNUNET_assert (cls != NULL); - /* new connection */ if (sc == NULL) { - sc = server_lookup_session (plugin, mhd_connection, url, method); + /* new connection */ + sc = server_lookup_serverconnection (plugin, mhd_connection, url, method); if (sc != NULL) (*httpSessionCache) = sc; else @@ -603,11 +622,22 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, return res; } } + else + { + /* 'old' connection */ + if (NULL == server_lookup_session (plugin, sc)) + { + /* Session was already disconnected */ + return MHD_NO; + } + } /* existing connection */ sc = (*httpSessionCache); s = sc->session; + GNUNET_assert (NULL != s); + /* connection is to be disconnected */ if (sc->disconnect == GNUNET_YES) { @@ -663,7 +693,7 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, if ((s->next_receive.abs_value <= now.abs_value)) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: %X: PUT with %u bytes forwarded to MST\n", s, + "Server: %p: PUT with %u bytes forwarded to MST\n", s, *upload_data_size); if (s->msg_tk == NULL) { @@ -683,7 +713,7 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, { t = s->server_recv; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Setting timeout for %X to %u sec.\n", t, + "Server: Setting timeout for %p to %u sec.\n", t, to); MHD_set_connection_option (t->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, to); @@ -692,7 +722,7 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, { t = s->server_send; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: Setting timeout for %X to %u sec.\n", t, + "Server: Setting timeout for %p to %u sec.\n", t, to); MHD_set_connection_option (t->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, to); @@ -710,7 +740,7 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Server: %X no inbound bandwidth available! Next read was delayed by %llu ms\n", + "Server: %p no inbound bandwidth available! Next read was delayed by %llu ms\n", s, now.abs_value - s->next_receive.abs_value); } return MHD_YES; @@ -734,24 +764,28 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, if (sc == NULL) return; - s = sc->session; + if (NULL == (s = server_lookup_session (p, sc))) + return; + + GNUNET_assert (NULL != p); + if (GNUNET_NO == exist_session(p, s)) + return; + plugin = s->plugin; if (sc->direction == _SEND) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: %X peer `%s' GET on address `%s' disconnected\n", + "Server: %p peer `%s' GET on address `%s' disconnected\n", s->server_send, GNUNET_i2s (&s->target), http_plugin_address_to_string (NULL, s->addr, s->addrlen)); - s->server_send = NULL; - - if (s->server_recv != NULL) + if (NULL != (tc = s->server_recv)) { - tc = s->server_recv; tc->disconnect = GNUNET_YES; + GNUNET_assert (NULL != tc->mhd_conn); #if MHD_VERSION >= 0x00090E00 - MHD_set_connection_option (sc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, + MHD_set_connection_option (tc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, 1); #endif } @@ -759,16 +793,16 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, if (sc->direction == _RECEIVE) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Server: %X peer `%s' PUT on address `%s' disconnected\n", + "Server: %p peer `%s' PUT on address `%s' disconnected\n", s->server_recv, GNUNET_i2s (&s->target), http_plugin_address_to_string (NULL, s->addr, s->addrlen)); s->server_recv = NULL; - if (s->server_send != NULL) + if (NULL != (tc = s->server_send)) { - tc = s->server_send; tc->disconnect = GNUNET_YES; + GNUNET_assert (NULL != tc->mhd_conn); #if MHD_VERSION >= 0x00090E00 - MHD_set_connection_option (sc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, + MHD_set_connection_option (tc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, 1); #endif } @@ -778,6 +812,7 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, s->msg_tk = NULL; } } + GNUNET_free (sc); t = plugin->server_semi_head; @@ -814,6 +849,12 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, s->msg_tk = NULL; } + GNUNET_assert (plugin->inbound_sessions > 0); + plugin->inbound_sessions --; + GNUNET_STATISTICS_set (plugin->env->stats, + "# HTTP inbound sessions", + plugin->inbound_sessions, GNUNET_NO); + notify_session_end (s->plugin, &s->target, s); } } @@ -821,31 +862,22 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, int server_disconnect (struct Session *s) { - struct Plugin *plugin = s->plugin; - struct Session *t = plugin->head; - - while (t != NULL) + if (s->server_send != NULL) { - if (t->inbound == GNUNET_YES) - { - if (t->server_send != NULL) - { - ((struct ServerConnection *) t->server_send)->disconnect = GNUNET_YES; - } - if (t->server_send != NULL) - { - ((struct ServerConnection *) t->server_send)->disconnect = GNUNET_YES; - } - } - t = t->next; + ((struct ServerConnection *) s->server_send)->disconnect = GNUNET_YES; } + if (s->server_recv != NULL) + { + ((struct ServerConnection *) s->server_recv)->disconnect = GNUNET_YES; + } + return GNUNET_OK; } int server_send (struct Session *s, struct HTTP_Message *msg) { - GNUNET_CONTAINER_DLL_insert (s->msg_head, s->msg_tail, msg); + GNUNET_CONTAINER_DLL_insert_tail (s->msg_head, s->msg_tail, msg); if (s->addrlen == sizeof (struct IPv4HttpAddress)) { @@ -876,17 +908,15 @@ server_v4_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (cls != NULL); plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - +#if 0 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Running IPv4 server\n"); - +#endif + plugin->server_v4_immediately = GNUNET_NO; GNUNET_assert (MHD_YES == MHD_run (plugin->server_v4)); - if (plugin->server_v4 != NULL) - plugin->server_v4_task = - server_schedule (plugin, plugin->server_v4, GNUNET_NO); + server_reschedule (plugin, plugin->server_v4, GNUNET_NO); } @@ -902,19 +932,16 @@ server_v6_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct Plugin *plugin = cls; GNUNET_assert (cls != NULL); - plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - +#if 0 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Running IPv6 server\n"); - +#endif + plugin->server_v6_immediately = GNUNET_NO; GNUNET_assert (MHD_YES == MHD_run (plugin->server_v6)); - if (plugin->server_v6 != NULL) - plugin->server_v6_task = - server_schedule (plugin, plugin->server_v6, GNUNET_NO); + server_reschedule (plugin, plugin->server_v6, GNUNET_NO); } /** @@ -936,7 +963,7 @@ server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, struct GNUNET_NETWORK_FDSet *wws; struct GNUNET_NETWORK_FDSet *wes; int max; - unsigned long long timeout; + unsigned MHD_LONG_LONG timeout; static unsigned long long last_timeout = 0; int haveto; @@ -981,13 +1008,13 @@ server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, GNUNET_SCHEDULER_cancel (plugin->server_v4_task); plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK; } -#if VERBOSE_SERVER +#if 0 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Scheduling IPv4 server task in %llu ms\n", tv); #endif ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, tv, wrs, wws, + tv, wrs, wws, &server_v4_run, plugin); } if (daemon_handle == plugin->server_v6) @@ -997,13 +1024,13 @@ server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, GNUNET_SCHEDULER_cancel (plugin->server_v6_task); plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK; } -#if VERBOSE_SERVER +#if 0 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Scheduling IPv6 server task in %llu ms\n", tv); #endif ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, tv, wrs, wws, + tv, wrs, wws, &server_v6_run, plugin); } GNUNET_NETWORK_fdset_destroy (wrs); @@ -1017,6 +1044,8 @@ server_start (struct Plugin *plugin) { int res = GNUNET_OK; unsigned int timeout; + p = plugin; + GNUNET_assert (NULL != plugin); #if BUILD_HTTPS res = server_load_certificate (plugin); @@ -1133,13 +1162,9 @@ server_start (struct Plugin *plugin) return GNUNET_SYSERR; } server_reschedule (plugin, plugin->server_v6, GNUNET_NO); - - -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "%s server component started on port %u\n", plugin->name, plugin->port); -#endif return res; } @@ -1206,16 +1231,16 @@ server_stop (struct Plugin *plugin) s = t; } + p = NULL; + #if BUILD_HTTPS GNUNET_free_non_null (plugin->crypto_init); GNUNET_free_non_null (plugin->cert); GNUNET_free_non_null (plugin->key); #endif -#if DEBUG_HTTP GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "%s server component stopped\n", plugin->name); -#endif } diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 2b2d728..af5c715 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2002--2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -39,9 +39,14 @@ #include "gnunet_transport_plugin.h" #include "transport.h" -#define DEBUG_TCP GNUNET_EXTRA_LOGGING +#define LOG(kind,...) GNUNET_log_from (kind, "transport-tcp",__VA_ARGS__) + +/** + * How long until we give up on establishing an NAT connection? + * Must be > 4 RTT + */ +#define NAT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) -#define DEBUG_TCP_NAT GNUNET_EXTRA_LOGGING GNUNET_NETWORK_STRUCT_BEGIN @@ -224,11 +229,6 @@ struct Session */ struct SessionHeader header; - /** - * Stored in a linked list. - */ - struct Session *next; - /** * Pointer to the global plugin struct. */ @@ -239,6 +239,11 @@ struct Session */ struct GNUNET_SERVER_Client *client; + /** + * Task cleaning up a NAT client connection establishment attempt; + */ + GNUNET_SCHEDULER_TaskIdentifier nat_connection_timeout; + /** * Messages currently pending for transmission * to this peer, if any. @@ -254,7 +259,7 @@ struct Session /** * Handle for pending transmission request. */ - struct GNUNET_CONNECTION_TransmitHandle *transmit_handle; + struct GNUNET_SERVER_TransmitHandle *transmit_handle; /** * To whom are we talking to (set to our identity @@ -267,6 +272,11 @@ struct Session */ GNUNET_SCHEDULER_TaskIdentifier receive_delay_task; + /** + * Session timeout task + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + /** * Address of the other peer (either based on our 'connect' * call or on our 'accept' call). @@ -329,7 +339,10 @@ struct Plugin */ struct GNUNET_NAT_Handle *nat; - struct GNUNET_CONTAINER_MultiHashMap * sessionmap; + /** + * Map from peer identities to sessions for the given peer. + */ + struct GNUNET_CONTAINER_MultiHashMap *sessionmap; /** * Handle to the network service. @@ -391,6 +404,71 @@ struct Plugin }; +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s); + + +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s); + + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s); + + +/* DEBUG CODE */ +static const char * +tcp_address_to_string (void *cls, const void *addr, size_t addrlen); + + +static unsigned int sessions; + + +static void +inc_sessions (struct Plugin *plugin, struct Session *session, int line) +{ + sessions++; + unsigned int size = GNUNET_CONTAINER_multihashmap_size(plugin->sessionmap); + if (sessions != size) + LOG (GNUNET_ERROR_TYPE_DEBUG, "Inconsistent sessions %u <-> session map size: %u\n", + sessions, size); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%4i Session increased to %u (session map size: %u): `%s' `%s'\n", + line, + sessions, + size, + GNUNET_i2s (&session->target), + tcp_address_to_string (NULL, session->addr, session->addrlen)); +} + + +static void +dec_sessions (struct Plugin *plugin, struct Session *session, int line) +{ + GNUNET_assert (sessions > 0); + unsigned int size = GNUNET_CONTAINER_multihashmap_size(plugin->sessionmap); + sessions--; + if (sessions != size) + LOG (GNUNET_ERROR_TYPE_DEBUG, "Inconsistent sessions %u <-> session map size: %u\n", + sessions, size); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%4i Session decreased to %u (session map size: %u): `%s' `%s'\n", + line, + sessions, + size, + GNUNET_i2s (&session->target), + tcp_address_to_string (NULL, session->addr, session->addrlen)); +} +/* DEBUG CODE */ + + /** * Function to check if an inbound connection is acceptable. * Mostly used to limit the total number of open connections @@ -410,6 +488,8 @@ plugin_tcp_access_check (void *cls, { struct Plugin *plugin = cls; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Accepting new incoming TCP connection\n"); if (0 == plugin->max_connections) return GNUNET_NO; plugin->max_connections--; @@ -436,9 +516,9 @@ tcp_nat_port_map_callback (void *cls, int add_remove, void *arg; size_t args; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "NPMC called with %d for address `%s'\n", add_remove, - GNUNET_a2s (addr, addrlen)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "NPMC called with %d for address `%s'\n", add_remove, + GNUNET_a2s (addr, addrlen)); /* convert 'addr' to our internal format */ switch (addr->sa_family) { @@ -490,27 +570,26 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen) int af; uint16_t port; - if (addrlen == sizeof (struct IPv6TcpAddress)) + switch (addrlen) { + case sizeof (struct IPv6TcpAddress): t6 = addr; af = AF_INET6; port = ntohs (t6->t6_port); memcpy (&a6, &t6->ipv6_addr, sizeof (a6)); sb = &a6; - } - else if (addrlen == sizeof (struct IPv4TcpAddress)) - { + break; + case sizeof (struct IPv4TcpAddress): t4 = addr; af = AF_INET; port = ntohs (t4->t4_port); memcpy (&a4, &t4->ipv4_addr, sizeof (a4)); sb = &a4; - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "tcp", - _("Unexpected address length: %u bytes\n"), - (unsigned int) addrlen); + break; + default: + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Unexpected address length: %u bytes\n"), + (unsigned int) addrlen); GNUNET_break (0); return NULL; } @@ -525,15 +604,88 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen) } +/** + * Function called to convert a string address to + * a binary address. + * + * @param cls closure ('struct Plugin*') + * @param addr string address + * @param addrlen length of the address + * @param buf location to store the buffer + * @param added location to store the number of bytes in the buffer. + * If the function returns GNUNET_SYSERR, its contents are undefined. + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +static int +tcp_string_to_address (void *cls, const char *addr, uint16_t addrlen, + void **buf, size_t *added) +{ + struct sockaddr_storage socket_address; + + if ((NULL == addr) || (addrlen == 0)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if ('\0' != addr[addrlen - 1]) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (strlen (addr) != addrlen - 1) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + GNUNET_STRINGS_to_address_ip (addr, strlen (addr), + &socket_address)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + switch (socket_address.ss_family) + { + case AF_INET: + { + struct IPv4TcpAddress *t4; + struct sockaddr_in *in4 = (struct sockaddr_in *) &socket_address; + + t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); + t4->ipv4_addr = in4->sin_addr.s_addr; + t4->t4_port = in4->sin_port; + *buf = t4; + *added = sizeof (struct IPv4TcpAddress); + return GNUNET_OK; + } + case AF_INET6: + { + struct IPv6TcpAddress *t6; + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &socket_address; + t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); + t6->ipv6_addr = in6->sin6_addr; + t6->t6_port = in6->sin6_port; + *buf = t6; + *added = sizeof (struct IPv6TcpAddress); + return GNUNET_OK; + } + default: + return GNUNET_SYSERR; + } +} + + struct SessionClientCtx { const struct GNUNET_SERVER_Client *client; struct Session *ret; }; -int session_lookup_by_client_it (void *cls, - const GNUNET_HashCode * key, - void *value) + +static int +session_lookup_by_client_it (void *cls, + const GNUNET_HashCode * key, + void *value) { struct SessionClientCtx *sc_ctx = cls; struct Session *s = value; @@ -546,6 +698,7 @@ int session_lookup_by_client_it (void *cls, return GNUNET_YES; } + /** * Find the session handle for the given client. * @@ -555,14 +708,13 @@ int session_lookup_by_client_it (void *cls, */ static struct Session * lookup_session_by_client (struct Plugin *plugin, - const struct GNUNET_SERVER_Client *client) + const struct GNUNET_SERVER_Client *client) { struct SessionClientCtx sc_ctx; + sc_ctx.client = client; sc_ctx.ret = NULL; - GNUNET_CONTAINER_multihashmap_iterate (plugin->sessionmap, &session_lookup_by_client_it, &sc_ctx); - return sc_ctx.ret; } @@ -572,7 +724,7 @@ lookup_session_by_client (struct Plugin *plugin, * * @param plugin the plugin * @param target peer to connect to - * @param client client to use + * @param client client to use, reference counter must have already been increased * @param is_nat this a NAT session, we should wait for a client to * connect to us from an address, then assign that to * the session @@ -586,15 +738,14 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, struct PendingMessage *pm; struct WelcomeMessage welcome; - if (is_nat != GNUNET_YES) - GNUNET_assert (client != NULL); + if (GNUNET_YES != is_nat) + GNUNET_assert (NULL != client); else - GNUNET_assert (client == NULL); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Creating new session for peer `%4s'\n", - GNUNET_i2s (target)); + GNUNET_assert (NULL == client); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Creating new session for peer `%4s'\n", + GNUNET_i2s (target)); ret = GNUNET_malloc (sizeof (struct Session)); ret->last_activity = GNUNET_TIME_absolute_get (); ret->plugin = plugin; @@ -617,10 +768,14 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, pm->message_size, GNUNET_NO); GNUNET_CONTAINER_DLL_insert (ret->pending_messages_head, ret->pending_messages_tail, pm); - if (is_nat != GNUNET_YES) + if (GNUNET_YES != is_nat) + { GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop ("# TCP sessions active"), 1, GNUNET_NO); + } + start_session_timeout (ret); + return ret; } @@ -659,16 +814,14 @@ do_transmit (void *cls, size_t size, void *buf) char *cbuf; size_t ret; - GNUNET_assert (session != NULL); + GNUNET_assert (NULL != session); session->transmit_handle = NULL; plugin = session->plugin; - if (buf == NULL) + if (NULL == buf) { -#if DEBUG_TCP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Timeout trying to transmit to peer `%4s', discarding message queue.\n", - GNUNET_i2s (&session->target)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Timeout trying to transmit to peer `%4s', discarding message queue.\n", + GNUNET_i2s (&session->target)); /* timeout; cancel all messages that have already expired */ hd = NULL; tl = NULL; @@ -679,11 +832,9 @@ do_transmit (void *cls, size_t size, void *buf) { GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, session->pending_messages_tail, pos); -#if DEBUG_TCP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Failed to transmit %u byte message to `%4s'.\n", - pos->message_size, GNUNET_i2s (&session->target)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Failed to transmit %u byte message to `%4s'.\n", + pos->message_size, GNUNET_i2s (&session->target)); ret += pos->message_size; GNUNET_CONTAINER_DLL_insert_after (hd, tl, tl, pos); } @@ -722,9 +873,9 @@ do_transmit (void *cls, size_t size, void *buf) GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, session->pending_messages_tail, pos); GNUNET_assert (size >= pos->message_size); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Transmitting message of type %u\n", - ntohs (((struct GNUNET_MessageHeader *) pos->msg)->type)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Transmitting message of type %u\n", + ntohs (((struct GNUNET_MessageHeader *) pos->msg)->type)); /* FIXME: this memcpy can be up to 7% of our total runtime */ memcpy (cbuf, pos->msg, pos->message_size); cbuf += pos->message_size; @@ -749,10 +900,8 @@ do_transmit (void *cls, size_t size, void *buf) } GNUNET_assert (hd == NULL); GNUNET_assert (tl == NULL); -#if DEBUG_TCP > 1 - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", "Transmitting %u bytes\n", + LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u bytes\n", ret); -#endif GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop ("# bytes currently in TCP buffers"), -(int64_t) ret, GNUNET_NO); @@ -801,31 +950,44 @@ disconnect_session (struct Session *session) struct PendingMessage *pm; struct Plugin * plugin = session->plugin; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Disconnecting session %p for peer `%s' address `%s'\n", - session, - GNUNET_i2s (&session->target), - tcp_address_to_string(NULL, session->addr, session->addrlen)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Disconnecting session of peer `%s' address `%s'\n", + GNUNET_i2s (&session->target), + tcp_address_to_string (NULL, session->addr, session->addrlen)); - GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(plugin->sessionmap, &session->target.hashPubKey, session)); + stop_session_timeout (session); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (plugin->sessionmap, &session->target.hashPubKey, session)) + { + GNUNET_STATISTICS_update (session->plugin->env->stats, + gettext_noop ("# TCP sessions active"), -1, + GNUNET_NO); + dec_sessions (plugin, session, __LINE__); + } + else GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (plugin->nat_wait_conns, &session->target.hashPubKey, session)); /* clean up state */ if (session->transmit_handle != NULL) { - GNUNET_CONNECTION_notify_transmit_ready_cancel (session->transmit_handle); + GNUNET_SERVER_notify_transmit_ready_cancel (session->transmit_handle); session->transmit_handle = NULL; } session->plugin->env->session_end (session->plugin->env->cls, &session->target, session); + + if (GNUNET_SCHEDULER_NO_TASK != session->nat_connection_timeout) + { + GNUNET_SCHEDULER_cancel (session->nat_connection_timeout); + session->nat_connection_timeout = GNUNET_SCHEDULER_NO_TASK; + } + while (NULL != (pm = session->pending_messages_head)) { -#if DEBUG_TCP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - pm->transmit_cont != - NULL ? "Could not deliver message to `%4s'.\n" : - "Could not deliver message to `%4s', notifying.\n", - GNUNET_i2s (&session->target)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + pm->transmit_cont != + NULL ? "Could not deliver message to `%4s'.\n" : + "Could not deliver message to `%4s', notifying.\n", + GNUNET_i2s (&session->target)); GNUNET_STATISTICS_update (session->plugin->env->stats, gettext_noop ("# bytes currently in TCP buffers"), -(int64_t) pm->message_size, GNUNET_NO); @@ -840,21 +1002,18 @@ disconnect_session (struct Session *session) GNUNET_SYSERR); GNUNET_free (pm); } - GNUNET_break (session->client != NULL); if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (session->receive_delay_task); - if (session->client != NULL) + if (NULL != session->client) GNUNET_SERVER_receive_done (session->client, GNUNET_SYSERR); } - if (session->client != NULL) + if (NULL != session->client) { + GNUNET_SERVER_client_disconnect (session->client); GNUNET_SERVER_client_drop (session->client); session->client = NULL; } - GNUNET_STATISTICS_update (session->plugin->env->stats, - gettext_noop ("# TCP sessions active"), -1, - GNUNET_NO); GNUNET_free_non_null (session->addr); GNUNET_assert (NULL == session->transmit_handle); GNUNET_free (session); @@ -899,15 +1058,9 @@ tcp_plugin_send (void *cls, struct Plugin * plugin = cls; struct PendingMessage *pm; - GNUNET_assert (plugin != NULL); - GNUNET_assert (session != NULL); - GNUNET_assert (session->client != NULL); + GNUNET_assert (NULL != plugin); + GNUNET_assert (NULL != session); - GNUNET_SERVER_client_set_timeout (session->client, - GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); - GNUNET_STATISTICS_update (plugin->env->stats, - gettext_noop ("# bytes currently in TCP buffers"), - msgbuf_size, GNUNET_NO); /* create new message entry */ pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size); pm->msg = (const char *) &pm[1]; @@ -917,40 +1070,79 @@ tcp_plugin_send (void *cls, pm->transmit_cont = cont; pm->transmit_cont_cls = cont_cls; - /* append pm to pending_messages list */ - GNUNET_CONTAINER_DLL_insert_tail (session->pending_messages_head, - session->pending_messages_tail, pm); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Asked to transmit %u bytes to `%s', added message to list.\n", + msgbuf_size, GNUNET_i2s (&session->target)); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Asked to transmit %u bytes to `%s', added message to list.\n", - msgbuf_size, GNUNET_i2s (&session->target)); + reschedule_session_timeout (session); - process_pending_messages (session); - return msgbuf_size; + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value(plugin->sessionmap, &session->target.hashPubKey, session)) + { + GNUNET_assert (session->client != NULL); + + GNUNET_SERVER_client_set_timeout (session->client, + GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# bytes currently in TCP buffers"), + msgbuf_size, GNUNET_NO); + + /* append pm to pending_messages list */ + GNUNET_CONTAINER_DLL_insert_tail (session->pending_messages_head, + session->pending_messages_tail, pm); + + process_pending_messages (session); + return msgbuf_size; + } + else if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value(plugin->nat_wait_conns, &session->target.hashPubKey, session)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "This NAT WAIT session for peer `%s' is not yet ready!\n", + GNUNET_i2s (&session->target)); + + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# bytes currently in TCP buffers"), + msgbuf_size, GNUNET_NO); + + /* append pm to pending_messages list */ + GNUNET_CONTAINER_DLL_insert_tail (session->pending_messages_head, + session->pending_messages_tail, pm); + return msgbuf_size; + } + else + { + if (NULL != cont) + cont (cont_cls, &session->target, GNUNET_SYSERR); + GNUNET_break (0); + GNUNET_free (pm); + return GNUNET_SYSERR; /* session does not exist here */ + } } + struct SessionItCtx { - void * addr; + void *addr; size_t addrlen; - struct Session * result; + struct Session *result; }; -int session_lookup_it (void *cls, - const GNUNET_HashCode * key, - void *value) + +static int +session_lookup_it (void *cls, + const GNUNET_HashCode *key, + void *value) { struct SessionItCtx * si_ctx = cls; struct Session * session = value; #if 0 char * a1 = strdup (tcp_address_to_string(NULL, session->addr, session->addrlen)); char * a2 = strdup (tcp_address_to_string(NULL, si_ctx->addr, si_ctx->addrlen)); - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "tcp", - "Comparing: %s %u <-> %s %u\n", - a1, - session->addrlen, - a2, - si_ctx->addrlen); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Comparing: %s %u <-> %s %u\n", + a1, + session->addrlen, + a2, + si_ctx->addrlen); GNUNET_free (a1); GNUNET_free (a2); #endif @@ -965,12 +1157,12 @@ int session_lookup_it (void *cls, #if 0 a1 = strdup (tcp_address_to_string(NULL, session->addr, session->addrlen)); a2 = strdup (tcp_address_to_string(NULL, si_ctx->addr, si_ctx->addrlen)); - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "tcp", - "Comparing: %s %u <-> %s %u , OK!\n", - a1, - session->addrlen, - a2, - si_ctx->addrlen); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Comparing: %s %u <-> %s %u , OK!\n", + a1, + session->addrlen, + a2, + si_ctx->addrlen); GNUNET_free (a1); GNUNET_free (a2); #endif @@ -980,6 +1172,21 @@ int session_lookup_it (void *cls, } +/** + * Task cleaning up a NAT connection attempt after timeout + */ +static void +nat_connect_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Session *session = cls; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "NAT WAIT connection to `%4s' at `%s' could not be established, removing session\n", + GNUNET_i2s (&session->target), tcp_address_to_string(NULL, session->addr, session->addrlen)); + disconnect_session (session); +} + + /** * Create a new session to transmit data to the target * This session will used to send data to this peer and the plugin will @@ -991,11 +1198,10 @@ int session_lookup_it (void *cls, */ static struct Session * tcp_plugin_get_session (void *cls, - const struct GNUNET_HELLO_Address *address) + const struct GNUNET_HELLO_Address *address) { struct Plugin * plugin = cls; struct Session * session = NULL; - int af; const void *sb; size_t sbs; @@ -1006,20 +1212,19 @@ tcp_plugin_get_session (void *cls, const struct IPv6TcpAddress *t6; struct GNUNET_ATS_Information ats; unsigned int is_natd = GNUNET_NO; - size_t addrlen = 0; + size_t addrlen; GNUNET_assert (plugin != NULL); GNUNET_assert (address != NULL); - addrlen = address->address_length; - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Trying to get session for `%s' address length %i\n", - tcp_address_to_string(NULL, address->address, address->address_length), - addrlen); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Trying to get session for `%s' address of peer `%s'\n", + tcp_address_to_string(NULL, address->address, address->address_length), + GNUNET_i2s (&address->peer)); /* look for existing session */ - if (GNUNET_CONTAINER_multihashmap_contains(plugin->sessionmap, &address->peer.hashPubKey)) + if (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_contains(plugin->sessionmap, &address->peer.hashPubKey)) { struct SessionItCtx si_ctx; @@ -1032,13 +1237,17 @@ tcp_plugin_get_session (void *cls, if (si_ctx.result != NULL) { session = si_ctx.result; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Found exisiting session for `%s' address `%s' session %p\n", - GNUNET_i2s (&address->peer), - tcp_address_to_string(NULL, address->address, address->address_length), - session); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found exisiting session for `%s' address `%s' session %p\n", + GNUNET_i2s (&address->peer), + tcp_address_to_string(NULL, address->address, address->address_length), + session); return session; } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Existing sessions did not match address `%s' or peer `%s'\n", + tcp_address_to_string(NULL, address->address, address->address_length), + GNUNET_i2s (&address->peer)); } if (addrlen == sizeof (struct IPv6TcpAddress)) @@ -1077,8 +1286,8 @@ tcp_plugin_get_session (void *cls, } else { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "tcp", - _("Address of unexpected length: %u\n"), addrlen); + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Address of unexpected length: %u\n"), addrlen); GNUNET_break (0); return NULL; } @@ -1111,26 +1320,34 @@ tcp_plugin_get_session (void *cls, GNUNET_CONTAINER_multihashmap_contains (plugin->nat_wait_conns, &address->peer.hashPubKey))) { -#if DEBUG_TCP_NAT - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - _("Found valid IPv4 NAT address (creating session)!\n")); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found valid IPv4 NAT address (creating session)!\n") ; session = create_session (plugin, &address->peer, NULL, GNUNET_YES); session->addrlen = 0; session->addr = NULL; session->ats_address_network_type = ats.value; + session->nat_connection_timeout = GNUNET_SCHEDULER_add_delayed(NAT_TIMEOUT, + &nat_connect_timeout, + session); GNUNET_assert (session != NULL); - GNUNET_assert (GNUNET_CONTAINER_multihashmap_put (plugin->nat_wait_conns, &address->peer.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) == GNUNET_OK); -#if DEBUG_TCP_NAT - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Created NAT WAIT connection to `%4s' at `%s'\n", - GNUNET_i2s (&session->target), GNUNET_a2s (sb, sbs)); -#endif - GNUNET_NAT_run_client (plugin->nat, &a4); - return session; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Created NAT WAIT connection to `%4s' at `%s'\n", + GNUNET_i2s (&session->target), GNUNET_a2s (sb, sbs)); + + if (GNUNET_OK == GNUNET_NAT_run_client (plugin->nat, &a4)) + return session; + else + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Running NAT client for `%4s' at `%s' failed\n", + GNUNET_i2s (&session->target), GNUNET_a2s (sb, sbs)); + disconnect_session (session); + return NULL; + } } /* create new outbound session */ @@ -1138,18 +1355,16 @@ tcp_plugin_get_session (void *cls, sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs); if (sa == NULL) { -#if DEBUG_TCP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Failed to create connection to `%4s' at `%s'\n", - GNUNET_i2s (&session->target), GNUNET_a2s (sb, sbs)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Failed to create connection to `%4s' at `%s'\n", + GNUNET_i2s (&session->target), GNUNET_a2s (sb, sbs)); return NULL; } plugin->max_connections--; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", - GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", + GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); session = create_session (plugin, &address->peer, @@ -1161,13 +1376,12 @@ tcp_plugin_get_session (void *cls, session->ats_address_network_type = ats.value; GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &address->peer.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Creating new session for `%s' address `%s' session %p\n", - GNUNET_i2s (&address->peer), - tcp_address_to_string(NULL, address->address, address->address_length), - session); - + inc_sessions (plugin, session, __LINE__); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Creating new session for `%s' address `%s' session %p\n", + GNUNET_i2s (&address->peer), + tcp_address_to_string(NULL, address->address, address->address_length), + session); /* Send TCP Welcome */ process_pending_messages (session); @@ -1175,9 +1389,10 @@ tcp_plugin_get_session (void *cls, } -int session_disconnect_it (void *cls, - const GNUNET_HashCode * key, - void *value) +static int +session_disconnect_it (void *cls, + const GNUNET_HashCode * key, + void *value) { struct Session *session = value; @@ -1189,25 +1404,6 @@ int session_disconnect_it (void *cls, return GNUNET_YES; } -int session_nat_disconnect_it (void *cls, - const GNUNET_HashCode * key, - void *value) -{ - struct Session *session = value; - - if (session != NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Cleaning up pending NAT session for peer `%4s'\n", GNUNET_i2s (&session->target)); - GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (session->plugin->nat_wait_conns, &session->target.hashPubKey, session)); - GNUNET_SERVER_client_drop (session->client); - GNUNET_SERVER_receive_done (session->client, GNUNET_SYSERR); - GNUNET_free (session); - } - - return GNUNET_YES; -} - /** * Function that can be called to force a disconnect from the @@ -1229,23 +1425,11 @@ static void tcp_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) { struct Plugin *plugin = cls; - struct Session *nat_session = NULL; - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Disconnecting peer `%4s'\n", GNUNET_i2s (target)); - GNUNET_CONTAINER_multihashmap_get_multiple (plugin->sessionmap, &target->hashPubKey, session_disconnect_it, plugin); - - nat_session = GNUNET_CONTAINER_multihashmap_get(plugin->nat_wait_conns, &target->hashPubKey); - if (nat_session != NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Cleaning up pending NAT session for peer `%4s'\n", GNUNET_i2s (target)); - GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (plugin->nat_wait_conns, &target->hashPubKey, nat_session)); - GNUNET_SERVER_client_drop (nat_session->client); - GNUNET_SERVER_receive_done (nat_session->client, GNUNET_SYSERR); - GNUNET_free (nat_session); - } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Disconnecting peer `%4s'\n", GNUNET_i2s (target)); + GNUNET_CONTAINER_multihashmap_get_multiple (plugin->sessionmap, &target->hashPubKey, &session_disconnect_it, plugin); + GNUNET_CONTAINER_multihashmap_get_multiple (plugin->nat_wait_conns, &target->hashPubKey, &session_disconnect_it, plugin); } @@ -1268,6 +1452,8 @@ struct PrettyPrinterContext * Port to add after the IP address. */ uint16_t port; + + int ipv6; }; @@ -1289,7 +1475,10 @@ append_port (void *cls, const char *hostname) GNUNET_free (ppc); return; } - GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port); + if (GNUNET_YES == ppc->ipv6) + GNUNET_asprintf (&ret, "[%s]:%d", hostname, ppc->port); + else + GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port); ppc->asc (ppc->asc_cls, ret); GNUNET_free (ret); } @@ -1348,6 +1537,12 @@ tcp_plugin_address_pretty_printer (void *cls, const char *type, sb = &a4; sbs = sizeof (a4); } + else if (0 == addrlen) + { + asc (asc_cls, ""); + asc (asc_cls, NULL); + return; + } else { /* invalid address */ @@ -1356,6 +1551,10 @@ tcp_plugin_address_pretty_printer (void *cls, const char *type, return; } ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); + if (addrlen == sizeof (struct IPv6TcpAddress)) + ppc->ipv6 = GNUNET_YES; + else + ppc->ipv6 = GNUNET_NO; ppc->asc = asc; ppc->asc_cls = asc_cls; ppc->port = port; @@ -1462,7 +1661,7 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client, const struct sockaddr_in *s4; const struct sockaddr_in6 *s6; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", "received NAT probe\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, "received NAT probe\n"); /* We have received a TCP NAT probe, meaning we (hopefully) initiated * a connection to this peer by running gnunet-nat-client. This peer @@ -1493,36 +1692,39 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client, clientIdentity.hashPubKey); if (session == NULL) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Did NOT find session for NAT probe!\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Did NOT find session for NAT probe!\n"); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Found session for NAT probe!\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found session for NAT probe!\n"); + + if (session->nat_connection_timeout != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (session->nat_connection_timeout); + session->nat_connection_timeout = GNUNET_SCHEDULER_NO_TASK; + } - GNUNET_assert (GNUNET_CONTAINER_multihashmap_remove - (plugin->nat_wait_conns, - &tcp_nat_probe->clientIdentity.hashPubKey, - session) == GNUNET_YES); if (GNUNET_OK != GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) { GNUNET_break (0); - GNUNET_free (session); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + disconnect_session (session); return; } - - GNUNET_SERVER_client_keep (client); - session->client = client; + GNUNET_assert (GNUNET_CONTAINER_multihashmap_remove + (plugin->nat_wait_conns, + &tcp_nat_probe->clientIdentity.hashPubKey, + session) == GNUNET_YES); + GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, + &session->target.hashPubKey, session, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); session->last_activity = GNUNET_TIME_absolute_get (); session->inbound = GNUNET_NO; - -#if DEBUG_TCP_NAT - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Found address `%s' for incoming connection\n", - GNUNET_a2s (vaddr, alen)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found address `%s' for incoming connection\n", + GNUNET_a2s (vaddr, alen)); switch (((const struct sockaddr *) vaddr)->sa_family) { case AF_INET: @@ -1543,20 +1745,18 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client, break; default: GNUNET_break_op (0); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Bad address for incoming connection!\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Bad address for incoming connection!\n"); GNUNET_free (vaddr); - - GNUNET_SERVER_client_drop (client); - GNUNET_free (session); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + disconnect_session (session); return; } GNUNET_free (vaddr); - - GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &session->target.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - + GNUNET_break (NULL == session->client); + GNUNET_SERVER_client_keep (client); + session->client = client; + inc_sessions (plugin, session, __LINE__); GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop ("# TCP sessions active"), 1, GNUNET_NO); @@ -1595,23 +1795,21 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Received %s message from `%4s'\n", "WELCOME", - GNUNET_i2s (&wm->clientIdentity)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received %s message from `%4s'\n", "WELCOME", + GNUNET_i2s (&wm->clientIdentity)); GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop ("# TCP WELCOME messages received"), 1, GNUNET_NO); - session = lookup_session_by_client (plugin, client); if (session != NULL) { if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Found existing session %p for peer `%s'\n", - session, - GNUNET_a2s (vaddr, alen)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found existing session %p for peer `%s'\n", + session, + GNUNET_a2s (vaddr, alen)); GNUNET_free (vaddr); } } @@ -1620,7 +1818,6 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_client_keep (client); session = create_session (plugin, &wm->clientIdentity, client, GNUNET_NO); session->inbound = GNUNET_YES; - if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) { if (alen == sizeof (struct sockaddr_in)) @@ -1650,12 +1847,11 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client, } else { -#if DEBUG_TCP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Did not obtain TCP socket address for incoming connection\n"); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Did not obtain TCP socket address for incoming connection\n"); } GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &wm->clientIdentity.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + inc_sessions (plugin, session, __LINE__); } if (session->expecting_welcome != GNUNET_YES) @@ -1695,6 +1891,8 @@ delayed_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) session->plugin->env->receive (session->plugin->env->cls, &session->target, NULL, &ats, 0, session, NULL, 0); + reschedule_session_timeout (session); + if (delay.rel_value == 0) GNUNET_SERVER_receive_done (session->client, GNUNET_OK); else @@ -1732,21 +1930,40 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client, if (NULL == session) { /* No inbound session found */ + void *vaddr; + size_t alen; + + GNUNET_SERVER_client_get_address (client, &vaddr, &alen); + LOG (GNUNET_ERROR_TYPE_ERROR, + "Received unexpected %u bytes of type %u from `%s'\n", + (unsigned int) ntohs (message->size), + (unsigned int) ntohs (message->type), + GNUNET_a2s(vaddr, alen)); GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + GNUNET_free_non_null(vaddr); return; } else if (GNUNET_YES == session->expecting_welcome) { /* Session is expecting WELCOME message */ + void *vaddr; + size_t alen; + + GNUNET_SERVER_client_get_address (client, &vaddr, &alen); + LOG (GNUNET_ERROR_TYPE_ERROR, + "Received unexpected %u bytes of type %u from `%s'\n", + (unsigned int) ntohs (message->size), + (unsigned int) ntohs (message->type), + GNUNET_a2s(vaddr, alen)); GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + GNUNET_free_non_null(vaddr); return; } session->last_activity = GNUNET_TIME_absolute_get (); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", + LOG (GNUNET_ERROR_TYPE_DEBUG, "Passing %u bytes of type %u from `%4s' to transport service.\n", (unsigned int) ntohs (message->size), (unsigned int) ntohs (message->type), @@ -1763,6 +1980,10 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client, distance[1].value = session->ats_address_network_type; GNUNET_break (ntohl(session->ats_address_network_type) != GNUNET_ATS_NET_UNSPECIFIED); + GNUNET_assert (GNUNET_CONTAINER_multihashmap_contains_value (plugin->sessionmap, + &session->target.hashPubKey, + session)); + delay = plugin->env->receive (plugin->env->cls, &session->target, message, @@ -1770,18 +1991,19 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client, 1, session, (GNUNET_YES == session->inbound) ? NULL : session->addr, (GNUNET_YES == session->inbound) ? 0 : session->addrlen); + + reschedule_session_timeout (session); + if (delay.rel_value == 0) { GNUNET_SERVER_receive_done (client, GNUNET_OK); } else { -#if DEBUG_TCP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Throttling receiving from `%s' for %llu ms\n", - GNUNET_i2s (&session->target), - (unsigned long long) delay.rel_value); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Throttling receiving from `%s' for %llu ms\n", + GNUNET_i2s (&session->target), + (unsigned long long) delay.rel_value); GNUNET_SERVER_disable_receive_done_warning (client); session->receive_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session); @@ -1808,16 +2030,14 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) session = lookup_session_by_client (plugin, client); if (session == NULL) return; /* unknown, nothing to do */ -#if DEBUG_TCP - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", - "Destroying session of `%4s' with %s due to network-level disconnect.\n", - GNUNET_i2s (&session->target), - (session->addr != - NULL) ? tcp_address_to_string (session->plugin, - session->addr, - session->addrlen) : - "*"); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Destroying session of `%4s' with %s due to network-level disconnect.\n", + GNUNET_i2s (&session->target), + (session->addr != + NULL) ? tcp_address_to_string (session->plugin, + session->addr, + session->addrlen) : + "*"); GNUNET_STATISTICS_update (session->plugin->env->stats, gettext_noop ("# network-level TCP disconnect events"), 1, @@ -1846,7 +2066,7 @@ notify_send_probe (void *cls, size_t size, void *buf) tcp_probe_ctx); if (buf == NULL) { - GNUNET_CONNECTION_destroy (tcp_probe_ctx->sock, GNUNET_NO); + GNUNET_CONNECTION_destroy (tcp_probe_ctx->sock); GNUNET_free (tcp_probe_ctx); return 0; } @@ -1912,6 +2132,91 @@ try_connection_reversal (void *cls, const struct sockaddr *addr, } +/** + * Session was idle, so disconnect it + */ +static void +session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_assert (NULL != cls); + struct Session *s = cls; + + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Session %p was idle for %llu, disconnecting\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + /* call session destroy function */ + disconnect_session(s); +} + + +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Timeout for session %p set to %llu\n", + s, + GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + + +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + if (GNUNET_SCHEDULER_NO_TASK == s->timeout_task) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Timeout for peer `%s' %s not scheduled\n", + GNUNET_i2s (&s->target), + tcp_address_to_string(NULL, s->addr, s->addrlen)); + return; + } + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p set to %llu\n", + s, + (unsigned long long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) + { + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Timeout rescheduled for session %p canceled\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Timeout for session %p was not active\n", + s); + } +} + + /** * Entry point for the plugin. * @@ -1942,6 +2247,18 @@ libgnunet_plugin_transport_tcp_init (void *cls) struct sockaddr **addrs; socklen_t *addrlens; + if (NULL == env->receive) + { + /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully + initialze the plugin or the API */ + api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); + api->cls = NULL; + api->address_pretty_printer = &tcp_plugin_address_pretty_printer; + api->address_to_string = &tcp_address_to_string; + api->string_to_address = &tcp_string_to_address; + return api; + } + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-tcp", "MAX_CONNECTIONS", @@ -1957,10 +2274,10 @@ libgnunet_plugin_transport_tcp_init (void *cls) "ADVERTISED-PORT", &aport)) && (aport > 65535))) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "tcp", - _ - ("Require valid port number for service `%s' in configuration!\n"), - "transport-tcp"); + LOG (GNUNET_ERROR_TYPE_ERROR, + _ + ("Require valid port number for service `%s' in configuration!\n"), + "transport-tcp"); return NULL; } if (aport == 0) @@ -1969,19 +2286,17 @@ libgnunet_plugin_transport_tcp_init (void *cls) aport = 0; if (bport != 0) { - service = GNUNET_SERVICE_start ("transport-tcp", env->cfg); + service = GNUNET_SERVICE_start ("transport-tcp", env->cfg, GNUNET_SERVICE_OPTION_NONE); if (service == NULL) { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "tcp", - _("Failed to start service.\n")); + LOG (GNUNET_ERROR_TYPE_WARNING, + _("Failed to start service.\n")); return NULL; } } else service = NULL; - - plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->sessionmap = GNUNET_CONTAINER_multihashmap_create(max_connections); plugin->max_connections = max_connections; @@ -2024,6 +2339,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) api->address_pretty_printer = &tcp_plugin_address_pretty_printer; api->check_address = &tcp_plugin_check_address; api->address_to_string = &tcp_address_to_string; + api->string_to_address = &tcp_string_to_address; plugin->service = service; if (service != NULL) { @@ -2035,9 +2351,9 @@ libgnunet_plugin_transport_tcp_init (void *cls) GNUNET_CONFIGURATION_get_value_time (env->cfg, "transport-tcp", "TIMEOUT", &idle_timeout)) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "tcp", - _("Failed to find option %s in section %s!\n"), - "TIMEOUT", "transport-tcp"); + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Failed to find option %s in section %s!\n"), + "TIMEOUT", "transport-tcp"); if (plugin->nat != NULL) GNUNET_NAT_unregister (plugin->nat); GNUNET_free (plugin); @@ -2058,17 +2374,21 @@ libgnunet_plugin_transport_tcp_init (void *cls) GNUNET_SERVER_disconnect_notify (plugin->server, &disconnect_notify, plugin); plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create (16); if (bport != 0) - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "tcp", - _("TCP transport listening on port %llu\n"), bport); + LOG (GNUNET_ERROR_TYPE_INFO, + _("TCP transport listening on port %llu\n"), bport); else - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "tcp", - _ - ("TCP transport not listening on any port (client only)\n")); + LOG (GNUNET_ERROR_TYPE_INFO, + _ + ("TCP transport not listening on any port (client only)\n")); if (aport != bport) - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "tcp", + LOG (GNUNET_ERROR_TYPE_INFO, _ ("TCP transport advertises itself as being on port %llu\n"), aport); + /* Initially set connections to 0 */ + GNUNET_STATISTICS_set(plugin->env->stats, + gettext_noop ("# TCP sessions active"), 0, + GNUNET_NO); return api; } @@ -2083,13 +2403,17 @@ libgnunet_plugin_transport_tcp_done (void *cls) struct Plugin *plugin = api->cls; struct TCPProbeContext *tcp_probe; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", "Shutting down TCP plugin\n"); - + if (NULL == plugin) + { + GNUNET_free (api); + return NULL; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down TCP plugin\n"); /* Removing leftover sessions */ GNUNET_CONTAINER_multihashmap_iterate(plugin->sessionmap, &session_disconnect_it, NULL); /* Removing leftover NAT sessions */ - GNUNET_CONTAINER_multihashmap_iterate(plugin->nat_wait_conns, &session_nat_disconnect_it, NULL); + GNUNET_CONTAINER_multihashmap_iterate(plugin->nat_wait_conns, &session_disconnect_it, NULL); if (plugin->service != NULL) GNUNET_SERVICE_stop (plugin->service); @@ -2102,7 +2426,7 @@ libgnunet_plugin_transport_tcp_done (void *cls) { GNUNET_CONTAINER_DLL_remove (plugin->probe_head, plugin->probe_tail, tcp_probe); - GNUNET_CONNECTION_destroy (tcp_probe->sock, GNUNET_NO); + GNUNET_CONNECTION_destroy (tcp_probe->sock); GNUNET_free (tcp_probe); } GNUNET_CONTAINER_multihashmap_destroy (plugin->nat_wait_conns); diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 7141563..c5a4c7b 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c @@ -85,6 +85,7 @@ struct PrettyPrinterContext uint16_t port; }; + struct Session { /** @@ -92,13 +93,13 @@ struct Session */ struct GNUNET_PeerIdentity target; + struct FragmentationContext * frag_ctx; + /** * Address of the other peer */ const struct sockaddr *sock_addr; - size_t addrlen; - /** * Desired delay for next sending we send to other peer */ @@ -109,15 +110,24 @@ struct Session */ struct GNUNET_TIME_Absolute flow_delay_from_other_peer; + /** + * Session timeout task + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + /** * expected delay for ACKs */ struct GNUNET_TIME_Relative last_expected_delay; - struct GNUNET_ATS_Information ats; - struct FragmentationContext * frag_ctx; + size_t addrlen; + + + unsigned int rc; + + int in_destroy; }; @@ -143,12 +153,12 @@ struct SourceInformation */ const void *arg; + struct Session *session; /** * Number of bytes in source address. */ size_t args; - struct Session *session; }; @@ -167,12 +177,13 @@ struct FindReceiveContext */ const struct sockaddr *addr; + struct Session *session; + /** * Number of bytes in 'addr'. */ socklen_t addr_len; - struct Session *session; }; @@ -225,9 +236,6 @@ struct FragmentationContext struct GNUNET_FRAGMENT_Context * frag; struct Session * session; - struct GNUNET_TIME_Absolute timeout; - - /** * Function to call upon completion of the transmission. */ @@ -238,6 +246,8 @@ struct FragmentationContext */ void *cont_cls; + struct GNUNET_TIME_Absolute timeout; + size_t bytes_to_send; }; @@ -248,9 +258,6 @@ struct UDPMessageWrapper struct UDPMessageWrapper *prev; struct UDPMessageWrapper *next; char *udp; - size_t msg_size; - - struct GNUNET_TIME_Absolute timeout; /** * Function to call upon completion of the transmission. @@ -264,6 +271,9 @@ struct UDPMessageWrapper struct FragmentationContext *frag_ctx; + size_t msg_size; + + struct GNUNET_TIME_Absolute timeout; }; @@ -289,6 +299,12 @@ struct UDP_ACK_Message }; +/** + * Encapsulation of all of the state of the plugin. + */ +struct Plugin * plugin; + + /** * We have been notified that our readset has something to read. We don't * know which socket needs to be read, so we have to check each one @@ -300,6 +316,7 @@ struct UDP_ACK_Message static void udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + /** * We have been notified that our readset has something to read. We don't * know which socket needs to be read, so we have to check each one @@ -311,6 +328,27 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); static void udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s); + +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s); + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s); + + + /** * Function called for a quick conversion of the binary address to * a numeric address. Note that the caller must not free the @@ -363,6 +401,77 @@ udp_address_to_string (void *cls, const void *addr, size_t addrlen) } +/** + * Function called to convert a string address to + * a binary address. + * + * @param cls closure ('struct Plugin*') + * @param addr string address + * @param addrlen length of the address + * @param buf location to store the buffer + * @param added location to store the number of bytes in the buffer. + * If the function returns GNUNET_SYSERR, its contents are undefined. + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +static int +udp_string_to_address (void *cls, const char *addr, uint16_t addrlen, + void **buf, size_t *added) +{ + struct sockaddr_storage socket_address; + + if ((NULL == addr) || (0 == addrlen)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + if ('\0' != addr[addrlen - 1]) + { + return GNUNET_SYSERR; + } + + if (strlen (addr) != addrlen - 1) + { + return GNUNET_SYSERR; + } + + if (GNUNET_OK != GNUNET_STRINGS_to_address_ip (addr, strlen (addr), + &socket_address)) + { + return GNUNET_SYSERR; + } + + switch (socket_address.ss_family) + { + case AF_INET: + { + struct IPv4UdpAddress *u4; + struct sockaddr_in *in4 = (struct sockaddr_in *) &socket_address; + u4 = GNUNET_malloc (sizeof (struct IPv4UdpAddress)); + u4->ipv4_addr = in4->sin_addr.s_addr; + u4->u4_port = in4->sin_port; + *buf = u4; + *added = sizeof (struct IPv4UdpAddress); + return GNUNET_OK; + } + case AF_INET6: + { + struct IPv6UdpAddress *u6; + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &socket_address; + u6 = GNUNET_malloc (sizeof (struct IPv6UdpAddress)); + u6->ipv6_addr = in6->sin6_addr; + u6->u6_port = in6->sin6_port; + *buf = u6; + *added = sizeof (struct IPv6UdpAddress); + return GNUNET_OK; + } + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } +} + + /** * Append our port and forward the result. * @@ -446,6 +555,12 @@ udp_plugin_address_pretty_printer (void *cls, const char *type, sb = &a4; sbs = sizeof (a4); } + else if (0 == addrlen) + { + asc (asc_cls, ""); + asc (asc_cls, NULL); + return; + } else { /* invalid address */ @@ -461,6 +576,21 @@ udp_plugin_address_pretty_printer (void *cls, const char *type, } +static void +call_continuation (struct UDPMessageWrapper *udpw, int result) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Calling continuation for %u byte message to `%s' with result %s\n", + udpw->msg_size, GNUNET_i2s (&udpw->session->target), + (GNUNET_OK == result) ? "OK" : "SYSERR"); + if (NULL != udpw->cont) + { + udpw->cont (udpw->cont_cls, &udpw->session->target,result); + } + +} + + /** * Check if the given port is plausible (must be either our listen * port or our advertised port). If it is neither, we return @@ -479,7 +609,6 @@ check_port (struct Plugin *plugin, uint16_t in_port) } - /** * Function that will be called to check if a binary address for this * plugin is well-formed and corresponds to an address for THIS peer @@ -539,75 +668,105 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen) /** - * Destroy a session, plugin is being unloaded. + * Task to free resources associated with a session. * - * @param cls unused - * @param key hash of public key of target peer - * @param value a 'struct PeerSession*' to clean up - * @return GNUNET_OK (continue to iterate) + * @param s session to free */ -static int -disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value) +static void +free_session (struct Session *s) +{ + if (s->frag_ctx != NULL) + { + GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag); + GNUNET_free (s->frag_ctx); + s->frag_ctx = NULL; + } + GNUNET_free (s); +} + + +/** + * Functions with this signature are called whenever we need + * to close a session due to a disconnect or failure to + * establish a connection. + * + * @param s session to close down + */ +static void +disconnect_session (struct Session *s) { - struct Plugin *plugin = cls; - struct Session *s = value; struct UDPMessageWrapper *udpw; struct UDPMessageWrapper *next; -#if DEBUG_UDP + GNUNET_assert (GNUNET_YES != s->in_destroy); LOG (GNUNET_ERROR_TYPE_DEBUG, "Session %p to peer `%s' address ended \n", s, GNUNET_i2s (&s->target), GNUNET_a2s (s->sock_addr, s->addrlen)); -#endif - - if (s->frag_ctx != NULL) - { - GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag); - GNUNET_free (s->frag_ctx); - s->frag_ctx = NULL; - } - - udpw = plugin->ipv4_queue_head; - while (udpw != NULL) + stop_session_timeout(s); + next = plugin->ipv4_queue_head; + while (NULL != (udpw = next)) { next = udpw->next; if (udpw->session == s) { GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); - - if (udpw->cont != NULL) - udpw->cont (udpw->cont_cls, &s->target, GNUNET_SYSERR); + call_continuation(udpw, GNUNET_SYSERR); GNUNET_free (udpw); } - udpw = next; } - - udpw = plugin->ipv6_queue_head; - while (udpw != NULL) + next = plugin->ipv6_queue_head; + while (NULL != (udpw = next)) { next = udpw->next; if (udpw->session == s) { GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw); - - if (udpw->cont != NULL) - udpw->cont (udpw->cont_cls, &s->target, GNUNET_SYSERR); + call_continuation(udpw, GNUNET_SYSERR); GNUNET_free (udpw); } udpw = next; } - plugin->env->session_end (plugin->env->cls, &s->target, s); + if (NULL != s->frag_ctx) + { + if (NULL != s->frag_ctx->cont) + { + s->frag_ctx->cont (s->frag_ctx->cont_cls, &s->target, GNUNET_SYSERR); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Calling continuation for fragemented message to `%s' with result SYSERR\n", + GNUNET_i2s (&s->target)); + } + } + GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (plugin->sessions, &s->target.hashPubKey, s)); + GNUNET_STATISTICS_set(plugin->env->stats, + "# UDP sessions active", + GNUNET_CONTAINER_multihashmap_size(plugin->sessions), + GNUNET_NO); + if (s->rc > 0) + s->in_destroy = GNUNET_YES; + else + free_session (s); +} - - GNUNET_free (s); +/** + * Destroy a session, plugin is being unloaded. + * + * @param cls unused + * @param key hash of public key of target peer + * @param value a 'struct PeerSession*' to clean up + * @return GNUNET_OK (continue to iterate) + */ +static int +disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value) +{ + disconnect_session(value); return GNUNET_OK; } @@ -626,14 +785,13 @@ udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) GNUNET_assert (plugin != NULL); GNUNET_assert (target != NULL); -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from peer `%s'\n", GNUNET_i2s (target)); -#endif /* Clean up sessions */ GNUNET_CONTAINER_multihashmap_get_multiple (plugin->sessions, &target->hashPubKey, &disconnect_and_free_it, plugin); } + static struct Session * create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, const void *addr, size_t addrlen, @@ -688,20 +846,19 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, GNUNET_break_op (0); return NULL; } - s->addrlen = len; s->target = *target; s->sock_addr = (const struct sockaddr *) &s[1]; - s->flow_delay_for_other_peer = GNUNET_TIME_relative_get_zero(); - s->flow_delay_from_other_peer = GNUNET_TIME_absolute_get_zero(); s->last_expected_delay = GNUNET_TIME_UNIT_SECONDS; - + start_session_timeout(s); return s; } -static int session_cmp_it (void *cls, - const GNUNET_HashCode * key, - void *value) + +static int +session_cmp_it (void *cls, + const GNUNET_HashCode * key, + void *value) { struct SessionCompareContext * cctx = cls; const struct GNUNET_HELLO_Address *address = cctx->addr; @@ -709,12 +866,9 @@ static int session_cmp_it (void *cls, socklen_t s_addrlen = s->addrlen; -#if VERBOSE_UDP - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing address %s <-> %s\n", + LOG (GNUNET_ERROR_TYPE_DEBUG, "Comparing address %s <-> %s\n", udp_address_to_string (NULL, (void *) address->address, address->address_length), GNUNET_a2s (s->sock_addr, s->addrlen)); -#endif - if ((address->address_length == sizeof (struct IPv4UdpAddress)) && (s_addrlen == sizeof (struct sockaddr_in))) { @@ -742,8 +896,6 @@ static int session_cmp_it (void *cls, return GNUNET_NO; } } - - return GNUNET_YES; } @@ -799,15 +951,14 @@ udp_plugin_get_session (void *cls, struct SessionCompareContext cctx; cctx.addr = address; cctx.res = NULL; -#if VERBOSE_UDP - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for existing session for peer `%s' `%s' \n", GNUNET_i2s (&address->peer), udp_address_to_string(NULL, address->address, address->address_length)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Looking for existing session for peer `%s' `%s' \n", + GNUNET_i2s (&address->peer), + udp_address_to_string(NULL, address->address, address->address_length)); GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessions, &address->peer.hashPubKey, session_cmp_it, &cctx); if (cctx.res != NULL) { -#if VERBOSE_UDP - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing session %p\n", cctx.res); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, "Found existing session %p\n", cctx.res); return cctx.res; } @@ -817,23 +968,28 @@ udp_plugin_get_session (void *cls, address->address, address->address_length, NULL, NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating new session %p for peer `%s' address `%s'\n", - s, - GNUNET_i2s(&address->peer), - udp_address_to_string(NULL,address->address,address->address_length)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Creating new session %p for peer `%s' address `%s'\n", + s, + GNUNET_i2s(&address->peer), + udp_address_to_string(NULL,address->address,address->address_length)); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (plugin->sessions, &s->target.hashPubKey, s, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); + GNUNET_STATISTICS_set(plugin->env->stats, + "# UDP sessions active", + GNUNET_CONTAINER_multihashmap_size(plugin->sessions), + GNUNET_NO); + return s; } -static void enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw) + +static void +enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw) { if (udpw->session->addrlen == sizeof (struct sockaddr_in)) @@ -842,6 +998,26 @@ static void enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw) GNUNET_CONTAINER_DLL_insert(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw); } + +/** + * Fragment message was transmitted via UDP, let fragmentation know + * to send the next fragment now. + * + * @param cls the 'struct UDPMessageWrapper' of the fragment + * @param target destination peer (ignored) + * @param result GNUNET_OK on success (ignored) + */ +static void +send_next_fragment (void *cls, + const struct GNUNET_PeerIdentity *target, + int result) +{ + struct UDPMessageWrapper *udpw = cls; + + GNUNET_FRAGMENT_context_transmission_done (udpw->frag_ctx->frag); +} + + /** * Function that is called with messages created by the fragmentation * module. In the case of the 'proc' callback of the @@ -858,28 +1034,23 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) struct Plugin *plugin = frag_ctx->plugin; struct UDPMessageWrapper * udpw; struct Session *s; - size_t msg_len = ntohs (msg->size); -#if VERBOSE_UDP - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Enqueuing fragment with %u bytes %u\n", msg_len , sizeof (struct UDPMessageWrapper)); -#endif - + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Enqueuing fragment with %u bytes %u\n", msg_len , sizeof (struct UDPMessageWrapper)); udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + msg_len); udpw->session = frag_ctx->session; s = udpw->session; udpw->udp = (char *) &udpw[1]; udpw->msg_size = msg_len; - udpw->cont = frag_ctx->cont; - udpw->cont_cls = frag_ctx->cont_cls; + udpw->cont = &send_next_fragment; + udpw->cont_cls = udpw; udpw->timeout = frag_ctx->timeout; udpw->frag_ctx = frag_ctx; memcpy (udpw->udp, msg, msg_len); - enqueue (plugin, udpw); - if (s->addrlen == sizeof (struct sockaddr_in)) { if (plugin->with_v4_ws == GNUNET_NO) @@ -889,7 +1060,6 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs_v4, plugin->ws_v4, @@ -897,7 +1067,6 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) plugin->with_v4_ws = GNUNET_YES; } } - else if (s->addrlen == sizeof (struct sockaddr_in6)) { if (plugin->with_v6_ws == GNUNET_NO) @@ -907,7 +1076,6 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) plugin->select_task_v6 = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs_v6, plugin->ws_v6, @@ -915,12 +1083,9 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) plugin->with_v6_ws = GNUNET_YES; } } - } - - /** * Function that can be used by the transport service to transmit * a message using the plugin. Note that in the case of a @@ -958,7 +1123,6 @@ udp_plugin_send (void *cls, { struct Plugin *plugin = cls; size_t mlen = msgbuf_size + sizeof (struct UDPMessage); - struct UDPMessageWrapper * udpw; struct UDPMessage *udp; char mbuf[mlen]; @@ -967,29 +1131,24 @@ udp_plugin_send (void *cls, if ((s->addrlen == sizeof (struct sockaddr_in6)) && (plugin->sockv6 == NULL)) return GNUNET_SYSERR; - - if ((s->addrlen == sizeof (struct sockaddr_in)) && (plugin->sockv4 == NULL)) - return GNUNET_SYSERR; - - + if ((s->addrlen == sizeof (struct sockaddr_in)) && (plugin->sockv4 == NULL)) + return GNUNET_SYSERR; if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) { GNUNET_break (0); return GNUNET_SYSERR; } - if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains_value(plugin->sessions, &s->target.hashPubKey, s)) { GNUNET_break (0); return GNUNET_SYSERR; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "UDP transmits %u-byte message to `%s' using address `%s'\n", - msgbuf_size, - GNUNET_i2s (&s->target), - GNUNET_a2s(s->sock_addr, s->addrlen)); - + mlen, + GNUNET_i2s (&s->target), + GNUNET_a2s(s->sock_addr, s->addrlen)); + /* Message */ udp = (struct UDPMessage *) mbuf; udp->header.size = htons (mlen); @@ -997,6 +1156,7 @@ udp_plugin_send (void *cls, udp->reserved = htonl (0); udp->sender = *plugin->env->my_identity; + reschedule_session_timeout(s); if (mlen <= UDP_MTU) { udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + mlen); @@ -1007,7 +1167,6 @@ udp_plugin_send (void *cls, udpw->cont = cont; udpw->cont_cls = cont_cls; udpw->frag_ctx = NULL; - memcpy (udpw->udp, udp, sizeof (struct UDPMessage)); memcpy (&udpw->udp[sizeof (struct UDPMessage)], msgbuf, msgbuf_size); @@ -1037,7 +1196,6 @@ udp_plugin_send (void *cls, frag_ctx); s->frag_ctx = frag_ctx; - } if (s->addrlen == sizeof (struct sockaddr_in)) @@ -1049,7 +1207,6 @@ udp_plugin_send (void *cls, plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs_v4, plugin->ws_v4, @@ -1057,7 +1214,6 @@ udp_plugin_send (void *cls, plugin->with_v4_ws = GNUNET_YES; } } - else if (s->addrlen == sizeof (struct sockaddr_in6)) { if (plugin->with_v6_ws == GNUNET_NO) @@ -1067,7 +1223,6 @@ udp_plugin_send (void *cls, plugin->select_task_v6 = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs_v6, plugin->ws_v6, @@ -1135,7 +1290,7 @@ udp_nat_port_map_callback (void *cls, int add_remove, * @param client the 'struct SourceInformation' * @param hdr the actual message */ -static void +static int process_inbound_tokenized_messages (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) { @@ -1145,20 +1300,23 @@ process_inbound_tokenized_messages (void *cls, void *client, struct GNUNET_TIME_Relative delay; GNUNET_assert (si->session != NULL); + if (GNUNET_YES == si->session->in_destroy) + return GNUNET_OK; /* setup ATS */ ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); ats[0].value = htonl (1); ats[1] = si->session->ats; GNUNET_break (ntohl(ats[1].value) != GNUNET_ATS_NET_UNSPECIFIED); - delay = plugin->env->receive (plugin->env->cls, - &si->sender, - hdr, - (const struct GNUNET_ATS_Information *) &ats, 2, - NULL, - si->arg, - si->args); + &si->sender, + hdr, + (const struct GNUNET_ATS_Information *) &ats, 2, + NULL, + si->arg, + si->args); si->session->flow_delay_for_other_peer = delay; + reschedule_session_timeout(si->session); + return GNUNET_OK; } @@ -1176,7 +1334,7 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg, socklen_t sender_addr_len) { struct SourceInformation si; - struct Session * s = NULL; + struct Session * s; struct IPv4UdpAddress u4; struct IPv6UdpAddress u6; const void *arg; @@ -1215,12 +1373,10 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg, GNUNET_break (0); return; } -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message with %u bytes from peer `%s' at `%s'\n", (unsigned int) ntohs (msg->header.size), GNUNET_i2s (&msg->sender), GNUNET_a2s (sender_addr, sender_addr_len)); -#endif struct GNUNET_HELLO_Address * address = GNUNET_HELLO_address_allocate(&msg->sender, "udp", arg, args); s = udp_plugin_get_session(plugin, address); @@ -1231,10 +1387,13 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg, si.sender = msg->sender; si.arg = arg; si.args = args; - + s->rc++; GNUNET_SERVER_mst_receive (plugin->mst, &si, (const char *) &msg[1], ntohs (msg->header.size) - sizeof (struct UDPMessage), GNUNET_YES, GNUNET_NO); + s->rc--; + if ( (0 == s->rc) && (GNUNET_YES == s->in_destroy)) + free_session (s); } @@ -1290,14 +1449,17 @@ fragment_msg_proc (void *cls, const struct GNUNET_MessageHeader *msg) rc->src_addr, rc->addr_len); } + struct LookupContext { const struct sockaddr * addr; - size_t addrlen; struct Session *res; + + size_t addrlen; }; + static int lookup_session_by_addr_it (void *cls, const GNUNET_HashCode * key, void *value) { @@ -1313,6 +1475,7 @@ lookup_session_by_addr_it (void *cls, const GNUNET_HashCode * key, void *value) return GNUNET_YES; } + /** * Transmit an acknowledgement. * @@ -1324,7 +1487,6 @@ static void ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) { struct DefragContext *rc = cls; - size_t msize = sizeof (struct UDP_ACK_Message) + ntohs (msg->size); struct UDP_ACK_Message *udp_ack; uint32_t delay = 0; @@ -1340,12 +1502,12 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) &l_ctx); s = l_ctx.res; - GNUNET_assert (s != NULL); + if (NULL == s) + return; if (s->flow_delay_for_other_peer.rel_value <= UINT32_MAX) delay = s->flow_delay_for_other_peer.rel_value; -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ACK to `%s' including delay of %u ms\n", GNUNET_a2s (rc->src_addr, @@ -1353,16 +1515,11 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)), delay); -#endif udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + msize); - udpw->cont = NULL; - udpw->cont_cls = NULL; - udpw->frag_ctx = NULL; udpw->msg_size = msize; udpw->session = s; - udpw->timeout = GNUNET_TIME_absolute_get_forever(); + udpw->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; udpw->udp = (char *)&udpw[1]; - udp_ack = (struct UDP_ACK_Message *) udpw->udp; udp_ack->header.size = htons ((uint16_t) msize); udp_ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK); @@ -1374,10 +1531,11 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) } -static void read_process_msg (struct Plugin *plugin, - const struct GNUNET_MessageHeader *msg, - char *addr, - socklen_t fromlen) +static void +read_process_msg (struct Plugin *plugin, + const struct GNUNET_MessageHeader *msg, + const char *addr, + socklen_t fromlen) { if (ntohs (msg->size) < sizeof (struct UDPMessage)) { @@ -1386,18 +1544,19 @@ static void read_process_msg (struct Plugin *plugin, } process_udp_message (plugin, (const struct UDPMessage *) msg, (const struct sockaddr *) addr, fromlen); - return; } -static void read_process_ack (struct Plugin *plugin, - const struct GNUNET_MessageHeader *msg, - char *addr, - socklen_t fromlen) + +static void +read_process_ack (struct Plugin *plugin, + const struct GNUNET_MessageHeader *msg, + char *addr, + socklen_t fromlen) { const struct GNUNET_MessageHeader *ack; const struct UDP_ACK_Message *udp_ack; struct LookupContext l_ctx; - struct Session *s = NULL; + struct Session *s; struct GNUNET_TIME_Relative flow_delay; if (ntohs (msg->size) < @@ -1406,9 +1565,7 @@ static void read_process_ack (struct Plugin *plugin, GNUNET_break_op (0); return; } - udp_ack = (const struct UDP_ACK_Message *) msg; - l_ctx.addr = (const struct sockaddr *) addr; l_ctx.addrlen = fromlen; l_ctx.res = NULL; @@ -1436,35 +1593,33 @@ static void read_process_ack (struct Plugin *plugin, if (GNUNET_OK != GNUNET_FRAGMENT_process_ack (s->frag_ctx->frag, ack)) { -#if DEBUG_UDP - LOG (GNUNET_ERROR_TYPE_DEBUG, - "UDP processes %u-byte acknowledgement from `%s' at `%s'\n", - (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender), - GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "UDP processes %u-byte acknowledgement from `%s' at `%s'\n", + (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender), + GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); return; } -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "FULL MESSAGE ACKed\n", (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender), GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); -#endif s->last_expected_delay = GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag); - struct UDPMessageWrapper * udpw = NULL; + struct UDPMessageWrapper * udpw; + struct UDPMessageWrapper * tmp; if (s->addrlen == sizeof (struct sockaddr_in6)) { udpw = plugin->ipv6_queue_head; - while (udpw!= NULL) + while (NULL != udpw) { + tmp = udpw->next; if ((udpw->frag_ctx != NULL) && (udpw->frag_ctx == s->frag_ctx)) { GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw); GNUNET_free (udpw); } - udpw = udpw->next; + udpw = tmp; } } if (s->addrlen == sizeof (struct sockaddr_in)) @@ -1472,43 +1627,46 @@ static void read_process_ack (struct Plugin *plugin, udpw = plugin->ipv4_queue_head; while (udpw!= NULL) { + tmp = udpw->next; if ((udpw->frag_ctx != NULL) && (udpw->frag_ctx == s->frag_ctx)) { GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); GNUNET_free (udpw); } - udpw = udpw->next; + udpw = tmp; } } if (s->frag_ctx->cont != NULL) - s->frag_ctx->cont - (s->frag_ctx->cont_cls, &udp_ack->sender, GNUNET_OK); + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Calling continuation for fragmented message to `%s' with result %s\n", + GNUNET_i2s (&s->target), "OK"); + s->frag_ctx->cont (s->frag_ctx->cont_cls, &udp_ack->sender, GNUNET_OK); + } + GNUNET_free (s->frag_ctx); s->frag_ctx = NULL; - return; } -static void read_process_fragment (struct Plugin *plugin, - const struct GNUNET_MessageHeader *msg, - char *addr, - socklen_t fromlen) + +static void +read_process_fragment (struct Plugin *plugin, + const struct GNUNET_MessageHeader *msg, + char *addr, + socklen_t fromlen) { struct DefragContext *d_ctx; struct GNUNET_TIME_Absolute now; struct FindReceiveContext frc; - frc.rc = NULL; frc.addr = (const struct sockaddr *) addr; frc.addr_len = fromlen; -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "UDP processes %u-byte fragment from `%s'\n", (unsigned int) ntohs (msg->size), GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); -#endif - /* Lookup existing receive context for this address */ GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs, &find_receive_context, @@ -1532,19 +1690,17 @@ static void read_process_fragment (struct Plugin *plugin, GNUNET_CONTAINER_heap_insert (plugin->defrag_ctxs, d_ctx, (GNUNET_CONTAINER_HeapCostType) now.abs_value); -#if DEBUG_UDP - LOG (GNUNET_ERROR_TYPE_DEBUG, "Created new defragmentation context for %u-byte fragment from `%s'\n", - (unsigned int) ntohs (msg->size), - GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Created new defragmentation context for %u-byte fragment from `%s'\n", + (unsigned int) ntohs (msg->size), + GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); } else { -#if DEBUG_UDP - LOG (GNUNET_ERROR_TYPE_DEBUG, "Found existing defragmentation context for %u-byte fragment from `%s'\n", - (unsigned int) ntohs (msg->size), - GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found existing defragmentation context for %u-byte fragment from `%s'\n", + (unsigned int) ntohs (msg->size), + GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); } if (GNUNET_OK == GNUNET_DEFRAGMENT_process_fragment (d_ctx->defrag, msg)) @@ -1565,6 +1721,7 @@ static void read_process_fragment (struct Plugin *plugin, } } + /** * Read and process a message from the given socket. * @@ -1576,7 +1733,7 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) { socklen_t fromlen; char addr[32]; - char buf[65536]; + char buf[65536] GNUNET_ALIGN; ssize_t size; const struct GNUNET_MessageHeader *msg; @@ -1613,7 +1770,7 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) return; case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK: - read_process_ack (plugin, msg, addr, fromlen);; + read_process_ack (plugin, msg, addr, fromlen); return; case GNUNET_MESSAGE_TYPE_FRAGMENT: @@ -1626,14 +1783,13 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) } } -size_t + +static size_t udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) { ssize_t sent; size_t slen; struct GNUNET_TIME_Absolute max; - struct GNUNET_TIME_Absolute ; - struct UDPMessageWrapper *udpw = NULL; if (sock == plugin->sockv4) @@ -1660,25 +1816,21 @@ udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) if (max.abs_value != udpw->timeout.abs_value) { /* Message timed out */ - - if (udpw->cont != NULL) - udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR); + call_continuation(udpw, GNUNET_SYSERR); if (udpw->frag_ctx != NULL) { -#if DEBUG_UDP - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Fragmented message for peer `%s' with size %u timed out\n", - GNUNET_i2s(&udpw->session->target), udpw->frag_ctx->bytes_to_send); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Fragmented message for peer `%s' with size %u timed out\n", + GNUNET_i2s(&udpw->session->target), udpw->frag_ctx->bytes_to_send); udpw->session->last_expected_delay = GNUNET_FRAGMENT_context_destroy(udpw->frag_ctx->frag); GNUNET_free (udpw->frag_ctx); udpw->session->frag_ctx = NULL; } else { -#if DEBUG_UDP - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message for peer `%s' with size %u timed out\n", - GNUNET_i2s(&udpw->session->target), udpw->msg_size); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Message for peer `%s' with size %u timed out\n", + GNUNET_i2s(&udpw->session->target), udpw->msg_size); } if (sock == plugin->sockv4) @@ -1700,20 +1852,21 @@ udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) if (delta.rel_value == 0) { /* this message is not delayed */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message for peer `%s' (%u bytes) is not delayed \n", - GNUNET_i2s(&udpw->session->target), udpw->msg_size); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Message for peer `%s' (%u bytes) is not delayed \n", + GNUNET_i2s(&udpw->session->target), udpw->msg_size); break; } else { /* this message is delayed, try next */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message for peer `%s' (%u bytes) is delayed for %llu \n", - GNUNET_i2s(&udpw->session->target), udpw->msg_size, - delta); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Message for peer `%s' (%u bytes) is delayed for %llu \n", + GNUNET_i2s(&udpw->session->target), udpw->msg_size, + delta); udpw = udpw->next; } } - } if (udpw == NULL) @@ -1726,29 +1879,40 @@ udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) if (GNUNET_SYSERR == sent) { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "UDP transmitted %u-byte message to %s (%d: %s)\n", - (unsigned int) (udpw->msg_size), GNUNET_a2s (sa, slen), (int) sent, - (sent < 0) ? STRERROR (errno) : "ok"); - if (udpw->cont != NULL) - udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR); - } - LOG (GNUNET_ERROR_TYPE_DEBUG, - "UDP transmitted %u-byte message to %s (%d: %s)\n", - (unsigned int) (udpw->msg_size), GNUNET_a2s (sa, slen), (int) sent, - (sent < 0) ? STRERROR (errno) : "ok"); + const struct GNUNET_ATS_Information type = plugin->env->get_address_type + (plugin->env->cls,sa, slen); - /* This was just a message fragment */ - if (udpw->frag_ctx != NULL) - { - GNUNET_FRAGMENT_context_transmission_done (udpw->frag_ctx->frag); + if ((GNUNET_ATS_NET_WAN == type.value) && + ((ENETUNREACH == errno) || (ENETDOWN == errno))) + { + /* "Network unreachable" or "Network down" */ + /* + * This indicates that this system is IPv6 enabled, but does not + * have a valid global IPv6 address assigned + */ + LOG (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + _("UDP could not message to `%s': `%s'. " + "Please check your network configuration and disable IPv6 if your " + "connection does not have a global IPv6 address\n"), + GNUNET_a2s (sa, slen), + STRERROR (errno)); + } + else + { + LOG (GNUNET_ERROR_TYPE_ERROR, + "UDP could not transmit %u-byte message to `%s': `%s'\n", + (unsigned int) (udpw->msg_size), GNUNET_a2s (sa, slen), + STRERROR (errno)); + } + call_continuation(udpw, GNUNET_SYSERR); } - /* This was a complete message*/ else { - if (udpw->cont != NULL) - udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_OK); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "UDP transmitted %u-byte message to `%s' (%d: %s)\n", + (unsigned int) (udpw->msg_size), GNUNET_a2s (sa, slen), (int) sent, + (sent < 0) ? STRERROR (errno) : "ok"); + call_continuation(udpw, GNUNET_OK); } if (sock == plugin->sockv4) @@ -1761,6 +1925,7 @@ udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) return sent; } + /** * We have been notified that our readset has something to read. We don't * know which socket needs to be read, so we have to check each one @@ -1799,7 +1964,6 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (plugin->select_task); plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs_v4, (plugin->ipv4_queue_head != NULL) ? plugin->ws_v4 : NULL, @@ -1847,7 +2011,6 @@ udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (plugin->select_task_v6); plugin->select_task_v6 = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs_v6, (plugin->ipv6_queue_head != NULL) ? plugin->ws_v6 : NULL, @@ -1875,7 +2038,7 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct plugin->sockv6 = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0); if (NULL == plugin->sockv6) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Disabling IPv6 since it is not supported on this system!\n"); + LOG (GNUNET_ERROR_TYPE_WARNING, "Disabling IPv6 since it is not supported on this system!\n"); plugin->enable_ipv6 = GNUNET_NO; } else @@ -1888,20 +2051,16 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct serverAddrv6->sin6_port = htons (plugin->port); addrlen = sizeof (struct sockaddr_in6); serverAddr = (struct sockaddr *) serverAddrv6; -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv6 port %d\n", ntohs (serverAddrv6->sin6_port)); -#endif tries = 0; while (GNUNET_NETWORK_socket_bind (plugin->sockv6, serverAddr, addrlen) != GNUNET_OK) { serverAddrv6->sin6_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 Binding failed, trying new port %d\n", ntohs (serverAddrv6->sin6_port)); -#endif tries++; if (tries > 10) { @@ -1912,11 +2071,9 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct } if (plugin->sockv6 != NULL) { -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 socket created on port %d\n", ntohs (serverAddrv6->sin6_port)); -#endif addrs[sockets_created] = (struct sockaddr *) serverAddrv6; addrlens[sockets_created] = sizeof (struct sockaddr_in6); sockets_created++; @@ -1941,19 +2098,15 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct addrlen = sizeof (struct sockaddr_in); serverAddr = (struct sockaddr *) serverAddrv4; -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv4 port %d\n", ntohs (serverAddrv4->sin_port)); -#endif tries = 0; while (GNUNET_NETWORK_socket_bind (plugin->sockv4, serverAddr, addrlen) != GNUNET_OK) { serverAddrv4->sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv4 Binding failed, trying new port %d\n", ntohs (serverAddrv4->sin_port)); -#endif tries++; if (tries > 10) { @@ -1982,11 +2135,10 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct } if (sockets_created == 0) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n")); + LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n")); plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs_v4, NULL, @@ -2007,7 +2159,6 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct plugin->select_task_v6 = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs_v6, NULL, @@ -2024,6 +2175,82 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct return sockets_created; } +/** + * Session was idle, so disconnect it + */ +static void +session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_assert (NULL != cls); + struct Session *s = cls; + + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p was idle for %llu, disconnecting\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + + /* call session destroy function */ + disconnect_session(s); + +} + +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); + + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p set to %llu\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); + + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p set to %llu\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + + if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) + { + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p canceled\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p was not active\n", + s); + } +} /** * The exported method. Makes the core api available via a global and @@ -2037,8 +2264,7 @@ libgnunet_plugin_transport_udp_init (void *cls) { struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; struct GNUNET_TRANSPORT_PluginFunctions *api; - struct Plugin *plugin; - + struct Plugin *p; unsigned long long port; unsigned long long aport; unsigned long long broadcast; @@ -2047,12 +2273,24 @@ libgnunet_plugin_transport_udp_init (void *cls) char * bind4_address; char * bind6_address; struct GNUNET_TIME_Relative interval; - struct sockaddr_in serverAddrv4; struct sockaddr_in6 serverAddrv6; - int res; + if (NULL == env->receive) + { + /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully + initialze the plugin or the API */ + api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); + api->cls = NULL; + api->address_pretty_printer = &udp_plugin_address_pretty_printer; + api->address_to_string = &udp_address_to_string; + api->string_to_address = &udp_string_to_address; + return api; + } + + GNUNET_assert( NULL != env->stats); + /* Get port number */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp", "PORT", @@ -2080,7 +2318,6 @@ libgnunet_plugin_transport_udp_init (void *cls) else enable_v6 = GNUNET_YES; - /* Addresses */ memset (&serverAddrv6, 0, sizeof (serverAddrv6)); memset (&serverAddrv4, 0, sizeof (serverAddrv4)); @@ -2117,7 +2354,6 @@ libgnunet_plugin_transport_udp_init (void *cls) } } - /* Enable neighbour discovery */ broadcast = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, "transport-udp", "BROADCAST"); @@ -2137,56 +2373,60 @@ libgnunet_plugin_transport_udp_init (void *cls) udp_max_bps = 1024 * 1024 * 50; /* 50 MB/s == infinity for practical purposes */ } - plugin = GNUNET_malloc (sizeof (struct Plugin)); + p = GNUNET_malloc (sizeof (struct Plugin)); api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); - GNUNET_BANDWIDTH_tracker_init (&plugin->tracker, + GNUNET_BANDWIDTH_tracker_init (&p->tracker, GNUNET_BANDWIDTH_value_init ((uint32_t)udp_max_bps), 30); - - - plugin->sessions = GNUNET_CONTAINER_multihashmap_create (10); - plugin->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); - plugin->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, plugin); - plugin->port = port; - plugin->aport = aport; - plugin->broadcast_interval = interval; - plugin->enable_ipv6 = enable_v6; - plugin->env = env; - - api->cls = plugin; + p->sessions = GNUNET_CONTAINER_multihashmap_create (10); + p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); + p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, p); + p->port = port; + p->aport = aport; + p->broadcast_interval = interval; + p->enable_ipv6 = enable_v6; + p->env = env; + + plugin = p; + + api->cls = p; api->send = NULL; api->disconnect = &udp_disconnect; api->address_pretty_printer = &udp_plugin_address_pretty_printer; api->address_to_string = &udp_address_to_string; + api->string_to_address = &udp_string_to_address; api->check_address = &udp_plugin_check_address; api->get_session = &udp_plugin_get_session; api->send = &udp_plugin_send; LOG (GNUNET_ERROR_TYPE_DEBUG, "Setting up sockets\n"); - res = setup_sockets (plugin, &serverAddrv6, &serverAddrv4); - if ((res == 0) || ((plugin->sockv4 == NULL) && (plugin->sockv6 == NULL))) + res = setup_sockets (p, &serverAddrv6, &serverAddrv4); + if ((res == 0) || ((p->sockv4 == NULL) && (p->sockv6 == NULL))) { LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create network sockets, plugin failed\n"); - GNUNET_free (plugin); + GNUNET_free (p); GNUNET_free (api); return NULL; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting broadcasting\n"); if (broadcast == GNUNET_YES) - setup_broadcast (plugin, &serverAddrv6, &serverAddrv4); - + { + LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting broadcasting\n"); + setup_broadcast (p, &serverAddrv6, &serverAddrv4); + } GNUNET_free_non_null (bind4_address); GNUNET_free_non_null (bind6_address); return api; } -int heap_cleanup_iterator (void *cls, - struct GNUNET_CONTAINER_HeapNode * - node, void *element, - GNUNET_CONTAINER_HeapCostType - cost) + +static int +heap_cleanup_iterator (void *cls, + struct GNUNET_CONTAINER_HeapNode * + node, void *element, + GNUNET_CONTAINER_HeapCostType + cost) { struct DefragContext * d_ctx = element; @@ -2203,13 +2443,20 @@ int heap_cleanup_iterator (void *cls, * returns the udp transport API. * * @param cls our 'struct GNUNET_TRANSPORT_PluginEnvironment' - * @return our 'struct GNUNET_TRANSPORT_PluginFunctions' + * @return NULL */ void * libgnunet_plugin_transport_udp_done (void *cls) { struct GNUNET_TRANSPORT_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; + + if (NULL == plugin) + { + GNUNET_free (api); + return NULL; + } + stop_broadcast (plugin); if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) @@ -2263,8 +2510,7 @@ libgnunet_plugin_transport_udp_done (void *cls) { struct UDPMessageWrapper *tmp = udpw->next; GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); - if (udpw->cont != NULL) - udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR); + call_continuation(udpw, GNUNET_SYSERR); GNUNET_free (udpw); udpw = tmp; } @@ -2273,17 +2519,14 @@ libgnunet_plugin_transport_udp_done (void *cls) { struct UDPMessageWrapper *tmp = udpw->next; GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw); - if (udpw->cont != NULL) - udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR); + call_continuation(udpw, GNUNET_SYSERR); GNUNET_free (udpw); udpw = tmp; } /* Clean up sessions */ -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up sessions\n"); -#endif GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, &disconnect_and_free_it, plugin); GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions); diff --git a/src/transport/plugin_transport_udp_broadcasting.c b/src/transport/plugin_transport_udp_broadcasting.c index e33af26..baabf45 100644 --- a/src/transport/plugin_transport_udp_broadcasting.c +++ b/src/transport/plugin_transport_udp_broadcasting.c @@ -90,7 +90,7 @@ struct Mstv6Context -void +int broadcast_ipv6_mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message) { @@ -104,13 +104,11 @@ broadcast_ipv6_mst_cb (void *cls, void *client, if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON != ntohs (msg->header.type)) - return; -#if DEBUG_UDP_BROADCASTING + return GNUNET_OK; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received beacon with %u bytes from peer `%s' via address `%s'\n", ntohs (msg->header.size), GNUNET_i2s (&msg->sender), udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr))); -#endif struct GNUNET_ATS_Information atsi[2]; /* setup ATS */ @@ -130,9 +128,10 @@ broadcast_ipv6_mst_cb (void *cls, void *client, ("# IPv6 multicast HELLO beacons received via udp"), 1, GNUNET_NO); GNUNET_free (mc); + return GNUNET_OK; } -void +int broadcast_ipv4_mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message) { @@ -145,13 +144,11 @@ broadcast_ipv4_mst_cb (void *cls, void *client, if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON != ntohs (msg->header.type)) - return; -#if DEBUG_UDP_BROADCASTING + return GNUNET_OK; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received beacon with %u bytes from peer `%s' via address `%s'\n", ntohs (msg->header.size), GNUNET_i2s (&msg->sender), udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr))); -#endif struct GNUNET_ATS_Information atsi[2]; @@ -172,6 +169,7 @@ broadcast_ipv4_mst_cb (void *cls, void *client, ("# IPv4 broadcast HELLO beacons received via udp"), 1, GNUNET_NO); GNUNET_free (mc); + return GNUNET_OK; } void @@ -179,13 +177,11 @@ udp_broadcast_receive (struct Plugin *plugin, const char * buf, ssize_t size, st { struct GNUNET_ATS_Information ats; - if (addrlen == sizeof (struct sockaddr_in)) + if ((GNUNET_YES == plugin->broadcast_ipv4) && (addrlen == sizeof (struct sockaddr_in))) { -#if DEBUG_UDP_BROADCASTING LOG (GNUNET_ERROR_TYPE_DEBUG, "Received IPv4 HELLO beacon broadcast with %i bytes from address %s\n", size, GNUNET_a2s ((const struct sockaddr *) addr, addrlen)); -#endif struct Mstv4Context *mc; mc = GNUNET_malloc (sizeof (struct Mstv4Context)); @@ -195,18 +191,18 @@ udp_broadcast_receive (struct Plugin *plugin, const char * buf, ssize_t size, st mc->addr.u4_port = av4->sin_port; ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) addr, addrlen); mc->ats_address_network_type = ats.value; + + GNUNET_assert (NULL != plugin->broadcast_ipv4_mst); if (GNUNET_OK != GNUNET_SERVER_mst_receive (plugin->broadcast_ipv4_mst, mc, buf, size, GNUNET_NO, GNUNET_NO)) GNUNET_free (mc); } - else if (addrlen == sizeof (struct sockaddr_in6)) + else if ((GNUNET_YES == plugin->broadcast_ipv4) && (addrlen == sizeof (struct sockaddr_in6))) { -#if DEBUG_UDP_BROADCASTING LOG (GNUNET_ERROR_TYPE_DEBUG, "Received IPv6 HELLO beacon broadcast with %i bytes from address %s\n", size, GNUNET_a2s ((const struct sockaddr *) &addr, addrlen)); -#endif struct Mstv6Context *mc; mc = GNUNET_malloc (sizeof (struct Mstv6Context)); @@ -216,7 +212,7 @@ udp_broadcast_receive (struct Plugin *plugin, const char * buf, ssize_t size, st mc->addr.u6_port = av6->sin6_port; ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) addr, addrlen); mc->ats_address_network_type = ats.value; - + GNUNET_assert (NULL != plugin->broadcast_ipv4_mst); if (GNUNET_OK != GNUNET_SERVER_mst_receive (plugin->broadcast_ipv6_mst, mc, buf, size, GNUNET_NO, GNUNET_NO)) @@ -224,37 +220,42 @@ udp_broadcast_receive (struct Plugin *plugin, const char * buf, ssize_t size, st } } -static void -udp_ipv4_broadcast_send (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +static unsigned int +prepare_beacon (struct Plugin *plugin, struct UDP_Beacon_Message *msg) { - struct Plugin *plugin = cls; - int sent; - uint16_t msg_size; uint16_t hello_size; - char buf[65536]; + uint16_t msg_size; const struct GNUNET_MessageHeader *hello; - struct UDP_Beacon_Message *msg; - struct BroadcastAddress *baddr; - - plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; - hello = plugin->env->get_our_hello (); hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello); msg_size = hello_size + sizeof (struct UDP_Beacon_Message); if (hello_size < (sizeof (struct GNUNET_MessageHeader)) || (msg_size > (UDP_MTU))) - return; + return 0; - msg = (struct UDP_Beacon_Message *) buf; msg->sender = *(plugin->env->my_identity); - msg->header.size = ntohs (msg_size); - msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON); + msg->header.size = htons (msg_size); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON); memcpy (&msg[1], hello, hello_size); - sent = 0; + return msg_size; +} + +static void +udp_ipv4_broadcast_send (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Plugin *plugin = cls; + int sent; + uint16_t msg_size; + char buf[65536] GNUNET_ALIGN; + struct BroadcastAddress *baddr; + + plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; + msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *) &buf); + sent = 0; baddr = plugin->ipv4_broadcast_head; /* just IPv4 */ while ((baddr != NULL) && (baddr->addrlen == sizeof (struct sockaddr_in))) @@ -263,19 +264,16 @@ udp_ipv4_broadcast_send (void *cls, addr->sin_port = htons (plugin->port); - sent = - GNUNET_NETWORK_socket_sendto (plugin->sockv4, msg, msg_size, + sent = GNUNET_NETWORK_socket_sendto (plugin->sockv4, &buf, msg_size, (const struct sockaddr *) addr, baddr->addrlen); if (sent == GNUNET_SYSERR) GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); else { -#if DEBUG_UDP_BROADCASTING LOG (GNUNET_ERROR_TYPE_DEBUG, - "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent, + "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent, GNUNET_a2s (baddr->addr, baddr->addrlen)); -#endif } baddr = baddr->next; } @@ -292,31 +290,13 @@ udp_ipv6_broadcast_send (void *cls, struct Plugin *plugin = cls; int sent; uint16_t msg_size; - uint16_t hello_size; - char buf[65536]; - - const struct GNUNET_MessageHeader *hello; - struct UDP_Beacon_Message *msg; + char buf[65536] GNUNET_ALIGN; plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK; - hello = plugin->env->get_our_hello (); - hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello); - msg_size = hello_size + sizeof (struct UDP_Beacon_Message); - - if (hello_size < (sizeof (struct GNUNET_MessageHeader)) || - (msg_size > (UDP_MTU))) - return; - - msg = (struct UDP_Beacon_Message *) buf; - msg->sender = *(plugin->env->my_identity); - msg->header.size = ntohs (msg_size); - msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON); - memcpy (&msg[1], hello, hello_size); + msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *) &buf); sent = 0; - - sent = - GNUNET_NETWORK_socket_sendto (plugin->sockv6, msg, msg_size, + sent = GNUNET_NETWORK_socket_sendto (plugin->sockv6, &buf, msg_size, (const struct sockaddr *) &plugin->ipv6_multicast_address, sizeof (struct sockaddr_in6)); @@ -324,16 +304,12 @@ udp_ipv6_broadcast_send (void *cls, GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); else { -#if DEBUG_UDP_BROADCASTING LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending IPv6 HELLO beacon broadcast with %i bytes to address %s\n", sent, GNUNET_a2s ((const struct sockaddr *) &plugin->ipv6_multicast_address, sizeof (struct sockaddr_in6))); -#endif } - - plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, &udp_ipv6_broadcast_send, plugin); @@ -349,7 +325,6 @@ iface_proc (void *cls, const char *name, int isDefault, if (addr != NULL) { -#if DEBUG_UDP_BROADCASTING GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address %s for interface %s %p\n ", GNUNET_a2s (addr, addrlen), name, addr); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -357,7 +332,6 @@ iface_proc (void *cls, const char *name, int isDefault, GNUNET_a2s (broadcast_addr, addrlen), name, broadcast_addr); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ", GNUNET_a2s (netmask, addrlen), name, netmask); -#endif /* Collecting broadcast addresses */ if (broadcast_addr != NULL) @@ -450,9 +424,7 @@ setup_broadcast (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struc } else { -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 broadcasting running\n"); -#endif plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_add_now (&udp_ipv6_broadcast_send, plugin); plugin->broadcast_ipv6 = GNUNET_YES; @@ -503,9 +475,7 @@ stop_broadcast (struct Plugin *plugin) } else { -#if DEBUG_UDP LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 Broadcasting stopped\n"); -#endif } if (plugin->send_ipv6_broadcast_task != GNUNET_SCHEDULER_NO_TASK) diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c index 499cc23..057479d 100644 --- a/src/transport/plugin_transport_unix.c +++ b/src/transport/plugin_transport_unix.c @@ -42,9 +42,6 @@ #include "gnunet_transport_plugin.h" #include "transport.h" -#define DEBUG_UNIX GNUNET_EXTRALOGGING -#define DETAILS GNUNET_NO - #define MAX_PROBES 20 /* @@ -88,6 +85,13 @@ struct Session void *addr; size_t addrlen; struct GNUNET_PeerIdentity target; + + /** + * Session timeout task + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + + struct Plugin * plugin; }; struct UNIXMessageWrapper @@ -188,12 +192,7 @@ struct Plugin */ struct GNUNET_TRANSPORT_PluginEnvironment *env; - /* - * Session of peers with whom we are currently connected - */ - struct PeerSession *sessions; - - /* + /** * Sessions */ struct GNUNET_CONTAINER_MultiHashMap *session_map; @@ -242,30 +241,167 @@ struct Plugin * ATS network */ struct GNUNET_ATS_Information ats_network; + + unsigned int bytes_in_queue; + unsigned int bytes_in_sent; + unsigned int bytes_in_recv; + unsigned int bytes_discarded; }; +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s); -static int -get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value) +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s); + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s); + + +static void +unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + + +static void +reschedule_select (struct Plugin * plugin) { - struct Session *s = value; - struct Plugin *plugin = cls; - GNUNET_assert (plugin != NULL); -#if DEBUG_UNIX - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting session for peer `%s' `%s' \n", GNUNET_i2s (&s->target), s->addr); -#endif + if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (plugin->select_task); + plugin->select_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (NULL != plugin->msg_head) + { + plugin->select_task = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + GNUNET_TIME_UNIT_FOREVER_REL, + plugin->rs, + plugin->ws, + &unix_plugin_select, plugin); + plugin->with_ws = GNUNET_YES; + } + else + { + plugin->select_task = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + GNUNET_TIME_UNIT_FOREVER_REL, + plugin->rs, + NULL, + &unix_plugin_select, plugin); + plugin->with_ws = GNUNET_NO; + } +} + +struct LookupCtx +{ + struct Session *s; + const struct sockaddr_un *addr; +}; + +int lookup_session_it (void *cls, + const GNUNET_HashCode * key, + void *value) +{ + struct LookupCtx *lctx = cls; + struct Session *t = value; + + if (0 == strcmp (t->addr, lctx->addr->sun_path)) + { + lctx->s = t; + return GNUNET_NO; + } + return GNUNET_YES; +} + +static struct Session * +lookup_session (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, const struct sockaddr_un *addr) +{ + struct LookupCtx lctx; + + GNUNET_assert (NULL != plugin); + GNUNET_assert (NULL != sender); + GNUNET_assert (NULL != addr); + + lctx.s = NULL; + lctx.addr = addr; + + GNUNET_CONTAINER_multihashmap_get_multiple (plugin->session_map, &sender->hashPubKey, &lookup_session_it, &lctx); + + return lctx.s; +} + +/** + * Functions with this signature are called whenever we need + * to close a session due to a disconnect or failure to + * establish a connection. + * + * @param s session to close down + */ +static void +disconnect_session (struct Session *s) +{ + struct UNIXMessageWrapper *msgw; + struct UNIXMessageWrapper *next; + struct Plugin * plugin = s->plugin; + int removed; + GNUNET_assert (plugin != NULL); + GNUNET_assert (s != NULL); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting session for peer `%s' `%s' \n", GNUNET_i2s (&s->target), s->addr); + stop_session_timeout (s); plugin->env->session_end (plugin->env->cls, &s->target, s); + msgw = plugin->msg_head; + removed = GNUNET_NO; + next = plugin->msg_head; + while (NULL != next) + { + msgw = next; + next = msgw->next; + if (msgw->session != s) + continue; + GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw); + if (NULL != msgw->cont) + msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR); + GNUNET_free (msgw->msg); + GNUNET_free (msgw); + removed = GNUNET_YES; + } + if ((GNUNET_YES == removed) && (NULL == plugin->msg_head)) + reschedule_select (plugin); + GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove(plugin->session_map, &s->target.hashPubKey, s)); + GNUNET_CONTAINER_multihashmap_remove(plugin->session_map, &s->target.hashPubKey, s)); + + GNUNET_STATISTICS_set(plugin->env->stats, + "# UNIX sessions active", + GNUNET_CONTAINER_multihashmap_size(plugin->session_map), + GNUNET_NO); GNUNET_free (s); +} +static int +get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value) +{ + struct Session *s = value; + disconnect_session (s); return GNUNET_YES; } + /** * Disconnect from a remote node. Clean up session if we have one for this peer * @@ -273,7 +409,7 @@ get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value) * @param target the peeridentity of the peer to disconnect * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed */ -void +static void unix_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) { struct Plugin *plugin = cls; @@ -314,28 +450,14 @@ unix_transport_server_stop (void *cls) plugin->select_task = GNUNET_SCHEDULER_NO_TASK; } - GNUNET_break (GNUNET_OK == - GNUNET_NETWORK_socket_close (plugin->unix_sock.desc)); - plugin->unix_sock.desc = NULL; - plugin->with_ws = GNUNET_NO; - return GNUNET_OK; -} - - -struct PeerSession * -find_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *peer) -{ - struct PeerSession *pos; - - pos = plugin->sessions; - while (pos != NULL) + if (NULL != plugin->unix_sock.desc) { - if (memcmp (&pos->target, peer, sizeof (struct GNUNET_PeerIdentity)) == 0) - return pos; - pos = pos->next; + GNUNET_break (GNUNET_OK == + GNUNET_NETWORK_socket_close (plugin->unix_sock.desc)); + plugin->unix_sock.desc = NULL; + plugin->with_ws = GNUNET_NO; } - - return pos; + return GNUNET_OK; } @@ -369,7 +491,7 @@ unix_real_send (void *cls, size_t addrlen, GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) { - + struct Plugin *plugin = cls; ssize_t sent; const void *sb; size_t sbs; @@ -377,34 +499,31 @@ unix_real_send (void *cls, size_t slen; int retry; + GNUNET_assert (NULL != plugin); + if (send_handle == NULL) { -#if DEBUG_UNIX - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "unix_real_send with send_handle NULL!\n"); -#endif - /* failed to open send socket for AF */ + /* We do not have a send handle */ + GNUNET_break (0); if (cont != NULL) cont (cont_cls, target, GNUNET_SYSERR); - return 0; + return -1; } if ((addr == NULL) || (addrlen == 0)) { -#if DEBUG_UNIX - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "unix_real_send called without address, returning!\n"); -#endif + /* Can never send if we don't have an address */ + GNUNET_break (0); if (cont != NULL) cont (cont_cls, target, GNUNET_SYSERR); - return 0; /* Can never send if we don't have an address!! */ + return -1; } + /* Prepare address */ memset (&un, 0, sizeof (un)); un.sun_family = AF_UNIX; slen = strlen (addr) + 1; if (slen >= sizeof (un.sun_path)) slen = sizeof (un.sun_path) - 1; - sent = 0; GNUNET_assert (slen < sizeof (un.sun_path)); memcpy (un.sun_path, addr, slen); un.sun_path[slen] = '\0'; @@ -417,11 +536,17 @@ unix_real_send (void *cls, #endif sb = (struct sockaddr *) &un; sbs = slen; + + /* Send the data */ + sent = 0; retry = GNUNET_NO; sent = GNUNET_NETWORK_socket_sendto (send_handle, msgbuf, msgbuf_size, sb, sbs); if ((GNUNET_SYSERR == sent) && ((errno == EAGAIN) || (errno == ENOBUFS))) - retry = GNUNET_YES; + { + /* We have to retry later: retry */ + return 0; + } if ((GNUNET_SYSERR == sent) && (errno == EMSGSIZE)) { @@ -436,23 +561,38 @@ unix_real_send (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to increase socket buffer size from %i to %i for message size %i\n", - size, ((msgbuf_size / 1000) + 2) * 1000, msgbuf_size); + size, + ((msgbuf_size / 1000) + 2) * 1000, + msgbuf_size); size = ((msgbuf_size / 1000) + 2) * 1000; if (GNUNET_NETWORK_socket_setsockopt ((struct GNUNET_NETWORK_Handle *) send_handle, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) == GNUNET_OK) - retry = GNUNET_YES; + { + /* Increased buffer size, retry sending */ + return 0; + } else + { + /* Could not increase buffer size: error, no retry */ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt"); + return -1; + } + } + else + { + /* Buffer is bigger than message: error, no retry + * This should never happen!*/ + GNUNET_break (0); + return -1; } } -#if DEBUG_UNIX GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNIX transmit %u-byte message to %s (%d: %s)\n", (unsigned int) msgbuf_size, GNUNET_a2s (sb, sbs), (int) sent, (sent < 0) ? STRERROR (errno) : "ok"); -#endif + /* Calling continuation */ if (cont != NULL) { @@ -465,14 +605,20 @@ unix_real_send (void *cls, /* return number of bytes successfully sent */ if (sent > 0) return sent; + if (sent == 0) + { + /* That should never happen */ + GNUNET_break (0); + return -1; + } /* failed and retry: return 0 */ if ((GNUNET_SYSERR == sent) && (retry == GNUNET_YES)) return 0; /* failed and no retry: return -1 */ if ((GNUNET_SYSERR == sent) && (retry == GNUNET_NO)) return -1; - - return sent; + /* default */ + return -1; } struct gsi_ctx @@ -482,15 +628,14 @@ struct gsi_ctx struct Session *res; }; + static int get_session_it (void *cls, const GNUNET_HashCode * key, void *value) { struct gsi_ctx *gsi = cls; struct Session *s = value; -#if DEBUG_UNIX GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing session %s %s\n", gsi->address, s->addr); -#endif if ((gsi->addrlen == s->addrlen) && (0 == memcmp (gsi->address, s->addr, s->addrlen))) { @@ -527,27 +672,29 @@ unix_plugin_get_session (void *cls, GNUNET_CONTAINER_multihashmap_get_multiple (plugin->session_map, &address->peer.hashPubKey, &get_session_it, &gsi); if (gsi.res != NULL) { -#if DEBUG_UNIX GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing session\n"); -#endif return gsi.res; } /* Create a new session */ - s = GNUNET_malloc (sizeof (struct Session) + address->address_length); s->addr = &s[1]; s->addrlen = address->address_length; + s->plugin = plugin; memcpy(s->addr, address->address, s->addrlen); memcpy(&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity)); + start_session_timeout (s); + GNUNET_CONTAINER_multihashmap_put (plugin->session_map, &address->peer.hashPubKey, s, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); -#if DEBUG_UNIX - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating new session\n"); -#endif + GNUNET_STATISTICS_set(plugin->env->stats, + "# UNIX sessions active", + GNUNET_CONTAINER_multihashmap_size(plugin->session_map), + GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating new session\n"); return s; } @@ -609,7 +756,11 @@ unix_plugin_send (void *cls, if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_contains_value(plugin->session_map, &session->target.hashPubKey, session)) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid session for peer `%s' `%s'\n", + GNUNET_i2s (&session->target), + (char *) session->addr); GNUNET_break (0); + return GNUNET_SYSERR; } @@ -621,6 +772,8 @@ unix_plugin_send (void *cls, sizeof (struct GNUNET_PeerIdentity)); memcpy (&message[1], msgbuf, msgbuf_size); + reschedule_session_timeout (session); + wrapper = GNUNET_malloc (sizeof (struct UNIXMessageWrapper)); wrapper->msg = message; wrapper->msgsize = ssize; @@ -632,24 +785,15 @@ unix_plugin_send (void *cls, GNUNET_CONTAINER_DLL_insert(plugin->msg_head, plugin->msg_tail, wrapper); -#if DEBUG_UNIX + plugin->bytes_in_queue += ssize; + GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes in send queue", + plugin->bytes_in_queue, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent %d bytes to `%s'\n", ssize, (char *) session->addr); -#endif - if (plugin->with_ws == GNUNET_NO) { - if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel(plugin->select_task); - - plugin->select_task = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, - GNUNET_TIME_UNIT_FOREVER_REL, - plugin->rs, - plugin->ws, - &unix_plugin_select, plugin); - plugin->with_ws = GNUNET_YES; + reschedule_select (plugin); } return ssize; } @@ -670,6 +814,8 @@ unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, const struct sockaddr_un *un, size_t fromlen) { struct GNUNET_ATS_Information ats[2]; + struct Session *s = NULL; + struct GNUNET_HELLO_Address * addr; ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); ats[0].value = htonl (UNIX_DIRECT_DISTANCE); @@ -678,20 +824,30 @@ unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, GNUNET_assert (fromlen >= sizeof (struct sockaddr_un)); -#if DEBUG_UNIX GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message from %s\n", un->sun_path); -#endif + + plugin->bytes_in_recv += ntohs(currhdr->size); + GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes received", + plugin->bytes_in_recv, GNUNET_NO); + + addr = GNUNET_HELLO_address_allocate(sender, "unix", un->sun_path, strlen (un->sun_path) + 1); + s = lookup_session (plugin, sender, un); + if (NULL == s) + s = unix_plugin_get_session (plugin, addr); + reschedule_session_timeout (s); + plugin->env->receive (plugin->env->cls, sender, currhdr, (const struct GNUNET_ATS_Information *) &ats, 2, - NULL, un->sun_path, strlen (un->sun_path) + 1); + s, un->sun_path, strlen (un->sun_path) + 1); + GNUNET_free (addr); } static void unix_plugin_select_read (struct Plugin * plugin) { - char buf[65536]; + char buf[65536] GNUNET_ALIGN; struct UNIXMessage *msg; struct GNUNET_PeerIdentity sender; struct sockaddr_un un; @@ -723,10 +879,8 @@ unix_plugin_select_read (struct Plugin * plugin) #if LINUX un.sun_path[0] = '/'; #endif -#if DEBUG_UNIX GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes from socket %s\n", ret, &un.sun_path[0]); -#endif } GNUNET_assert (AF_UNIX == (un.sun_family)); @@ -752,14 +906,17 @@ unix_plugin_select_read (struct Plugin * plugin) GNUNET_break_op (0); break; } + unix_demultiplexer (plugin, &sender, currhdr, &un, sizeof (un)); offset += csize; } } + static void unix_plugin_select_write (struct Plugin * plugin) { + static int retry_counter; int sent = 0; struct UNIXMessageWrapper * msgw = plugin->msg_head; @@ -774,37 +931,69 @@ unix_plugin_select_write (struct Plugin * plugin) msgw->session->addrlen, msgw->cont, msgw->cont_cls); - /* successfully sent bytes */ - if (sent > 0) + if (sent == 0) + { + /* failed and retry */ + retry_counter++; + GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX retry attempt", + retry_counter, GNUNET_NO); + return; + } + + if (retry_counter > 0 ) + { + /* no retry: reset counter */ + retry_counter = 0; + GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX retry attempt", + retry_counter, GNUNET_NO); + } + + if (sent == -1) { + /* failed and no retry */ GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); + + GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize); + plugin->bytes_in_queue -= msgw->msgsize; + GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes in send queue", + plugin->bytes_in_queue, GNUNET_NO); + plugin->bytes_discarded += msgw->msgsize; + GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes discarded", + plugin->bytes_discarded, GNUNET_NO); + GNUNET_free (msgw->msg); GNUNET_free (msgw); return; } - /* failed and no retry */ - if (sent == -1) + if (sent > 0) { + /* successfully sent bytes */ GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); + + GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize); + plugin->bytes_in_queue -= msgw->msgsize; + GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes in send queue", + plugin->bytes_in_queue, GNUNET_NO); + plugin->bytes_in_sent += msgw->msgsize; + GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes sent", + plugin->bytes_in_sent, GNUNET_NO); + GNUNET_free (msgw->msg); GNUNET_free (msgw); return; } - /* failed and retry */ - if (sent == 0) - return; } -/* - * @param cls the plugin handle - * @param tc the scheduling context (for rescheduling this function again) - * + +/** * We have been notified that our writeset has something to read. We don't * know which socket needs to be read, so we have to check each one * Then reschedule this function to be called again once more is available. * + * @param cls the plugin handle + * @param tc the scheduling context (for rescheduling this function again) */ static void unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) @@ -815,9 +1004,9 @@ unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) return; - plugin->with_ws = GNUNET_NO; if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) { + /* Ready to send data */ GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->unix_sock.desc)); if (plugin->msg_head != NULL) @@ -826,30 +1015,22 @@ unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) { + /* Ready to receive data */ GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->unix_sock.desc)); unix_plugin_select_read (plugin); } - if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (plugin->select_task); - plugin->select_task = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, - GNUNET_TIME_UNIT_FOREVER_REL, - plugin->rs, - (plugin->msg_head != NULL) ? plugin->ws : NULL, - &unix_plugin_select, plugin); - if (plugin->msg_head != NULL) - plugin->with_ws = GNUNET_YES; + reschedule_select (plugin); } + /** * Create a slew of UNIX sockets. If possible, use IPv6 and IPv4. * * @param cls closure for server start, should be a struct Plugin * * @return number of sockets created or GNUNET_SYSERR on error -*/ + */ static int unix_transport_server_start (void *cls) { @@ -893,10 +1074,8 @@ unix_transport_server_start (void *cls) plugin->unix_sock.desc = NULL; return GNUNET_SYSERR; } -#if DEBUG_UNIX GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "unix", "Bound to `%s'\n", &un.sun_path[0]); -#endif plugin->rs = GNUNET_NETWORK_fdset_create (); plugin->ws = GNUNET_NETWORK_fdset_create (); GNUNET_NETWORK_fdset_zero (plugin->rs); @@ -904,14 +1083,7 @@ unix_transport_server_start (void *cls) GNUNET_NETWORK_fdset_set (plugin->rs, plugin->unix_sock.desc); GNUNET_NETWORK_fdset_set (plugin->ws, plugin->unix_sock.desc); - plugin->select_task = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, - GNUNET_TIME_UNIT_FOREVER_REL, - plugin->rs, - NULL, - &unix_plugin_select, plugin); - plugin->with_ws = GNUNET_NO; + reschedule_select (plugin); return 1; } @@ -936,12 +1108,9 @@ unix_transport_server_start (void *cls) static int unix_check_address (void *cls, const void *addr, size_t addrlen) { - -#if DEBUG_UNIX GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Informing transport service about my address `%s'\n", (char *) addr); -#endif return GNUNET_OK; } @@ -968,16 +1137,59 @@ unix_plugin_address_pretty_printer (void *cls, const char *type, GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls) { - if ((addr != NULL) && (addrlen > 0)) + if ((NULL != addr) && (addrlen > 0)) + { asc (asc_cls, (const char *) addr); + } else { GNUNET_break (0); - asc (asc_cls, "Invalid UNIX address"); + asc (asc_cls, ""); } + asc (asc_cls, NULL); +} + +/** + * Function called to convert a string address to + * a binary address. + * + * @param cls closure ('struct Plugin*') + * @param addr string address + * @param addrlen length of the address (strlen(addr) + '\0') + * @param buf location to store the buffer + * If the function returns GNUNET_SYSERR, its contents are undefined. + * @param added length of created address + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +static int +unix_string_to_address (void *cls, const char *addr, uint16_t addrlen, + void **buf, size_t *added) +{ + if ((NULL == addr) || (0 == addrlen)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + if ('\0' != addr[addrlen - 1]) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + if (strlen (addr) != addrlen - 1) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + (*buf) = strdup (addr); + (*added) = strlen (addr) + 1; + return GNUNET_OK; } + /** * Function called for a quick conversion of the binary address to * a numeric address. Note that the caller must not free the @@ -994,10 +1206,10 @@ unix_address_to_string (void *cls, const void *addr, size_t addrlen) { if ((addr != NULL) && (addrlen > 0)) return (const char *) addr; - else - return NULL; + return NULL; } + /** * Notify transport service about address * @@ -1014,6 +1226,85 @@ address_notification (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) strlen (plugin->unix_socket_path) + 1); } + +/** + * Session was idle, so disconnect it + */ +static void +session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_assert (NULL != cls); + struct Session *s = cls; + + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p was idle for %llu, disconnecting\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + + /* call session destroy function */ + disconnect_session(s); + +} + +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); + + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p set to %llu\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); + + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p set to %llu\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + + if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) + { + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p canceled\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p was not active\n", + s); + } +} + + /** * The exported method. Makes the core api available via a global and * returns the unix transport API. @@ -1027,6 +1318,19 @@ libgnunet_plugin_transport_unix_init (void *cls) struct Plugin *plugin; int sockets_created; + if (NULL == env->receive) + { + /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully + initialze the plugin or the API */ + api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); + api->cls = NULL; + api->address_pretty_printer = &unix_plugin_address_pretty_printer; + api->address_to_string = &unix_address_to_string; + api->string_to_address = &unix_string_to_address; + return api; + } + GNUNET_assert( NULL != env->stats); + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-unix", "PORT", &port)) @@ -1046,6 +1350,7 @@ libgnunet_plugin_transport_unix_init (void *cls) api->address_pretty_printer = &unix_plugin_address_pretty_printer; api->address_to_string = &unix_address_to_string; api->check_address = &unix_check_address; + api->string_to_address = &unix_string_to_address; sockets_created = unix_transport_server_start (plugin); if (sockets_created == 0) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UNIX sockets\n")); @@ -1062,13 +1367,20 @@ libgnunet_plugin_transport_unix_done (void *cls) struct GNUNET_TRANSPORT_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; + if (NULL == plugin) + { + GNUNET_free (api); + return NULL; + } unix_transport_server_stop (plugin); GNUNET_CONTAINER_multihashmap_iterate (plugin->session_map, &get_session_delete_it, plugin); GNUNET_CONTAINER_multihashmap_destroy (plugin->session_map); - GNUNET_NETWORK_fdset_destroy (plugin->rs); - GNUNET_NETWORK_fdset_destroy (plugin->ws); + if (NULL != plugin->rs) + GNUNET_NETWORK_fdset_destroy (plugin->rs); + if (NULL != plugin->ws) + GNUNET_NETWORK_fdset_destroy (plugin->ws); GNUNET_free (plugin->unix_socket_path); GNUNET_free (plugin); GNUNET_free (api); diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 08f9c58..aed4b22 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c @@ -1,31 +1,29 @@ /* - This file is part of GNUnet - (C) 2010 2011 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - */ + This file is part of GNUnet + (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ /** * @file transport/plugin_transport_wlan.c * @brief transport plugin for wlan * @author David Brodski + * @author Christian Grothoff */ - -//TODO split rx and tx structures for better handling - #include "platform.h" #include "gnunet_hello_lib.h" #include "gnunet_protocols.h" @@ -39,1808 +37,756 @@ #include "gnunet_fragmentation_lib.h" #include "gnunet_constants.h" -/** - * DEBUG switch - */ -#define DEBUG_WLAN GNUNET_EXTRA_LOGGING - - -#define PROTOCOL_PREFIX "wlan" - -#define PLUGIN_LOG_NAME "wlan-plugin" +#define LOG(kind,...) GNUNET_log_from (kind, "transport-wlan",__VA_ARGS__) /** - * Max size of packet + * Max size of packet (that we give to the WLAN driver for transmission) */ #define WLAN_MTU 1430 -/** - * time out of a session - */ -#define SESSION_TIMEOUT GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT - /** * time out of a mac endpoint */ #define MACENDPOINT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2) /** - * scaling factor for hello beacon - */ -#define HELLO_BEACON_SCALING_FACTOR 30 - -/** - * scaling factor for restarting the helper - */ -#define HELPER_RESTART_SCALING_FACTOR 2 - -/** - * max size of fragment queue - */ -#define FRAGMENT_QUEUE_SIZE 10 -/** - * max messages in fragment queue per session/client - */ -#define FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION 1 - -/** - * max messages in fragment queue per MAC + * We reduce the frequence of HELLO beacons in relation to + * the number of MAC addresses currently visible to us. + * This is the multiplication factor. */ -#define FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT 1 +#define HELLO_BEACON_SCALING_FACTOR GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) /** - * max messages in in queue - */ -#define MESSAGES_IN_QUEUE_SIZE 10 -/** - * max messages in in queue per session/client + * Maximum number of messages in defragmentation queue per MAC */ -#define MESSAGES_IN_DEFRAG_QUEUE_PER_MAC 1 +#define MESSAGES_IN_DEFRAG_QUEUE_PER_MAC 2 /** - * LLC fields for better compatibility + * Link layer control fields for better compatibility + * (i.e. GNUnet over WLAN is not IP-over-WLAN). */ #define WLAN_LLC_DSAP_FIELD 0x1f #define WLAN_LLC_SSAP_FIELD 0x1f -#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ - -#define IEEE80211_FC0_VERSION_MASK 0x03 -#define IEEE80211_FC0_VERSION_SHIFT 0 -#define IEEE80211_FC0_VERSION_0 0x00 -#define IEEE80211_FC0_TYPE_MASK 0x0c -#define IEEE80211_FC0_TYPE_SHIFT 2 -#define IEEE80211_FC0_TYPE_MGT 0x00 -#define IEEE80211_FC0_TYPE_CTL 0x04 -#define IEEE80211_FC0_TYPE_DATA 0x08 - GNUNET_NETWORK_STRUCT_BEGIN - -/* - * generic definitions for IEEE 802.11 frames - */ -struct ieee80211_frame -{ - u_int8_t i_fc[2]; - u_int8_t i_dur[2]; - u_int8_t i_addr1[IEEE80211_ADDR_LEN]; - u_int8_t i_addr2[IEEE80211_ADDR_LEN]; - u_int8_t i_addr3[IEEE80211_ADDR_LEN]; - u_int8_t i_seq[2]; - u_int8_t llc[4]; -} GNUNET_PACKED; -GNUNET_NETWORK_STRUCT_END - /** - * Encapsulation of all of the state of the plugin. + * Header for messages which need fragmentation. This is the format of + * a message we obtain AFTER defragmentation. We then need to check + * the CRC and then tokenize the payload and pass it to the + * 'receive' callback. */ -struct Plugin +struct WlanHeader { - /** - * Our environment. - */ - struct GNUNET_TRANSPORT_PluginEnvironment *env; /** - * List of open connections. head + * Message type is GNUNET_MESSAGE_TYPE_WLAN_DATA. */ - struct MacEndpoint *mac_head; + struct GNUNET_MessageHeader header; /** - * List of open connections. tail + * CRC32 checksum (only over the payload), in NBO. */ - struct MacEndpoint *mac_tail; + uint32_t crc GNUNET_PACKED; /** - * Number of connections + * Sender of the message. */ - unsigned int mac_count; + struct GNUNET_PeerIdentity sender; /** - * encapsulation of data from the local wlan helper program + * Target of the message. */ - struct GNUNET_SERVER_MessageStreamTokenizer *suid_tokenizer; + struct GNUNET_PeerIdentity target; - /** - * encapsulation of packets received from the wlan helper - */ - struct GNUNET_SERVER_MessageStreamTokenizer *data_tokenizer; + /* followed by payload, possibly including + multiple messages! */ + +}; +GNUNET_NETWORK_STRUCT_END - /** - * stdout pipe handle for the gnunet-helper-transport-wlan process - */ - struct GNUNET_DISK_PipeHandle *server_stdout; +/** + * Information kept for each message that is yet to be fragmented and + * transmitted. + */ +struct PendingMessage +{ /** - * stdout file handle for the gnunet-helper-transport-wlan process + * next entry in the DLL */ - const struct GNUNET_DISK_FileHandle *server_stdout_handle; + struct PendingMessage *next; /** - * stdin pipe handle for the gnunet-helper-transport-wlan process + * previous entry in the DLL */ - struct GNUNET_DISK_PipeHandle *server_stdin; + struct PendingMessage *prev; /** - * stdin file handle for the gnunet-helper-transport-wlan process + * The pending message */ - const struct GNUNET_DISK_FileHandle *server_stdin_handle; + struct WlanHeader *msg; /** - * ID of the gnunet-wlan-server std read task + * Continuation function to call once the message + * has been sent. Can be NULL if there is no + * continuation to call. */ - GNUNET_SCHEDULER_TaskIdentifier server_read_task; + GNUNET_TRANSPORT_TransmitContinuation transmit_cont; /** - * ID of the gnunet-wlan-server std read task + * Cls for transmit_cont */ - GNUNET_SCHEDULER_TaskIdentifier server_write_task; + void *transmit_cont_cls; /** - * ID of the delay task for writing + * Timeout task (for this message). */ - GNUNET_SCHEDULER_TaskIdentifier server_write_delay_task; + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + +}; + + +/** + * Session handle for connections with other peers. + */ +struct Session +{ /** - * The process id of the wlan process + * API requirement (must be first). */ - struct GNUNET_OS_Process *server_proc; + struct SessionHeader header; /** - * The interface of the wlan card given to us by the user. + * We keep all sessions in a DLL at their respective + * 'struct MACEndpoint'. */ - char *interface; + struct Session *next; /** - * Mode of operation for the helper, 0 = normal, 1 = first loopback, 2 = second loopback + * We keep all sessions in a DLL at their respective + * 'struct MACEndpoint'. */ - long long unsigned int testmode; + struct Session *prev; /** - * The mac_address of the wlan card given to us by the helper. + * MAC endpoint with the address of this peer. */ - struct GNUNET_TRANSPORT_WLAN_MacAddress mac_address; + struct MacEndpoint *mac; /** - * Sessions currently pending for transmission - * to a peer, if any. + * Head of messages currently pending for transmission to this peer. */ - struct Sessionqueue *pending_Sessions_head; + struct PendingMessage *pending_message_head; /** - * Sessions currently pending for transmission - * to a peer (tail), if any. + * Tail of messages currently pending for transmission to this peer. */ - struct Sessionqueue *pending_Sessions_tail; + struct PendingMessage *pending_message_tail; /** - * number of pending sessions + * To whom are we talking to (set to our identity + * if we are still waiting for the welcome message) */ - unsigned int pendingsessions; + struct GNUNET_PeerIdentity target; /** - * Messages in the sending queues + * When should this session time out? */ - int pending_Fragment_Messages; + struct GNUNET_TIME_Absolute timeout; /** - * messages ready for send, head + * Timeout task (for the session). */ - struct FragmentMessage_queue *sending_messages_head; + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + +}; + + +/** + * Struct for messages that are being fragmented in a MAC's transmission queue. + */ +struct FragmentMessage +{ + /** - * messages ready for send, tail + * This is a doubly-linked list. */ - struct FragmentMessage_queue *sending_messages_tail; + struct FragmentMessage *next; + /** - * time of the next "hello-beacon" + * This is a doubly-linked list. */ - struct GNUNET_TIME_Absolute beacon_time; + struct FragmentMessage *prev; /** - * queue to send acks for received fragments (head) + * MAC endpoint this message belongs to */ - struct AckSendQueue *ack_send_queue_head; + struct MacEndpoint *macendpoint; /** - * queue to send acks for received fragments (tail) + * Fragmentation context */ - struct AckSendQueue *ack_send_queue_tail; + struct GNUNET_FRAGMENT_Context *fragcontext; /** - * Tracker for bandwidth limit + * Transmission handle to helper (to cancel if the frag context + * is destroyed early for some reason). */ - struct GNUNET_BANDWIDTH_Tracker tracker; + struct GNUNET_HELPER_SendHandle *sh; /** - * saves the current state of the helper process + * Intended recipient. */ - int helper_is_running; -}; + struct GNUNET_PeerIdentity target; -/** - * Struct to store data if file write did not accept the whole packet - */ -struct Finish_send -{ /** - * pointer to the global plugin struct + * Timeout value for the message. */ - struct Plugin *plugin; + struct GNUNET_TIME_Absolute timeout; /** - * head of the next part to send to the helper + * Timeout task. */ - char *head_of_next_write; + GNUNET_SCHEDULER_TaskIdentifier timeout_task; /** - * Start of the message to send, needed for free + * Continuation to call when we're done with this message. */ - struct GNUNET_MessageHeader *msgstart; + GNUNET_TRANSPORT_TransmitContinuation cont; /** - * rest size to send + * Closure for 'cont' */ - ssize_t size; -}; - -/** - * Queue of sessions, for the general session queue and the pending session queue - */ -//TODO DOXIGEN -struct Sessionqueue -{ - struct Sessionqueue *next; - struct Sessionqueue *prev; - struct Session *content; -#if !HAVE_UNALIGNED_64_ACCESS - void *dummy; /* for alignment, see #1909 */ -#endif -}; - -/** - * Queue of fragmented messages, for the sending queue of the plugin - */ -//TODO DOXIGEN -struct FragmentMessage_queue -{ - struct FragmentMessage_queue *next; - struct FragmentMessage_queue *prev; - struct FragmentMessage *content; -}; - -/** - * Queue for the fragments received - */ -//TODO DOXIGEN -struct Receive_Fragment_Queue -{ - struct Receive_Fragment_Queue *next; - struct Receive_Fragment_Queue *prev; - uint16_t num; - const char *msg; - uint16_t size; - struct Radiotap_rx rxinfo; -}; - -//TODO DOXIGEN -struct MacEndpoint_id_fragment_triple -{ - struct MacEndpoint *endpoint; - uint32_t message_id; - struct FragmentMessage *fm; -}; + void *cont_cls; -//TODO DOXIGEN -struct Plugin_Session_pair -{ - struct Plugin *plugin; - struct Session *session; }; -GNUNET_NETWORK_STRUCT_BEGIN - /** - * Header for messages which need fragmentation + * Struct to represent one network card connection */ -struct WlanHeader +struct MacEndpoint { - struct GNUNET_MessageHeader header; - /** - * checksum/error correction + * We keep all MACs in a DLL in the plugin. */ - uint32_t crc GNUNET_PACKED; + struct MacEndpoint *next; /** - * To whom are we talking to (set to our identity - * if we are still waiting for the welcome message) + * We keep all MACs in a DLL in the plugin. */ - struct GNUNET_PeerIdentity target; + struct MacEndpoint *prev; /** - * Where the packet came from + * Pointer to the global plugin struct. */ - struct GNUNET_PeerIdentity source; - -// followed by payload - -}; -GNUNET_NETWORK_STRUCT_END + struct Plugin *plugin; -/** - * Information kept for each message that is yet to - * be transmitted. - */ -struct PendingMessage -{ - /** - * dll next - */ - struct PendingMessage *next; /** - * dll prev + * Head of sessions that use this MAC. */ - struct PendingMessage *prev; + struct Session *sessions_head; /** - * The pending message + * Tail of sessions that use this MAC. */ - struct WlanHeader *msg; + struct Session *sessions_tail; /** - * Size of the message + * Head of messages we are currently sending to this MAC. */ - size_t message_size; + struct FragmentMessage *sending_messages_head; /** - * Continuation function to call once the message - * has been sent. Can be NULL if there is no - * continuation to call. + * Tail of messages we are currently sending to this MAC. */ - GNUNET_TRANSPORT_TransmitContinuation transmit_cont; + struct FragmentMessage *sending_messages_tail; /** - * Cls for transmit_cont + * Defrag context for this MAC */ - void *transmit_cont_cls; + struct GNUNET_DEFRAGMENT_Context *defrag; /** - * Timeout value for the pending message. + * When should this endpoint time out? */ struct GNUNET_TIME_Absolute timeout; -}; - -/** - * Queue for acks to send for fragments recived - */ -struct AckSendQueue -{ - - /** - * next ack in the ack send queue - */ - struct AckSendQueue *next; /** - * previous ack in the ack send queue + * Timeout task. */ - struct AckSendQueue *prev; + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + /** - * pointer to the session this ack belongs to + * count of messages in the fragment out queue for this mac endpoint */ - struct MacEndpoint *endpoint; + unsigned int fragment_messages_out_count; + /** - * ID of message, to distinguish between the messages, picked randomly. + * peer mac address */ - uint32_t message_id; + struct GNUNET_TRANSPORT_WLAN_MacAddress addr; /** - * msg to send + * Desired transmission power for this MAC */ - struct GNUNET_MessageHeader *hdr; + uint16_t tx_power; + /** - * pointer to the ieee wlan header + * Desired transmission rate for this MAC */ - struct ieee80211_frame *ieeewlanheader; + uint8_t rate; + /** - * pointer to the radiotap header + * Antenna we should use for this MAC */ - struct Radiotap_Send *radioHeader; + uint8_t antenna; + }; + /** - * Session infos gathered from a messages + * Encapsulation of all of the state of the plugin. */ -struct Session_light +struct Plugin { /** - * the session this message belongs to + * Our environment. */ - struct Session *session; + struct GNUNET_TRANSPORT_PluginEnvironment *env; + /** - * peer mac address + * Handle to helper process for priviledged operations. + */ + struct GNUNET_HELPER_Handle *suid_helper; + + /** + * ARGV-vector for the helper (all helpers take only the binary + * name, one actual argument, plus the NULL terminator for 'argv'). */ - struct GNUNET_TRANSPORT_WLAN_MacAddress addr; + char * helper_argv[3]; /** - * mac endpoint + * The interface of the wlan card given to us by the user. */ - struct MacEndpoint *macendpoint; -}; + char *interface; -/** - * Session handle for connections. - */ -struct Session -{ + /** + * Tokenizer for demultiplexing of data packets resulting from defragmentation. + */ + struct GNUNET_SERVER_MessageStreamTokenizer *fragment_data_tokenizer; /** - * API requirement. + * Tokenizer for demultiplexing of data packets received from the suid helper */ - struct SessionHeader header; + struct GNUNET_SERVER_MessageStreamTokenizer *helper_payload_tokenizer; /** - * Message currently pending for transmission - * to this peer, if any. head + * Tokenizer for demultiplexing of data packets that follow the WLAN Header */ - struct PendingMessage *pending_message_head; + struct GNUNET_SERVER_MessageStreamTokenizer *wlan_header_payload_tokenizer; /** - * Message currently pending for transmission - * to this peer, if any. tail + * Head of list of open connections. */ - struct PendingMessage *pending_message_tail; + struct MacEndpoint *mac_head; /** - * To whom are we talking to (set to our identity - * if we are still waiting for the welcome message) + * Tail of list of open connections. */ - struct GNUNET_PeerIdentity target; + struct MacEndpoint *mac_tail; /** - * Address of the other peer (either based on our 'connect' - * call or on our 'accept' call). + * Number of connections */ - void *connect_addr; + unsigned int mac_count; /** - * Last activity on this connection. Used to select preferred - * connection and timeout + * Task that periodically sends a HELLO beacon via the helper. */ - struct GNUNET_TIME_Absolute last_activity; + GNUNET_SCHEDULER_TaskIdentifier beacon_task; /** - * Timeout task. + * Tracker for bandwidth limit */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; + struct GNUNET_BANDWIDTH_Tracker tracker; /** - * peer connection + * The mac_address of the wlan card given to us by the helper. */ - struct MacEndpoint *mac; + struct GNUNET_TRANSPORT_WLAN_MacAddress mac_address; /** - * count of messages in the fragment out queue for this session + * Have we received a control message with our MAC address yet? */ + int have_mac; - int fragment_messages_out_count; }; + /** - * Struct to represent one network card connection + * Information associated with a message. Can contain + * the session or the MAC endpoint associated with the + * message (or both). */ -struct MacEndpoint +struct MacAndSession { /** - * Pointer to the global plugin struct. - */ - struct Plugin *plugin; - /** - * Struct to hold the session reachable over this mac; head - */ - struct Sessionqueue *sessions_head; - /** - * Struct to hold the session reachable over this mac; tail + * NULL if the identity of the other peer is not known. */ - struct Sessionqueue *sessions_tail; + struct Session *session; + /** - * Messages currently sending - * to a peer, if any. + * MAC address of the other peer, NULL if not known. */ - struct FragmentMessage *sending_messages_head; - - /** - * Messages currently sending - * to a peer (tail), if any. - */ - struct FragmentMessage *sending_messages_tail; - /** - * dll next - */ - struct MacEndpoint *next; - /** - * dll prev - */ - struct MacEndpoint *prev; - - /** - * peer mac address - */ - struct GNUNET_TRANSPORT_WLAN_MacAddress addr; - - /** - * Defrag context for this mac endpoint - */ - struct GNUNET_DEFRAGMENT_Context *defrag; - - /** - * count of messages in the fragment out queue for this mac endpoint - */ - - int fragment_messages_out_count; - - //TODO DOXIGEN - uint8_t rate; - uint16_t tx_power; - uint8_t antenna; - - /** - * Duplicates received - */ - int dups; - - /** - * Fragments received - */ - int fragc; - - /** - * Acks received - */ - int acks; - - /** - * Last activity on this endpoint. Used to select preferred - * connection. - */ - struct GNUNET_TIME_Absolute last_activity; - - /** - * Timeout task. - */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; -}; - -/** - * Struct for Messages in the fragment queue - */ -struct FragmentMessage -{ - - /** - * Session this message belongs to - */ - struct Session *session; - - /** - * This is a doubly-linked list. - */ - struct FragmentMessage *next; - - /** - * This is a doubly-linked list. - */ - struct FragmentMessage *prev; - - /** - * Fragmentation context - */ - struct GNUNET_FRAGMENT_Context *fragcontext; - - /** - * Timeout value for the message. - */ - struct GNUNET_TIME_Absolute timeout; - - /** - * Timeout task. - */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; - - /** - * Fragment to send - */ - char *frag; - - /** - * size of message - */ - size_t size; - - /** - * pointer to the ieee wlan header - */ - struct ieee80211_frame *ieeewlanheader; - /** - * pointer to the radiotap header - */ - struct Radiotap_Send *radioHeader; -}; - -static void -do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - -static void -free_session (struct Plugin *plugin, struct Sessionqueue *queue, - int do_free_macendpoint); - -static struct MacEndpoint * -create_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr); - -static void -finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - -/** - * Generates a nice hexdump of a memory area. - * - * \param mem pointer to memory to dump - * \param length how many bytes to dump - */ -static void -hexdump (const void *mem, unsigned length) -{ - char line[80]; - char *src = (char *) mem; - - printf ("dumping %u bytes from %p\r\n" - " 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\r\n", - length, src); - unsigned i; - int j; - - for (i = 0; i < length; i += 16, src += 16) - { - char *t = line; - - t += sprintf (t, "%04x: ", i); - for (j = 0; j < 16; j++) - { - if (i + j < length) - t += sprintf (t, "%02X", src[j] & 0xff); - else - t += sprintf (t, " "); - - t += sprintf (t, (j % 2) ? " " : "-"); - } - - t += sprintf (t, " "); - for (j = 0; j < 16; j++) - { - if (i + j < length) - { - if (isprint ((unsigned char) src[j])) - t += sprintf (t, "%c", src[j]); - else - t += sprintf (t, "."); - } - else - { - t += sprintf (t, " "); - } - } - - t += sprintf (t, "\r\n"); - printf ("%s", line); - } -} - -/** - * Function to find a MacEndpoint with a specific mac addr - * @param plugin pointer to the plugin struct - * @param addr pointer to the mac address - * @param create_new GNUNET_YES if a new end point should be created - * @return - */ -static struct MacEndpoint * -get_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr, - int create_new) -{ - struct MacEndpoint *queue = plugin->mac_head; - - while (queue != NULL) - { - //GNUNET_assert (queue->sessions_head != NULL); - if (memcmp (addr, &queue->addr, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) - return queue; /* session found */ - queue = queue->next; - } - - if (create_new == GNUNET_YES) - { - return create_macendpoint (plugin, addr); - } - else - { - return NULL; - } - -} - -/** - * search for a session with the macendpoint and peer id - * - * @param plugin pointer to the plugin struct - * @param endpoint pointer to the mac endpoint of the peer - * @param peer pointer to the peerid - * @return returns the session - */ -static struct Session * -search_session (struct Plugin *plugin, const struct MacEndpoint *endpoint, - const struct GNUNET_PeerIdentity *peer) -{ - GNUNET_assert (endpoint != NULL); - struct Sessionqueue *queue = endpoint->sessions_head; - - while (queue != NULL) - { - GNUNET_assert (queue->content != NULL); - if (memcmp - (peer, &queue->content->target, - sizeof (struct GNUNET_PeerIdentity)) == 0) - return queue->content; /* session found */ - queue = queue->next; - } - return NULL; -} - -/** - * Function called for a quick conversion of the binary address to - * a numeric address. Note that the caller must not free the - * address and that the next call to this function is allowed - * to override the address again. - * - * @param cls closure - * @param addr binary address - * @param addrlen length of the address - * @return string representing the same address - */ -static const char * -wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) -{ - static char ret[40]; - const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac; - - if (addrlen != sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) - { - GNUNET_break (0); - return NULL; - } - mac = addr; - GNUNET_snprintf (ret, sizeof (ret), "%s Mac-Address %X:%X:%X:%X:%X:%X", - PROTOCOL_PREFIX, mac->mac[0], mac->mac[1], mac->mac[2], - mac->mac[3], mac->mac[4], mac->mac[5]); - - return ret; -} - -/** - * Function for the scheduler if a session times out - * @param cls pointer to the Sessionqueue - * @param tc pointer to the GNUNET_SCHEDULER_TaskContext - */ -static void -session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct Sessionqueue *queue = cls; - - GNUNET_assert (queue != NULL); - GNUNET_assert (queue->content != NULL); - queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK; - if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) - { - return; - } - if (GNUNET_TIME_absolute_get_remaining - (GNUNET_TIME_absolute_add - (queue->content->last_activity, SESSION_TIMEOUT)).rel_value == 0) - { - - GNUNET_assert (queue->content->mac != NULL); - GNUNET_assert (queue->content->mac->plugin != NULL); - GNUNET_STATISTICS_update (queue->content->mac->plugin->env->stats, - _("# wlan session timeouts"), 1, GNUNET_NO); - free_session (queue->content->mac->plugin, queue, GNUNET_YES); - } - else - { - queue->content->timeout_task = - GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue); - } -} - -/** - * create a new session - * - * @param plugin pointer to the plugin struct - * @param endpoint pointer to the mac endpoint of the peer - * @param peer peer identity to use for this session - * @return returns the session - */ -static struct Session * -create_session (struct Plugin *plugin, struct MacEndpoint *endpoint, - const struct GNUNET_PeerIdentity *peer) -{ - GNUNET_assert (endpoint != NULL); - GNUNET_assert (plugin != NULL); - GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan session created"), 1, - GNUNET_NO); - struct Sessionqueue *queue = - GNUNET_malloc (sizeof (struct Sessionqueue) + sizeof (struct Session)); - - GNUNET_CONTAINER_DLL_insert_tail (endpoint->sessions_head, - endpoint->sessions_tail, queue); - - queue->content = (struct Session *) &queue[1]; - queue->content->mac = endpoint; - queue->content->target = *peer; - queue->content->last_activity = GNUNET_TIME_absolute_get (); - queue->content->timeout_task = - GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "New session %p with endpoint %p: %s\n", queue->content, - endpoint, wlan_plugin_address_to_string (NULL, - endpoint->addr.mac, - 6)); - return queue->content; -} - -/** - * Get session from address, create if no session exists - * - * @param plugin pointer to the plugin struct - * @param addr pointer to the mac address of the peer - * @param peer pointer to the peerid - * @return returns the session - */ -static struct Session * -get_session (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr, - const struct GNUNET_PeerIdentity *peer) -{ - struct MacEndpoint *mac; - - mac = get_macendpoint (plugin, addr, GNUNET_YES); - struct Session *session = search_session (plugin, mac, peer); - - if (session != NULL) - return session; - return create_session (plugin, mac, peer); -} - -/** - * Queue the session to send data - * checks if there is a message pending - * checks if this session is not allready in the queue - * @param plugin pointer to the plugin - * @param session pointer to the session to add - */ -static void -queue_session (struct Plugin *plugin, struct Session *session) -{ - struct Sessionqueue *queue = plugin->pending_Sessions_head; - - if (session->pending_message_head != NULL) - { - while (queue != NULL) - { - // content is never NULL - GNUNET_assert (queue->content != NULL); - // is session already in queue? - if (session == queue->content) - { - return; - } - // try next - queue = queue->next; - } - - // Session is not in the queue - - queue = GNUNET_malloc (sizeof (struct Sessionqueue)); - queue->content = session; - - //insert at the tail - GNUNET_CONTAINER_DLL_insert_tail (plugin->pending_Sessions_head, - plugin->pending_Sessions_tail, queue); - plugin->pendingsessions++; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), - plugin->pendingsessions, GNUNET_NO); - } - -} - -/** - * Function to schedule the write task, executed after a delay - * @param cls pointer to the plugin struct - * @param tc GNUNET_SCHEDULER_TaskContext pointer - */ -static void -delay_fragment_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct Plugin *plugin = cls; - - plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; - - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - return; - - // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg - if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK) - { - plugin->server_write_task = - GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, - plugin->server_stdin_handle, - &do_transmit, plugin); - } -} - -/** - * Function to calculate the time of the next periodic "hello-beacon" - * @param plugin pointer to the plugin struct - */ -static void -set_next_beacon_time (struct Plugin *const plugin) -{ - //under 10 known peers: once a second - if (plugin->mac_count < 10) - { - plugin->beacon_time = - GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, - HELLO_BEACON_SCALING_FACTOR)); - } - //under 30 known peers: every 10 seconds - else if (plugin->mac_count < 30) - { - plugin->beacon_time = - GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, - 10 * HELLO_BEACON_SCALING_FACTOR)); - } - //over 30 known peers: once a minute - else - { - plugin->beacon_time = - GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MINUTES, - HELLO_BEACON_SCALING_FACTOR)); - } -} - -/** - * Function to set the timer for the next timeout of the fragment queue - * @param plugin the handle to the plugin struct - */ -static void -set_next_send (struct Plugin *const plugin) -{ - struct GNUNET_TIME_Relative next_send; - - //abort if helper is not running - if (plugin->helper_is_running == GNUNET_NO) - { - return; - } - - //cancel old task - if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task); - plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; - } - - //check if some acks are in the queue - if (plugin->ack_send_queue_head != NULL) - { - next_send = GNUNET_TIME_UNIT_ZERO; - } - - //check if there are some fragments in the queue - else if (plugin->sending_messages_head != NULL) - { - next_send = GNUNET_TIME_UNIT_ZERO; - } - else - { - next_send = GNUNET_TIME_absolute_get_remaining (plugin->beacon_time); - } - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Next packet is send in: %u\n", next_send.rel_value); - if (next_send.rel_value == GNUNET_TIME_UNIT_ZERO.rel_value) - { - if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK) - { - plugin->server_write_task = - GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, - plugin->server_stdin_handle, - &do_transmit, plugin); - } - } - else - { - if (plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK) - { - plugin->server_write_delay_task = - GNUNET_SCHEDULER_add_delayed (next_send, &delay_fragment_task, - plugin); - } - } -} - -/** - * Function to get the next queued Session, removes the session from the queue - * @param plugin pointer to the plugin struct - * @return pointer to the session found, returns NULL if there is now session in the queue - */ -static struct Session * -get_next_queue_session (struct Plugin *plugin) -{ - struct Session *session; - struct Sessionqueue *sessionqueue; - struct Sessionqueue *sessionqueue_alt; - struct PendingMessage *pm; - - sessionqueue = plugin->pending_Sessions_head; - - while (sessionqueue != NULL) - { - session = sessionqueue->content; - - GNUNET_assert (session != NULL); - pm = session->pending_message_head; - - if (pm == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - "pending message is empty, should not happen. session %p\n", - session); - sessionqueue_alt = sessionqueue; - sessionqueue = sessionqueue->next; - plugin->pendingsessions--; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), - plugin->pendingsessions, GNUNET_NO); - GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, - plugin->pending_Sessions_tail, - sessionqueue_alt); - - GNUNET_free (sessionqueue_alt); - continue; - - } - - //check for message timeout - if (GNUNET_TIME_absolute_get_remaining (pm->timeout).rel_value > 0) - { - //check if session has no message in the fragment queue - if ((session->mac->fragment_messages_out_count < - FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT) && - (session->fragment_messages_out_count < - FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION)) - { - plugin->pendingsessions--; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), - plugin->pendingsessions, GNUNET_NO); - GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, - plugin->pending_Sessions_tail, - sessionqueue); - GNUNET_free (sessionqueue); - - return session; - } - else - { - sessionqueue = sessionqueue->next; - } - } - else - { - GNUNET_CONTAINER_DLL_remove (session->pending_message_head, - session->pending_message_tail, pm); - - //call the cont func that it did not work - if (pm->transmit_cont != NULL) - pm->transmit_cont (pm->transmit_cont_cls, &(session->target), - GNUNET_SYSERR); - GNUNET_free (pm->msg); - GNUNET_free (pm); - - if (session->pending_message_head == NULL) - { - sessionqueue_alt = sessionqueue; - sessionqueue = sessionqueue->next; - plugin->pendingsessions--; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), - plugin->pendingsessions, GNUNET_NO); - GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, - plugin->pending_Sessions_tail, - sessionqueue_alt); - - GNUNET_free (sessionqueue_alt); - } - } - - } - return NULL; -} - -/** - * frees the space of a message in the fragment queue (send queue) - * @param plugin the plugin struct - * @param fm message to free - */ -static void -free_fragment_message (struct Plugin *plugin, struct FragmentMessage *fm) -{ - struct Session *session = fm->session; - struct MacEndpoint *endpoint = session->mac; - struct FragmentMessage_queue *fmq; - struct FragmentMessage_queue *fmq_next; - - fmq = plugin->sending_messages_head; - while (fmq != NULL) - { - fmq_next = fmq->next; - if (fmq->content == fm) - { - GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head, - plugin->sending_messages_tail, fmq); - GNUNET_free (fmq); - } - fmq = fmq_next; - } - - (session->mac->fragment_messages_out_count)--; - session->fragment_messages_out_count--; - plugin->pending_Fragment_Messages--; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"), - plugin->pending_Fragment_Messages, GNUNET_NO); - GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head, - endpoint->sending_messages_tail, fm); - GNUNET_FRAGMENT_context_destroy (fm->fragcontext); - if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (fm->timeout_task); - fm->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - - GNUNET_free (fm); - - queue_session (plugin, session); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Free pending fragment messages %p, session %p\n", fm, - session); -} - -/** - * function to fill the radiotap header - * @param plugin pointer to the plugin struct - * @param endpoint pointer to the endpoint - * @param header pointer to the radiotap header - * @return GNUNET_YES at success - */ -static int -getRadiotapHeader (struct Plugin *plugin, struct MacEndpoint *endpoint, - struct Radiotap_Send *header) -{ - - if (endpoint != NULL) - { - header->rate = endpoint->rate; - header->tx_power = endpoint->tx_power; - header->antenna = endpoint->antenna; - } - else - { - header->rate = 255; - header->tx_power = 0; - header->antenna = 0; - } - - return GNUNET_YES; -} - -/** - * function to generate the wlan hardware header for one packet - * @param Header address to write the header to - * @param to_mac_addr address of the recipient - * @param plugin pointer to the plugin struct - * @param size size of the whole packet, needed to calculate the time to send the packet - * @return GNUNET_YES if there was no error - */ -static int -getWlanHeader (struct ieee80211_frame *Header, - const struct GNUNET_TRANSPORT_WLAN_MacAddress *to_mac_addr, struct Plugin *plugin, - unsigned int size) -{ - uint16_t *tmp16; - const int rate = 11000000; - - Header->i_fc[0] = IEEE80211_FC0_TYPE_DATA; - Header->i_fc[1] = 0x00; - memcpy (&Header->i_addr3, &mac_bssid_gnunet, sizeof (mac_bssid_gnunet)); - memcpy (&Header->i_addr2, plugin->mac_address.mac, - sizeof (plugin->mac_address)); - memcpy (&Header->i_addr1, to_mac_addr, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); - - tmp16 = (uint16_t *) Header->i_dur; - *tmp16 = (uint16_t) GNUNET_htole16 ((size * 1000000) / rate + 290); - Header->llc[0] = WLAN_LLC_DSAP_FIELD; - Header->llc[1] = WLAN_LLC_SSAP_FIELD; - - return GNUNET_YES; -} - - -/** - * function to add a fragment of a message to send - * @param cls FragmentMessage this message belongs to - * @param hdr pointer to the start of the message - */ -static void -add_message_for_send (void *cls, const struct GNUNET_MessageHeader *hdr) -{ - - struct FragmentMessage *fm = cls; - struct FragmentMessage_queue *fmqueue; - - GNUNET_assert (cls != NULL); - GNUNET_assert (fm->frag == NULL); - struct MacEndpoint *endpoint = fm->session->mac; - struct Plugin *plugin = endpoint->plugin; - struct GNUNET_MessageHeader *msgheader; - struct GNUNET_MessageHeader *msgheader2; - uint16_t size; - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Adding fragment of message %p to send, session %p, endpoint %p, type %u\n", - fm, fm->session, endpoint, hdr->type); - size = - sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) + - sizeof (struct ieee80211_frame) + ntohs (hdr->size); - fm->frag = GNUNET_malloc (size); - fm->size = size; - - msgheader = (struct GNUNET_MessageHeader *) fm->frag; - msgheader->size = htons (size); - msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); - - fm->radioHeader = (struct Radiotap_Send *) &msgheader[1]; - fm->ieeewlanheader = (struct ieee80211_frame *) &fm->radioHeader[1]; - msgheader2 = (struct GNUNET_MessageHeader *) &fm->ieeewlanheader[1]; - memcpy (msgheader2, hdr, ntohs (hdr->size)); - - fmqueue = GNUNET_malloc (sizeof (struct FragmentMessage_queue)); - fmqueue->content = fm; - - GNUNET_CONTAINER_DLL_insert_tail (plugin->sending_messages_head, - plugin->sending_messages_tail, fmqueue); - set_next_send (plugin); -} - - -/** - * We have been notified that gnunet-helper-transport-wlan has written something to stdout. - * Handle the output, then reschedule this function to be called again once - * more is available. - * - * @param cls the plugin handle - * @param tc the scheduling context - */ -static void -wlan_plugin_helper_read (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct Plugin *plugin = cls; - - plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; - - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - return; - - char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)]; - ssize_t bytes; - - bytes = - GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf, - sizeof (mybuf)); - if (bytes <= 0) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - _ - ("Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n"), - bytes); - return; - } - GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes, - GNUNET_NO, GNUNET_NO); - - GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); - plugin->server_read_task = - GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, - plugin->server_stdout_handle, - &wlan_plugin_helper_read, plugin); -} - -/** - * Start the gnunet-helper-transport-wlan process. - * - * @param plugin the transport plugin - * @return GNUNET_YES if process was started, GNUNET_SYSERR on error - */ -static int -wlan_transport_start_wlan_helper (struct Plugin *plugin) -{ - const char *filenamehw = "gnunet-helper-transport-wlan"; - const char *filenameloopback = "gnunet-helper-transport-wlan-dummy"; - char *absolute_filename = NULL; - - if (plugin->helper_is_running == GNUNET_YES) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "wlan_transport_start_wlan_helper not needed, helper already running!"); - return GNUNET_YES; - } - - plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); - if (plugin->server_stdout == NULL) - return GNUNET_SYSERR; - - plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); - if (plugin->server_stdin == NULL) - return GNUNET_SYSERR; - - if ((plugin->testmode == 1) || (plugin->testmode == 2)) - { - if (GNUNET_OS_check_helper_binary (filenameloopback) == GNUNET_YES) - { - absolute_filename = GNUNET_strdup (filenameloopback); - } - else - { - char cwd[FILENAME_MAX]; - - GNUNET_assert (getcwd (cwd, sizeof (cwd)) != NULL); - - GNUNET_asprintf (&absolute_filename, "%s%s%s", cwd, DIR_SEPARATOR_STR, - filenameloopback); - - if (GNUNET_DISK_file_test (filenameloopback) != GNUNET_YES) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - "Helper `%s' not found! %i\n", absolute_filename); - GNUNET_break (0); - } - } - } - - /* Start the server process */ - - if (plugin->testmode == 0) - { - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Starting gnunet-helper-transport-wlan process cmd: %s %s %i\n", - filenamehw, plugin->interface, plugin->testmode); - if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES) - { - plugin->server_proc = - GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout, - filenamehw, filenamehw, plugin->interface, - NULL); - } - else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - "gnunet-helper-transport-wlan is not suid, please change it or look at the doku\n"); - GNUNET_break (0); - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - "gnunet-helper-transport-wlan not found, please look if it exists and is the $PATH variable!\n"); - GNUNET_break (0); - } - - } - else if (plugin->testmode == 1) - { - - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME, - "Starting gnunet-helper-transport-wlan-dummy loopback 1 process cmd: %s %s %i\n", - absolute_filename, plugin->interface, plugin->testmode); - plugin->server_proc = - GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout, - absolute_filename, absolute_filename, "1", - NULL); - if (plugin->server_proc == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - "`%s' not found, please look if it exists and is in the $PATH variable!\n", - absolute_filename); - GNUNET_break (0); - } - } - else if (plugin->testmode == 2) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME, - "Starting gnunet-helper-transport-wlan-dummy loopback 2 process cmd: %s %s %i\n", - absolute_filename, plugin->interface, plugin->testmode); - plugin->server_proc = - GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout, - absolute_filename, absolute_filename, "2", - NULL); - if (plugin->server_proc == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - "`%s' not found, please look if it exists and is in the $PATH variable!\n", - absolute_filename); - GNUNET_break (0); - } - } - if (absolute_filename != NULL) - GNUNET_free (absolute_filename); - if (plugin->server_proc == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Failed to start gnunet-helper-transport-wlan process\n"); - return GNUNET_SYSERR; - } - - - - /* Close the write end of the read pipe */ - GNUNET_DISK_pipe_close_end (plugin->server_stdout, - GNUNET_DISK_PIPE_END_WRITE); - - /* Close the read end of the write pipe */ - GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ); - - plugin->server_stdout_handle = - GNUNET_DISK_pipe_handle (plugin->server_stdout, - GNUNET_DISK_PIPE_END_READ); - plugin->server_stdin_handle = - GNUNET_DISK_pipe_handle (plugin->server_stdin, - GNUNET_DISK_PIPE_END_WRITE); - - GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Adding server_read_task for the gnunet-helper-transport-wlan\n"); - plugin->server_read_task = - GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, - plugin->server_stdout_handle, - &wlan_plugin_helper_read, plugin); + struct MacEndpoint *endpoint; +}; - plugin->helper_is_running = GNUNET_YES; - return GNUNET_YES; -} /** - * Stops the gnunet-helper-transport-wlan process. + * Print MAC addresses nicely. * - * @param plugin the transport plugin - * @return GNUNET_YES if process was started, GNUNET_SYSERR on error + * @param mac the mac address + * @return string to a static buffer with the human-readable mac, will be overwritten during the next call to this function */ -static int -wlan_transport_stop_wlan_helper (struct Plugin *plugin) +static const char * +mac_to_string (const struct GNUNET_TRANSPORT_WLAN_MacAddress * mac) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Stoping WLAN helper process\n"); + static char macstr[20]; - if (plugin->helper_is_running == GNUNET_NO) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "wlan_transport_stop_wlan_helper not needed, helper already stopped!"); - return GNUNET_YES; - } + GNUNET_snprintf (macstr, sizeof (macstr), "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", mac->mac[0], mac->mac[1], + mac->mac[2], mac->mac[3], mac->mac[4], mac->mac[5]); + return macstr; +} - if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task); - plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; - } - if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK) +/** + * Fill the radiotap header + * + * @param endpoint pointer to the endpoint, can be NULL + * @param header pointer to the radiotap header + * @param size total message size + */ +static void +get_radiotap_header (struct MacEndpoint *endpoint, + struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header, + uint16_t size) +{ + header->header.type = ntohs (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER); + header->header.size = ntohs (size); + if (NULL != endpoint) { - GNUNET_SCHEDULER_cancel (plugin->server_write_task); - plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; + header->rate = endpoint->rate; + header->tx_power = endpoint->tx_power; + header->antenna = endpoint->antenna; } - - if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK) + else { - GNUNET_SCHEDULER_cancel (plugin->server_read_task); - plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; + header->rate = 255; + header->tx_power = 0; + header->antenna = 0; } +} - GNUNET_DISK_pipe_close (plugin->server_stdout); - GNUNET_DISK_pipe_close (plugin->server_stdin); - GNUNET_OS_process_kill (plugin->server_proc, SIGKILL); - GNUNET_OS_process_wait (plugin->server_proc); - GNUNET_OS_process_close (plugin->server_proc); - plugin->helper_is_running = GNUNET_NO; +/** + * Generate the WLAN hardware header for one packet + * + * @param plugin the plugin handle + * @param header address to write the header to + * @param to_mac_addr address of the recipient + * @param size size of the whole packet, needed to calculate the time to send the packet + */ +static void +get_wlan_header (struct Plugin *plugin, + struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *header, + const struct GNUNET_TRANSPORT_WLAN_MacAddress *to_mac_addr, + unsigned int size) +{ + const int rate = 11000000; - return GNUNET_YES; + header->frame_control = htons (IEEE80211_FC0_TYPE_DATA); + header->addr1 = *to_mac_addr; + header->addr2 = plugin->mac_address; + header->addr3 = mac_bssid_gnunet; + header->duration = GNUNET_htole16 ((size * 1000000) / rate + 290); + header->sequence_control = 0; // FIXME? + header->llc[0] = WLAN_LLC_DSAP_FIELD; + header->llc[1] = WLAN_LLC_SSAP_FIELD; + header->llc[2] = 0; // FIXME? + header->llc[3] = 0; // FIXME? } + /** - * function for delayed restart of the helper process - * @param cls Finish_send struct if message should be finished - * @param tc TaskContext + * Send an ACK for a fragment we received. + * + * @param cls the 'struct MacEndpoint' the ACK must be sent to + * @param msg_id id of the message + * @param hdr pointer to the hdr where the ack is stored */ static void -delay_restart_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +send_ack (void *cls, uint32_t msg_id, + const struct GNUNET_MessageHeader *hdr) { - struct Finish_send *finish = cls; - struct Plugin *plugin; - - plugin = finish->plugin; + struct MacEndpoint *endpoint = cls; + struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage* radio_header; + uint16_t msize = ntohs (hdr->size); + size_t size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + msize; + char buf[size]; - plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; - if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) + if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) { - GNUNET_free_non_null (finish->msgstart); - GNUNET_free (finish); + GNUNET_break (0); return; } - - wlan_transport_start_wlan_helper (plugin); - - if (finish->size != 0) - { - plugin->server_write_task = - GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, - plugin->server_stdin_handle, - &finish_sending, finish); - } - else - { - set_next_send (plugin); - GNUNET_free_non_null (finish->msgstart); - GNUNET_free (finish); - } - + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Sending ACK to helper\n"); + radio_header = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) buf; + get_radiotap_header (endpoint, radio_header, size); + get_wlan_header (endpoint->plugin, + &radio_header->frame, + &endpoint->addr, + size); + memcpy (&radio_header[1], hdr, msize); + if (NULL != + GNUNET_HELPER_send (endpoint->plugin->suid_helper, + &radio_header->header, + GNUNET_NO /* dropping ACKs is bad */, + NULL, NULL)) + GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN ACKs sent"), + 1, GNUNET_NO); } + /** - * Function to restart the helper - * @param plugin pointer to the global plugin struct - * @param finish pointer to the Finish_send struct to finish + * Handles the data after all fragments are put together + * + * @param cls macendpoint this messages belongs to + * @param hdr pointer to the data */ static void -restart_helper (struct Plugin *plugin, struct Finish_send *finish) +wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr) { - static struct GNUNET_TIME_Relative next_try = { 1000 }; - GNUNET_assert (finish != NULL); - - wlan_transport_stop_wlan_helper (plugin); - plugin->server_write_task = - GNUNET_SCHEDULER_add_delayed (next_try, &delay_restart_helper, finish); - GNUNET_TIME_relative_multiply (next_try, HELPER_RESTART_SCALING_FACTOR); + struct MacEndpoint *endpoint = cls; + struct Plugin *plugin = endpoint->plugin; + struct MacAndSession mas; + GNUNET_STATISTICS_update (plugin->env->stats, + _("# WLAN messages defragmented"), 1, + GNUNET_NO); + mas.session = NULL; + mas.endpoint = endpoint; + (void) GNUNET_SERVER_mst_receive (plugin->fragment_data_tokenizer, + &mas, + (const char *) hdr, + ntohs (hdr->size), + GNUNET_YES, GNUNET_NO); } + /** - * function to finish a sending if not all could have been writen befor - * @param cls pointer to the Finish_send struct - * @param tc TaskContext + * Free a session + * + * @param session the session free */ static void -finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +free_session (struct Session *session) { - struct Finish_send *finish = cls; - struct Plugin *plugin; - ssize_t bytes; - - plugin = finish->plugin; - plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; - - if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) - { - GNUNET_free (finish->msgstart); - GNUNET_free (finish); - return; - } - bytes = - GNUNET_DISK_file_write (plugin->server_stdin_handle, - finish->head_of_next_write, finish->size); - - if (bytes != finish->size) - { - if (bytes != GNUNET_SYSERR) - { - finish->head_of_next_write += bytes; - finish->size -= bytes; - plugin->server_write_task = - GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, - plugin->server_stdin_handle, - &finish_sending, finish); - } - else + struct MacEndpoint *endpoint = session->mac; + struct PendingMessage *pm; + + endpoint->plugin->env->session_end (endpoint->plugin->env->cls, + &session->target, + session); + while (NULL != (pm = session->pending_message_head)) + { + GNUNET_CONTAINER_DLL_remove (session->pending_message_head, + session->pending_message_tail, pm); + if (GNUNET_SCHEDULER_NO_TASK != pm->timeout_task) { - restart_helper (plugin, finish); + GNUNET_SCHEDULER_cancel (pm->timeout_task); + pm->timeout_task = GNUNET_SCHEDULER_NO_TASK; } + GNUNET_free (pm->msg); + GNUNET_free (pm); } - else + GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head, + endpoint->sessions_tail, + session); + if (session->timeout_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_free (finish->msgstart); - GNUNET_free (finish); - set_next_send (plugin); + GNUNET_SCHEDULER_cancel (session->timeout_task); + session->timeout_task = GNUNET_SCHEDULER_NO_TASK; } + GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN sessions allocated"), -1, + GNUNET_NO); + GNUNET_free (session); } + /** - * function to send a hello beacon - * @param plugin pointer to the plugin struct + * A session is timing out. Clean up. + * + * @param cls pointer to the Session + * @param tc pointer to the GNUNET_SCHEDULER_TaskContext */ static void -send_hello_beacon (struct Plugin *plugin) +session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - uint16_t size; - ssize_t bytes; - uint16_t hello_size; - struct GNUNET_MessageHeader *msgheader; - struct ieee80211_frame *ieeewlanheader; - struct Radiotap_Send *radioHeader; - struct GNUNET_MessageHeader *msgheader2; - const struct GNUNET_MessageHeader *hello; - struct Finish_send *finish; - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Sending hello beacon\n"); - - GNUNET_assert (plugin != NULL); - - GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hello beacons send"), - 1, GNUNET_NO); + struct Session * session = cls; + struct GNUNET_TIME_Relative timeout; - hello = plugin->env->get_our_hello (); - hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello); - GNUNET_assert (sizeof (struct WlanHeader) + hello_size <= WLAN_MTU); - size = - sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) + - sizeof (struct ieee80211_frame) + hello_size; - - msgheader = GNUNET_malloc (size); - msgheader->size = htons (size); - msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); - - radioHeader = (struct Radiotap_Send *) &msgheader[1]; - getRadiotapHeader (plugin, NULL, radioHeader); - ieeewlanheader = (struct ieee80211_frame *) &radioHeader[1]; - getWlanHeader (ieeewlanheader, &bc_all_mac, plugin, size); - - msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1]; - /*msgheader2->size = - * htons (GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello) + - * sizeof (struct GNUNET_MessageHeader)); - * - * msgheader2->type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); */ - memcpy (msgheader2, hello, hello_size); - - bytes = GNUNET_DISK_file_write (plugin->server_stdin_handle, msgheader, size); - - if (bytes == GNUNET_SYSERR) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - _ - ("Error writing to wlan helper. errno == %d, ERROR: %s\n"), - errno, strerror (errno)); - finish = GNUNET_malloc (sizeof (struct Finish_send)); - finish->plugin = plugin; - finish->head_of_next_write = NULL; - finish->size = 0; - finish->msgstart = NULL; - restart_helper (plugin, finish); - - set_next_beacon_time (plugin); - - } - else + session->timeout_task = GNUNET_SCHEDULER_NO_TASK; + timeout = GNUNET_TIME_absolute_get_remaining (session->timeout); + if (0 == timeout.rel_value) { - GNUNET_assert (bytes == size); - set_next_beacon_time (plugin); - set_next_send (plugin); + free_session (session); + return; } - GNUNET_free (msgheader); - - + session->timeout_task = + GNUNET_SCHEDULER_add_delayed (timeout, &session_timeout, session); } + /** - * function to add an ack to send it for a received fragment - * @param cls MacEndpoint this ack belongs to - * @param msg_id id of the message - * @param hdr pointer to the hdr where the ack is stored + * Create a new session * + * @param endpoint pointer to the mac endpoint of the peer + * @param peer peer identity to use for this session + * @return returns the session */ -static void -add_ack_for_send (void *cls, uint32_t msg_id, - const struct GNUNET_MessageHeader *hdr) +static struct Session * +create_session (struct MacEndpoint *endpoint, + const struct GNUNET_PeerIdentity *peer) { + struct Session *session; - struct AckSendQueue *ack; + for (session = endpoint->sessions_head; NULL != session; session = session->next) + if (0 == memcmp (peer, &session->target, + sizeof (struct GNUNET_PeerIdentity))) + { + session->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); + return session; + } + GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN sessions allocated"), 1, + GNUNET_NO); + session = GNUNET_malloc (sizeof (struct Session)); + GNUNET_CONTAINER_DLL_insert_tail (endpoint->sessions_head, + endpoint->sessions_tail, + session); + session->mac = endpoint; + session->target = *peer; + session->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); + session->timeout_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, &session_timeout, session); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Created new session for peer `%s' with endpoint %s\n", + GNUNET_i2s (peer), + mac_to_string (&endpoint->addr)); + return session; +} - GNUNET_assert (cls != NULL); - struct MacEndpoint *endpoint = cls; - struct Plugin *plugin = endpoint->plugin; - struct GNUNET_MessageHeader *msgheader; - struct GNUNET_MessageHeader *msgheader2; - uint16_t size; - size = - sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) + - sizeof (struct ieee80211_frame) + ntohs (hdr->size) + - sizeof (struct AckSendQueue); +/** + * Function called once we have successfully given the fragment + * message to the SUID helper process and we are thus ready for + * the next fragment. + * + * @param cls the 'struct FragmentMessage' + * @param result result of the operation (GNUNET_OK on success, GNUNET_NO if the helper died, GNUNET_SYSERR + * if the helper was stopped) + */ +static void +fragment_transmission_done (void *cls, + int result) +{ + struct FragmentMessage *fm = cls; - ack = GNUNET_malloc (size); - ack->message_id = msg_id; - ack->endpoint = endpoint; + fm->sh = NULL; + GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext); +} - size = - sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) + - sizeof (struct ieee80211_frame) + ntohs (hdr->size); - msgheader = (struct GNUNET_MessageHeader *) &ack[1]; - ack->hdr = (struct GNUNET_MessageHeader *) &ack[1]; - msgheader->size = htons (size); - msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); +/** + * Transmit a fragment of a message. + * + * @param cls 'struct FragmentMessage' this fragment message belongs to + * @param hdr pointer to the start of the fragment message + */ +static void +transmit_fragment (void *cls, + const struct GNUNET_MessageHeader *hdr) +{ + struct FragmentMessage *fm = cls; + struct MacEndpoint *endpoint = fm->macendpoint; + size_t size; + uint16_t msize; + + msize = ntohs (hdr->size); + size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + msize; + { + char buf[size]; + struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radio_header; + + radio_header = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) buf; + get_radiotap_header (endpoint, radio_header, size); + get_wlan_header (endpoint->plugin, + &radio_header->frame, + &endpoint->addr, + size); + memcpy (&radio_header[1], hdr, msize); + GNUNET_assert (NULL == fm->sh); + fm->sh = GNUNET_HELPER_send (endpoint->plugin->suid_helper, + &radio_header->header, + GNUNET_NO, + &fragment_transmission_done, fm); + if (NULL != fm->sh) + GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN message fragments sent"), + 1, GNUNET_NO); + else + GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext); + } +} - ack->radioHeader = (struct Radiotap_Send *) &msgheader[1]; - ack->ieeewlanheader = (struct ieee80211_frame *) &(ack->radioHeader)[1]; - msgheader2 = (struct GNUNET_MessageHeader *) &(ack->ieeewlanheader)[1]; - memcpy (msgheader2, hdr, ntohs (hdr->size)); - GNUNET_CONTAINER_DLL_insert_tail (plugin->ack_send_queue_head, - plugin->ack_send_queue_tail, ack); +/** + * Frees the space of a message in the fragment queue (send queue) + * + * @param fm message to free + */ +static void +free_fragment_message (struct FragmentMessage *fm) +{ + struct MacEndpoint *endpoint = fm->macendpoint; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Adding ack with message id %u to send, AckSendQueue %p, endpoint %p\n", - msg_id, ack, endpoint); - set_next_send (plugin); + GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# WLAN messages pending (with fragmentation)"), + -1, GNUNET_NO); + GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head, + endpoint->sending_messages_tail, fm); + if (NULL != fm->sh) + { + GNUNET_HELPER_send_cancel (fm->sh); + fm->sh = NULL; + } + GNUNET_FRAGMENT_context_destroy (fm->fragcontext); + if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (fm->timeout_task); + fm->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_free (fm); } + /** - * Function for the scheduler if a FragmentMessage times out - * @param cls pointer to the FragmentMessage + * A FragmentMessage has timed out. Remove it. + * + * @param cls pointer to the 'struct FragmentMessage' * @param tc pointer to the GNUNET_SCHEDULER_TaskContext */ static void @@ -1849,284 +795,162 @@ fragmentmessage_timeout (void *cls, { struct FragmentMessage *fm = cls; - GNUNET_assert (fm != NULL); fm->timeout_task = GNUNET_SCHEDULER_NO_TASK; - if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) + if (NULL != fm->cont) { - return; + fm->cont (fm->cont_cls, &fm->target, GNUNET_SYSERR); + fm->cont = NULL; } - free_fragment_message (fm->session->mac->plugin, fm); + free_fragment_message (fm); } + /** - * Function to check if there is some space in the fragment queue - * inserts a message if space is available - * @param plugin the plugin struct + * Transmit a message to the given destination with fragmentation. + * + * @param endpoint desired destination + * @param timeout how long can the message wait? + * @param target peer that should receive the message + * @param msg message to transmit + * @param cont continuation to call once the message has + * been transmitted (or if the transport is ready + * for the next transmission call; or if the + * peer disconnected...); can be NULL + * @param cont_cls closure for cont */ - static void -check_fragment_queue (struct Plugin *plugin) +send_with_fragmentation (struct MacEndpoint *endpoint, + struct GNUNET_TIME_Relative timeout, + const struct GNUNET_PeerIdentity *target, + const struct GNUNET_MessageHeader *msg, + GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) + { - struct Session *session; struct FragmentMessage *fm; - struct GNUNET_PeerIdentity pid; - - struct PendingMessage *pm; - - if (plugin->pending_Fragment_Messages < FRAGMENT_QUEUE_SIZE) - { - session = get_next_queue_session (plugin); - if (session != NULL) - { - pm = session->pending_message_head; - GNUNET_assert (pm != NULL); - GNUNET_CONTAINER_DLL_remove (session->pending_message_head, - session->pending_message_tail, pm); - session->mac->fragment_messages_out_count++; - session->fragment_messages_out_count++; - plugin->pending_Fragment_Messages++; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"), - plugin->pending_Fragment_Messages, GNUNET_NO); - - fm = GNUNET_malloc (sizeof (struct FragmentMessage)); - fm->session = session; - fm->timeout.abs_value = pm->timeout.abs_value; - fm->frag = NULL; - fm->fragcontext = - GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU, - &plugin->tracker, - GNUNET_TIME_UNIT_SECONDS, - &(pm->msg->header), - &add_message_for_send, fm); - fm->timeout_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining - (fm->timeout), fragmentmessage_timeout, - fm); - GNUNET_CONTAINER_DLL_insert_tail (session->mac->sending_messages_head, - session->mac->sending_messages_tail, - fm); - - if (pm->transmit_cont != NULL) - { - pid = session->target; - pm->transmit_cont (pm->transmit_cont_cls, &pid, GNUNET_OK); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "called pm->transmit_cont for %p\n", session); - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "no pm->transmit_cont for %p\n", session); - } - GNUNET_free (pm); - - if (session->pending_message_head != NULL) - { - //requeue session - queue_session (plugin, session); - } - - } - } + struct Plugin *plugin; - //check if timeout changed - set_next_send (plugin); + plugin = endpoint->plugin; + fm = GNUNET_malloc (sizeof (struct FragmentMessage)); + fm->macendpoint = endpoint; + fm->target = *target; + fm->timeout = GNUNET_TIME_relative_to_absolute (timeout); + fm->cont = cont; + fm->cont_cls = cont_cls; + fm->fragcontext = + GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU, + &plugin->tracker, + GNUNET_TIME_UNIT_SECONDS, + msg, + &transmit_fragment, fm); + fm->timeout_task = + GNUNET_SCHEDULER_add_delayed (timeout, + &fragmentmessage_timeout, fm); + GNUNET_CONTAINER_DLL_insert_tail (endpoint->sending_messages_head, + endpoint->sending_messages_tail, + fm); } + /** - * Function to send an ack, does not free the ack - * @param plugin pointer to the plugin + * Free a MAC endpoint. + * + * @param endpoint pointer to the MacEndpoint to free */ static void -send_ack (struct Plugin *plugin) +free_macendpoint (struct MacEndpoint *endpoint) { + struct Plugin *plugin = endpoint->plugin; + struct FragmentMessage *fm; + struct Session *session; - ssize_t bytes; - struct AckSendQueue *ack; - struct Finish_send *finish; - - ack = plugin->ack_send_queue_head; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Sending ack for message_id %u for mac endpoint %p, size %u\n", - ack->message_id, ack->endpoint, - ntohs (ack->hdr->size) - sizeof (struct Radiotap_Send)); - GNUNET_assert (plugin != NULL); - GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks send"), 1, - GNUNET_NO); - - getRadiotapHeader (plugin, ack->endpoint, ack->radioHeader); - getWlanHeader (ack->ieeewlanheader, &ack->endpoint->addr, plugin, - ntohs (ack->hdr->size)); + GNUNET_STATISTICS_update (plugin->env->stats, + _("# WLAN MAC endpoints allocated"), -1, GNUNET_NO); + while (NULL != (session = endpoint->sessions_head)) + free_session (session); + while (NULL != (fm = endpoint->sending_messages_head)) + free_fragment_message (fm); + GNUNET_CONTAINER_DLL_remove (plugin->mac_head, + plugin->mac_tail, + endpoint); - bytes = - GNUNET_DISK_file_write (plugin->server_stdin_handle, ack->hdr, - ntohs (ack->hdr->size)); - if (bytes == GNUNET_SYSERR) + if (NULL != endpoint->defrag) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - _ - ("Error writing to wlan helper. errno == %d, ERROR: %s\n"), - errno, strerror (errno)); - finish = GNUNET_malloc (sizeof (struct Finish_send)); - finish->plugin = plugin; - finish->head_of_next_write = NULL; - finish->size = 0; - finish->msgstart = NULL; - restart_helper (plugin, finish); + GNUNET_DEFRAGMENT_context_destroy(endpoint->defrag); + endpoint->defrag = NULL; } - else + + plugin->mac_count--; + if (GNUNET_SCHEDULER_NO_TASK != endpoint->timeout_task) { - GNUNET_assert (bytes == ntohs (ack->hdr->size)); - GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head, - plugin->ack_send_queue_tail, ack); - GNUNET_free (ack); - set_next_send (plugin); + GNUNET_SCHEDULER_cancel (endpoint->timeout_task); + endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK; } + GNUNET_free (endpoint); } + /** - * Function called when wlan helper is ready to get some data + * A MAC endpoint is timing out. Clean up. * - * @param cls closure - * @param tc GNUNET_SCHEDULER_TaskContext + * @param cls pointer to the MacEndpoint + * @param tc pointer to the GNUNET_SCHEDULER_TaskContext */ static void -do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +macendpoint_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct Plugin *plugin = cls; - - GNUNET_assert (plugin != NULL); - - plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - return; - - struct Session *session; - struct FragmentMessage *fm; - struct Finish_send *finish; - struct FragmentMessage_queue *fmq; - ssize_t bytes; - - if (plugin->ack_send_queue_head != NULL) - { - send_ack (plugin); - return; - } - - //test if a "hello-beacon" has to be send - if (GNUNET_TIME_absolute_get_remaining (plugin->beacon_time).rel_value == 0) - { - send_hello_beacon (plugin); - return; - } + struct MacEndpoint *endpoint = cls; + struct GNUNET_TIME_Relative timeout; - if (plugin->sending_messages_head != NULL) + endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK; + timeout = GNUNET_TIME_absolute_get_remaining (endpoint->timeout); + if (0 == timeout.rel_value) { - GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan fragments send"), 1, - GNUNET_NO); - - fmq = plugin->sending_messages_head; - fm = fmq->content; - GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head, - plugin->sending_messages_tail, fmq); - GNUNET_free (fmq); - - session = fm->session; - GNUNET_assert (session != NULL); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT for fragment message %p, size: %u\n", - fm, fm->size); - getRadiotapHeader (plugin, session->mac, fm->radioHeader); - getWlanHeader (fm->ieeewlanheader, &(fm->session->mac->addr), plugin, - fm->size); - - bytes = - GNUNET_DISK_file_write (plugin->server_stdin_handle, fm->frag, - fm->size); - - - if (bytes != fm->size) - { - finish = GNUNET_malloc (sizeof (struct Finish_send)); - finish->plugin = plugin; - finish->msgstart = (struct GNUNET_MessageHeader *) fm->frag; - GNUNET_assert (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); - - if (bytes == GNUNET_SYSERR) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - _ - ("Error writing to wlan helper. errno == %d, ERROR: %s\n"), - errno, strerror (errno)); - - finish->head_of_next_write = fm->frag; - finish->size = fm->size; - restart_helper (plugin, finish); - } - else - { - finish->head_of_next_write = fm->frag + bytes; - finish->size = fm->size - bytes; - plugin->server_write_task = - GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, - plugin->server_stdin_handle, - &finish_sending, finish); - } - - fm->frag = NULL; - } - else - { - GNUNET_free (fm->frag); - fm->frag = NULL; - set_next_send (plugin); - } - GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext); + free_macendpoint (endpoint); return; } - -#if 1 - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "do_transmit did nothing, should not happen!\n"); -#endif - set_next_send (plugin); + endpoint->timeout_task = + GNUNET_SCHEDULER_add_delayed (timeout, &macendpoint_timeout, + endpoint); } + /** - * Another peer has suggested an address for this - * peer and transport plugin. Check that this could be a valid - * address. If so, consider adding it to the list - * of addresses. + * Find (or create) a MacEndpoint with a specific MAC address * - * @param cls closure - * @param addr pointer to the address - * @param addrlen length of addr - * @return GNUNET_OK if this is a plausible address for this peer - * and transport + * @param plugin pointer to the plugin struct + * @param addr the MAC address of the endpoint + * @return handle to our data structure for this MAC */ -static int -wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) +static struct MacEndpoint * +create_macendpoint (struct Plugin *plugin, + const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr) { - //struct Plugin *plugin = cls; - - /* check if the address is plausible; if so, - * add it to our list! */ - - GNUNET_assert (cls != NULL); - //FIXME mitm is not checked - //Mac Address has 6 bytes - if (addrlen == 6) - { - /* TODO check for bad addresses like multicast, broadcast, etc */ - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "wlan_plugin_address_suggested got good address, size %u!\n", - addrlen); - return GNUNET_OK; - } - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "wlan_plugin_address_suggested got bad address, size %u!\n", - addrlen); - return GNUNET_SYSERR; + struct MacEndpoint *pos; + + for (pos = plugin->mac_head; NULL != pos; pos = pos->next) + if (0 == memcmp (addr, &pos->addr, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) + return pos; + pos = GNUNET_malloc (sizeof (struct MacEndpoint)); + pos->addr = *addr; + pos->plugin = plugin; + pos->defrag = + GNUNET_DEFRAGMENT_context_create (plugin->env->stats, WLAN_MTU, + MESSAGES_IN_DEFRAG_QUEUE_PER_MAC, + pos, + &wlan_data_message_handler, + &send_ack); + pos->timeout = GNUNET_TIME_relative_to_absolute (MACENDPOINT_TIMEOUT); + pos->timeout_task = + GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout, + pos); + GNUNET_CONTAINER_DLL_insert (plugin->mac_head, plugin->mac_tail, pos); + plugin->mac_count++; + GNUNET_STATISTICS_update (plugin->env->stats, _("# WLAN MAC endpoints allocated"), + 1, GNUNET_NO); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "New MAC endpoint `%s'\n", + mac_to_string (addr)); + return pos; } @@ -2138,33 +962,55 @@ wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) * @param address the address * @return the session or NULL of max connections exceeded */ - static struct Session * wlan_plugin_get_session (void *cls, - const struct GNUNET_HELLO_Address *address) + const struct GNUNET_HELLO_Address *address) { struct Plugin *plugin = cls; - struct Session * s = NULL; - - GNUNET_assert (plugin != NULL); - GNUNET_assert (address != NULL); + struct MacEndpoint *endpoint; - if (GNUNET_OK == wlan_plugin_address_suggested (plugin, - address->address, - address->address_length)) - { - s = get_session (plugin, address->address, &address->peer); - } - else + if (NULL == address) + return NULL; + if (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress) != address->address_length) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME, - _("Wlan Address len %d is wrong\n"), address->address_length); - return s; + GNUNET_break (0); + return NULL; } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Service asked to create session for peer `%s' with MAC `%s'\n", + GNUNET_i2s (&address->peer), + mac_to_string (address->address)); + endpoint = create_macendpoint (plugin, address->address); + return create_session (endpoint, &address->peer); +} + - return s; +/** + * Function that can be used to force the plugin to disconnect + * from the given peer and cancel all previous transmissions + * (and their continuation). + * + * @param cls closure + * @param target peer from which to disconnect + */ +static void +wlan_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) +{ + struct Plugin *plugin = cls; + struct Session *session; + struct MacEndpoint *endpoint; + + for (endpoint = plugin->mac_head; NULL != endpoint; endpoint = endpoint->next) + for (session = endpoint->sessions_head; NULL != session; session = session->next) + if (0 == memcmp (target, &session->target, + sizeof (struct GNUNET_PeerIdentity))) + { + free_session (session); + break; /* inner-loop only (in case peer has another MAC as well!) */ + } } + /** * Function that can be used by the transport service to transmit * a message using the plugin. Note that in the case of a @@ -2201,925 +1047,586 @@ wlan_plugin_send (void *cls, GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) { struct Plugin *plugin = cls; - struct PendingMessage *newmsg; struct WlanHeader *wlanheader; - - GNUNET_assert (plugin != NULL); - GNUNET_assert (session != NULL); - GNUNET_assert (msgbuf_size > 0); - - //queue message: - - //queue message in session - //test if there is no other message in the "queue" - //FIXME: to many send requests - if (session->pending_message_head != NULL) - { - newmsg = session->pending_message_head; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "wlan_plugin_send: a pending message is already in the queue for this client\n remaining time to send this message is %u, queued fragment messages for this mac connection %u\n", - GNUNET_TIME_absolute_get_remaining (newmsg-> - timeout).rel_value, - session->mac->fragment_messages_out_count); - } - - newmsg = GNUNET_malloc (sizeof (struct PendingMessage)); - newmsg->msg = GNUNET_malloc (msgbuf_size + sizeof (struct WlanHeader)); - wlanheader = newmsg->msg; - //copy msg to buffer, not fragmented / segmented yet, but with message header + size_t size = msgbuf_size + sizeof (struct WlanHeader); + char buf[size] GNUNET_ALIGN; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Transmitting %u bytes of payload to peer `%s' (starting with %u byte message of type %u)\n", + msgbuf_size, + GNUNET_i2s (&session->target), + (unsigned int) ntohs (((struct GNUNET_MessageHeader*)msgbuf)->size), + (unsigned int) ntohs (((struct GNUNET_MessageHeader*)msgbuf)->type)); + wlanheader = (struct WlanHeader *) buf; wlanheader->header.size = htons (msgbuf_size + sizeof (struct WlanHeader)); wlanheader->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA); - memcpy (&(wlanheader->target), &session->target, sizeof (struct GNUNET_PeerIdentity)); - memcpy (&(wlanheader->source), plugin->env->my_identity, - sizeof (struct GNUNET_PeerIdentity)); - wlanheader->crc = 0; + wlanheader->sender = *plugin->env->my_identity; + wlanheader->target = session->target; + wlanheader->crc = htonl (GNUNET_CRYPTO_crc32_n (msgbuf, msgbuf_size)); memcpy (&wlanheader[1], msgbuf, msgbuf_size); - wlanheader->crc = - htonl (GNUNET_CRYPTO_crc32_n - ((char *) wlanheader, msgbuf_size + sizeof (struct WlanHeader))); - - newmsg->transmit_cont = cont; - newmsg->transmit_cont_cls = cont_cls; - newmsg->timeout = GNUNET_TIME_relative_to_absolute (to); - - newmsg->timeout.abs_value = newmsg->timeout.abs_value - 500; - - newmsg->message_size = msgbuf_size + sizeof (struct WlanHeader); - - GNUNET_CONTAINER_DLL_insert_tail (session->pending_message_head, - session->pending_message_tail, newmsg); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "New message for %p with size (incl wlan header) %u added\n", - session, newmsg->message_size); -#if DEBUG_WLAN > 1 - hexdump (msgbuf, GNUNET_MIN (msgbuf_size, 256)); -#endif - //queue session - queue_session (plugin, session); - - check_fragment_queue (plugin); - //FIXME not the correct size - return msgbuf_size; -} - - -/** - * function to free a mac endpoint - * @param plugin pointer to the plugin struct - * @param endpoint pointer to the MacEndpoint to free - */ -static void -free_macendpoint (struct Plugin *plugin, struct MacEndpoint *endpoint) -{ - struct Sessionqueue *sessions; - struct Sessionqueue *sessions_next; - - GNUNET_assert (endpoint != NULL); - - sessions = endpoint->sessions_head; - while (sessions != NULL) - { - sessions_next = sessions->next; - free_session (plugin, sessions, GNUNET_NO); - sessions = sessions_next; - } - - GNUNET_CONTAINER_DLL_remove (plugin->mac_head, plugin->mac_tail, endpoint); - if (endpoint->timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (endpoint->timeout_task); - endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - plugin->mac_count--; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"), - plugin->mac_count, GNUNET_NO); - GNUNET_free (endpoint); - + send_with_fragmentation (session->mac, + to, + &session->target, + &wlanheader->header, + cont, cont_cls); + return size; } -/** - * function to free a session - * @param plugin pointer to the plugin - * @param queue pointer to the sessionqueue element to free - * @param do_free_macendpoint if GNUNET_YES and mac endpoint would be empty, free mac endpoint - */ -static void -free_session (struct Plugin *plugin, struct Sessionqueue *queue, - int do_free_macendpoint) -{ - struct Sessionqueue *pendingsession; - struct Sessionqueue *pendingsession_tmp; - struct PendingMessage *pm; - struct MacEndpoint *endpoint; - struct FragmentMessage *fm; - struct FragmentMessage *fmnext; - int check = 0; - - GNUNET_assert (plugin != NULL); - GNUNET_assert (queue != NULL); - GNUNET_assert (queue->content != NULL); - - //session found - //is this session pending for send - pendingsession = plugin->pending_Sessions_head; - while (pendingsession != NULL) - { - pendingsession_tmp = pendingsession; - pendingsession = pendingsession->next; - GNUNET_assert (pendingsession_tmp->content != NULL); - if (pendingsession_tmp->content == queue->content) - { - plugin->pendingsessions--; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), - plugin->pendingsessions, GNUNET_NO); - GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, - plugin->pending_Sessions_tail, - pendingsession_tmp); - GNUNET_free (pendingsession_tmp); - - GNUNET_assert (check == 0); - check = 1; - } - } - - endpoint = queue->content->mac; - fm = endpoint->sending_messages_head; - while (fm != NULL) - { - fmnext = fm->next; - if (fm->session == queue->content) - { - free_fragment_message (plugin, fm); - } - fm = fmnext; - } - - // remove PendingMessage - pm = queue->content->pending_message_head; - while (pm != NULL) - { - GNUNET_CONTAINER_DLL_remove (queue->content->pending_message_head, - queue->content->pending_message_tail, pm); - GNUNET_free (pm->msg); - GNUNET_free (pm); - pm = queue->content->pending_message_head; - } - - GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head, endpoint->sessions_tail, - queue); - //Check that no ohter session on this endpoint for this session exits - GNUNET_assert (search_session (plugin, endpoint, &queue->content->target) == - NULL); - if (endpoint->sessions_head == NULL && do_free_macendpoint == GNUNET_YES) - { - free_macendpoint (plugin, endpoint); - //check if no endpoint with the same address exists - GNUNET_assert (get_macendpoint (plugin, &endpoint->addr, GNUNET_NO) == - NULL); - } - - if (queue->content->timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (queue->content->timeout_task); - queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - GNUNET_free (queue); - - check_fragment_queue (plugin); -} /** - * Function that can be used to force the plugin to disconnect - * from the given peer and cancel all previous transmissions - * (and their continuation). + * We have received data from the WLAN via some session. Process depending + * on the message type (HELLO, DATA, FRAGMENTATION or FRAGMENTATION-ACK). * - * @param cls closure - * @param target peer from which to disconnect + * @param cls pointer to the plugin + * @param client pointer to the session this message belongs to + * @param hdr start of the message */ -static void -wlan_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) +static int +process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) { struct Plugin *plugin = cls; - struct Sessionqueue *queue; - struct Sessionqueue *queue_next; - struct MacEndpoint *endpoint = plugin->mac_head; - struct MacEndpoint *endpoint_next; + struct MacAndSession *mas = client; + struct MacAndSession xmas; +#define NUM_ATS 2 + struct GNUNET_ATS_Information ats[NUM_ATS]; /* FIXME: do better here */ + struct FragmentMessage *fm; + struct GNUNET_PeerIdentity tmpsource; + const struct WlanHeader *wlanheader; + int ret; + uint16_t msize; - // just look at all the session for the needed one - while (endpoint != NULL) + ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); + ats[0].value = htonl (1); + ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); + ats[1].value = htonl (GNUNET_ATS_NET_WLAN); + msize = ntohs (hdr->size); + switch (ntohs (hdr->type)) { - queue = endpoint->sessions_head; - endpoint_next = endpoint->next; - while (queue != NULL) + case GNUNET_MESSAGE_TYPE_HELLO: + if (GNUNET_OK != + GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) hdr, &tmpsource)) { - // content is never NULL - GNUNET_assert (queue->content != NULL); - queue_next = queue->next; - if (memcmp - (target, &(queue->content->target), - sizeof (struct GNUNET_PeerIdentity)) == 0) - { - free_session (plugin, queue, GNUNET_YES); - } - // try next - queue = queue_next; + GNUNET_break_op (0); + break; } - endpoint = endpoint_next; - } -} - -/** - * Convert the transports address to a nice, human-readable - * format. - * - * @param cls closure - * @param type name of the transport that generated the address - * @param addr one of the addresses of the host, NULL for the last address - * the specific address format depends on the transport - * @param addrlen length of the address - * @param numeric should (IP) addresses be displayed in numeric form? - * @param timeout after how long should we give up? - * @param asc function to call on each string - * @param asc_cls closure for asc - */ -static void -wlan_plugin_address_pretty_printer (void *cls, const char *type, - const void *addr, size_t addrlen, - int numeric, - struct GNUNET_TIME_Relative timeout, - GNUNET_TRANSPORT_AddressStringCallback asc, - void *asc_cls) -{ - char *ret; - const unsigned char *input; - - //GNUNET_assert(cls !=NULL); - if (addrlen != sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) - { - /* invalid address (MAC addresses have 6 bytes) */ - //GNUNET_break (0); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_plugin_address_pretty_printer got size: %u, worng size!\n", - addrlen); - asc (asc_cls, NULL); - return; - } - input = (const unsigned char *) addr; - GNUNET_asprintf (&ret, - "Transport %s: %s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", - type, PROTOCOL_PREFIX, input[0], input[1], input[2], - input[3], input[4], input[5]); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_plugin_address_pretty_printer got size: %u, nummeric %u, type %s; made string: %s\n", - addrlen, numeric, type, ret); - asc (asc_cls, ret); - //only one mac address per plugin - asc (asc_cls, NULL); -} - - - -/** - * handels the data after all fragments are put together - * @param cls macendpoint this messages belongs to - * @param hdr pointer to the data - */ -static void -wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr) -{ - struct MacEndpoint *endpoint = (struct MacEndpoint *) cls; - struct Plugin *plugin = endpoint->plugin; - struct WlanHeader *wlanheader; - struct Session *session; - - const struct GNUNET_MessageHeader *temp_hdr; - struct GNUNET_PeerIdentity tmpsource; - int crc; - - GNUNET_assert (plugin != NULL); - - if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA) - { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Processing %u bytes of HELLO from peer `%s' at MAC %s\n", + (unsigned int) msize, + GNUNET_i2s (&tmpsource), + mac_to_string (&mas->endpoint->addr)); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_data_message_handler got GNUNET_MESSAGE_TYPE_WLAN_DATA size: %u\n", - ntohs (hdr->size)); - - if (ntohs (hdr->size) < - sizeof (struct WlanHeader) + sizeof (struct GNUNET_MessageHeader)) + GNUNET_STATISTICS_update (plugin->env->stats, + _("# HELLO messages received via WLAN"), 1, + GNUNET_NO); + plugin->env->receive (plugin->env->cls, + &tmpsource, + hdr, + ats, NUM_ATS, + mas->session, + (mas->endpoint == NULL) ? NULL : (const char *) &mas->endpoint->addr, + (mas->endpoint == NULL) ? 0 : sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); + break; + case GNUNET_MESSAGE_TYPE_FRAGMENT: + if (NULL == mas->endpoint) { - //packet not big enought - return; + GNUNET_break (0); + break; } - + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Processing %u bytes of FRAGMENT from MAC %s\n", + (unsigned int) msize, + mac_to_string (&mas->endpoint->addr)); GNUNET_STATISTICS_update (plugin->env->stats, - _("# wlan whole messages received"), 1, - GNUNET_NO); - wlanheader = (struct WlanHeader *) hdr; - - session = search_session (plugin, endpoint, &wlanheader->source); - - temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1]; - crc = ntohl (wlanheader->crc); - wlanheader->crc = 0; - if (GNUNET_CRYPTO_crc32_n - ((char *) wlanheader, ntohs (wlanheader->header.size)) != crc) + _("# fragments received via WLAN"), 1, GNUNET_NO); + (void) GNUNET_DEFRAGMENT_process_fragment (mas->endpoint->defrag, + hdr); + break; + case GNUNET_MESSAGE_TYPE_FRAGMENT_ACK: + if (NULL == mas->endpoint) { - //wrong crc, dispose message - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME, - "Wlan message header crc was wrong: %u != %u\n", - GNUNET_CRYPTO_crc32_n ((char *) wlanheader, - ntohs (wlanheader->header.size)), - crc); - hexdump ((void *) hdr, ntohs (hdr->size)); - return; + GNUNET_break (0); + break; } - - //if not in session list - if (session == NULL) + GNUNET_STATISTICS_update (plugin->env->stats, _("# ACKs received via WLAN"), + 1, GNUNET_NO); + for (fm = mas->endpoint->sending_messages_head; NULL != fm; fm = fm->next) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "WLAN client not in session list: packet size = %u, inner size = %u, header size = %u\n", - ntohs (wlanheader->header.size), ntohs (temp_hdr->size), - sizeof (struct WlanHeader)); - //try if it is a hello message - if (ntohs (wlanheader->header.size) >= - ntohs (temp_hdr->size) + sizeof (struct WlanHeader)) + ret = GNUNET_FRAGMENT_process_ack (fm->fragcontext, hdr); + if (GNUNET_OK == ret) { - if (ntohs (temp_hdr->type) == GNUNET_MESSAGE_TYPE_HELLO) - { - if (GNUNET_HELLO_get_id - ((const struct GNUNET_HELLO_Message *) temp_hdr, - &tmpsource) == GNUNET_OK) - { - session = create_session (plugin, endpoint, &tmpsource); - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, - "WLAN client not in session list and hello message is not okay\n"); - return; - } - - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, - "WLAN client not in session list and not a hello message\n"); - return; - } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Got last ACK, finished message transmission to `%s' (%p)\n", + mac_to_string (&mas->endpoint->addr), + fm); + mas->endpoint->timeout = GNUNET_TIME_relative_to_absolute (MACENDPOINT_TIMEOUT); + if (NULL != fm->cont) + { + fm->cont (fm->cont_cls, &fm->target, GNUNET_OK); + fm->cont = NULL; + } + free_fragment_message (fm); + break; } - else + if (GNUNET_NO == ret) { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, - "WLAN client not in session list and message size in does not fit\npacket size = %u, inner size = %u, header size = %u\n", - ntohs (wlanheader->header.size), - ntohs (temp_hdr->size), sizeof (struct WlanHeader)); - return; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Got an ACK, message transmission to `%s' not yet finished\n", + mac_to_string (&mas->endpoint->addr)); + break; } } - - //"receive" the message - - if (memcmp - (&wlanheader->source, &session->target, - sizeof (struct GNUNET_PeerIdentity)) != 0) + LOG (GNUNET_ERROR_TYPE_DEBUG, + "ACK not matched against any active fragmentation with MAC `%s'\n", + mac_to_string (&mas->endpoint->addr)); + break; + case GNUNET_MESSAGE_TYPE_WLAN_DATA: + if (NULL == mas->endpoint) { - //wrong peer id - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "WLAN peer source id doesn't match packet peer source id: session %p\n", - session); - return; + GNUNET_break (0); + break; } - - if (memcmp - (&wlanheader->target, plugin->env->my_identity, - sizeof (struct GNUNET_PeerIdentity)) != 0) + if (msize < sizeof (struct WlanHeader)) { - //wrong peer id - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "WLAN peer target id doesn't match our peer id: session %p\n", - session); - return; - } - - GNUNET_SERVER_mst_receive (plugin->data_tokenizer, session, - (const char *) temp_hdr, - ntohs (hdr->size) - sizeof (struct WlanHeader), - GNUNET_YES, GNUNET_NO); - - return; - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, - "wlan_data_message_handler got wrong message type: %u\n", - ntohs (hdr->size)); - return; - } -} - -/** - * function to process the a message, give it to the higher layer - * @param cls pointer to the plugin - * @param client pointer to the session this message belongs to - * @param hdr start of the message - */ -//TODO ATS informations -static void -process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) -{ - - GNUNET_assert (client != NULL); - GNUNET_assert (cls != NULL); - struct Session *session = (struct Session *) client; - struct Plugin *plugin = (struct Plugin *) cls; - struct GNUNET_ATS_Information ats[2]; - - ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); - ats[0].value = htonl (1); - ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats[1].value = htonl (GNUNET_ATS_NET_WLAN); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Calling plugin->env->receive for session %p; %s; size: %u\n", - session, wlan_plugin_address_to_string (NULL, - session->mac-> - addr.mac, 6), - htons (hdr->size)); - plugin->env->receive (plugin->env->cls, &(session->target), hdr, - (const struct GNUNET_ATS_Information *) &ats, 2, - session, (const char *) &session->mac->addr, - sizeof (session->mac->addr)); -} - -/** - * Function used for to process the data received from the wlan interface - * - * @param cls the plugin handle - * @param session_light pointer to the struct holding known informations - * @param hdr hdr of the GNUNET_MessageHeader - * @param rxinfo pointer to the radiotap informations got with this packet FIXME: give ATS for info - */ -static void -wlan_data_helper (void *cls, struct Session_light *session_light, - const struct GNUNET_MessageHeader *hdr, - const struct Radiotap_rx *rxinfo) -{ - struct Plugin *plugin = cls; - struct FragmentMessage *fm; - struct FragmentMessage *fm2; - struct GNUNET_PeerIdentity tmpsource; - - GNUNET_assert (plugin != NULL); - - //ADVERTISEMENT - if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_HELLO) - { - - //TODO better DOS protection, error handling - //TODO test first than create session - GNUNET_assert (session_light != NULL); - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_HELLO size: %u; %s\n", - ntohs (hdr->size), wlan_plugin_address_to_string (NULL, - session_light->addr. - mac, 6)); - if (session_light->macendpoint == NULL) + GNUNET_break (0); + break; + } + wlanheader = (const struct WlanHeader *) hdr; + if (0 != memcmp (&wlanheader->target, + plugin->env->my_identity, + sizeof (struct GNUNET_PeerIdentity))) { - session_light->macendpoint = - get_macendpoint (plugin, &session_light->addr, GNUNET_YES); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "WLAN data for `%s', not for me, ignoring\n", + GNUNET_i2s (&wlanheader->target)); + break; } - - - if (GNUNET_HELLO_get_id - ((const struct GNUNET_HELLO_Message *) hdr, &tmpsource) == GNUNET_OK) + if (ntohl (wlanheader->crc) != + GNUNET_CRYPTO_crc32_n (&wlanheader[1], msize - sizeof (struct WlanHeader))) { - session_light->session = - search_session (plugin, session_light->macendpoint, &tmpsource); - if (session_light->session == NULL) - { - session_light->session = - create_session (plugin, session_light->macendpoint, &tmpsource); - } GNUNET_STATISTICS_update (plugin->env->stats, - _("# wlan hello messages received"), 1, - GNUNET_NO); - plugin->env->receive (plugin->env->cls, &session_light->session->target, - hdr, NULL, 0, session_light->session, - (const char *) &session_light->session->mac->addr, - sizeof (session_light->session->mac->addr)); + _("# WLAN DATA messages discarded due to CRC32 error"), 1, + GNUNET_NO); + break; + } + xmas.endpoint = mas->endpoint; + xmas.session = create_session (mas->endpoint, &wlanheader->sender); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Processing %u bytes of WLAN DATA from peer `%s'\n", + (unsigned int) msize, + GNUNET_i2s (&wlanheader->sender)); + (void) GNUNET_SERVER_mst_receive (plugin->wlan_header_payload_tokenizer, + &xmas, + (const char *) &wlanheader[1], + msize - sizeof (struct WlanHeader), + GNUNET_YES, GNUNET_NO); + break; + default: + if (NULL == mas->endpoint) + { + GNUNET_break (0); + break; } - else + if (NULL == mas->session) { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME, - "WLAN client not in session list and hello message is not okay\n"); - return; + GNUNET_break (0); + break; } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received packet with %u bytes of type %u from peer %s\n", + (unsigned int) msize, + (unsigned int) ntohs (hdr->type), + GNUNET_i2s (&mas->session->target)); + plugin->env->receive (plugin->env->cls, + &mas->session->target, + hdr, + ats, NUM_ATS, + mas->session, + (mas->endpoint == NULL) ? NULL : (const char *) &mas->endpoint->addr, + (mas->endpoint == NULL) ? 0 : sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); + break; } + return GNUNET_OK; +} +#undef NUM_ATS - //FRAGMENT - else if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_FRAGMENT) - { +/** + * Function used for to process the data from the suid process + * + * @param cls the plugin handle + * @param client client that send the data (not used) + * @param hdr header of the GNUNET_MessageHeader + */ +static int +handle_helper_message (void *cls, void *client, + const struct GNUNET_MessageHeader *hdr) +{ + struct Plugin *plugin = cls; + const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rxinfo; + const struct GNUNET_TRANSPORT_WLAN_HelperControlMessage *cm; + struct MacAndSession mas; + uint16_t msize; - GNUNET_assert (session_light != NULL); - if (session_light->macendpoint == NULL) + msize = ntohs (hdr->size); + switch (ntohs (hdr->type)) + { + case GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL: + if (msize != sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage)) { - session_light->macendpoint = - get_macendpoint (plugin, &session_light->addr, GNUNET_YES); + GNUNET_break (0); + break; } - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_FRAGMENT with size: %u; mac endpoint %p: %s\n", - ntohs (hdr->size), session_light->macendpoint, - wlan_plugin_address_to_string (NULL, - session_light->addr.mac, - 6)); - GNUNET_STATISTICS_update (plugin->env->stats, - _("# wlan fragments received"), 1, GNUNET_NO); - int ret = - GNUNET_DEFRAGMENT_process_fragment (session_light->macendpoint->defrag, - hdr); - - if (ret == GNUNET_NO) + cm = (const struct GNUNET_TRANSPORT_WLAN_HelperControlMessage *) hdr; + if (GNUNET_YES == plugin->have_mac) { - session_light->macendpoint->dups++; + if (0 == memcmp (&plugin->mac_address, + &cm->mac, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) + break; /* no change */ + /* remove old address */ + plugin->env->notify_address (plugin->env->cls, GNUNET_NO, + &plugin->mac_address, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); } - else if (ret == GNUNET_OK) + plugin->mac_address = cm->mac; + plugin->have_mac = GNUNET_YES; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received WLAN_HELPER_CONTROL message with MAC address `%s' for peer `%s'\n", + mac_to_string (&cm->mac), + GNUNET_i2s (plugin->env->my_identity)); + plugin->env->notify_address (plugin->env->cls, GNUNET_YES, + &plugin->mac_address, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); + break; + case GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER: + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Got data message from helper with %u bytes\n", + msize); + GNUNET_STATISTICS_update (plugin->env->stats, + _("# DATA messages received via WLAN"), 1, + GNUNET_NO); + if (msize < sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)) { - session_light->macendpoint->fragc++; + GNUNET_break (0); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Size of packet is too small (%u bytes)\n", + msize); + break; } - set_next_send (plugin); - - } - - //ACK + rxinfo = (const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) hdr; - else if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_FRAGMENT_ACK) - { - GNUNET_assert (session_light != NULL); - if (session_light->macendpoint == NULL) + /* check if message is actually for us */ + if (0 != memcmp (&rxinfo->frame.addr3, &mac_bssid_gnunet, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) { - session_light->macendpoint = - get_macendpoint (plugin, &session_light->addr, GNUNET_NO); + /* Not the GNUnet BSSID */ + break; } - - if (session_light->macendpoint == NULL) + if ( (0 != memcmp (&rxinfo->frame.addr1, &bc_all_mac, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) && + (0 != memcmp (&rxinfo->frame.addr1, &plugin->mac_address, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) ) { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Macendpoint does not exist for this GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; %s\n", - ntohs (hdr->size), wlan_plugin_address_to_string (NULL, - session_light->addr.mac, - 6)); - return; + /* Neither broadcast nor specifically for us */ + break; } - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; mac endpoint: %p; %s\n", - ntohs (hdr->size), session_light->macendpoint, - wlan_plugin_address_to_string (NULL, - session_light->addr.mac, - 6)); - fm = session_light->macendpoint->sending_messages_head; - while (fm != NULL) + if (0 == memcmp (&rxinfo->frame.addr2, &plugin->mac_address, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))) { - fm2 = fm->next; - GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks received"), - 1, GNUNET_NO); - int ret = GNUNET_FRAGMENT_process_ack (fm->fragcontext, hdr); - - if (ret == GNUNET_OK) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Got last ack, finished fragment message %p\n", fm); - session_light->macendpoint->acks++; - fm->session->last_activity = GNUNET_TIME_absolute_get (); - session_light->macendpoint->last_activity = fm->session->last_activity; - free_fragment_message (plugin, fm); - check_fragment_queue (plugin); - return; - } - if (ret == GNUNET_NO) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Got ack for: %p\n", fm); - session_light->macendpoint->acks++; - return; - } - if (ret == GNUNET_SYSERR) - { - - } - - fm = fm2; + /* packet is FROM us, thus not FOR us */ + break; } - - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "WLAN fragment not in fragment list\n"); - return; - - } - else - { - // TODO Wrong data? - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME, - "WLAN packet inside the WLAN helper packet has not the right type: %u size: %u\n", - ntohs (hdr->type), ntohs (hdr->size)); + + GNUNET_STATISTICS_update (plugin->env->stats, + _("# WLAN DATA messages processed"), + 1, GNUNET_NO); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Receiving %u bytes of data from MAC `%s'\n", + (unsigned int) (msize - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)), + mac_to_string (&rxinfo->frame.addr2)); + mas.endpoint = create_macendpoint (plugin, &rxinfo->frame.addr2); + mas.session = NULL; + (void) GNUNET_SERVER_mst_receive (plugin->helper_payload_tokenizer, + &mas, + (const char*) &rxinfo[1], + msize - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage), + GNUNET_YES, GNUNET_NO); + break; + default: GNUNET_break (0); - return; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Unexpected message of type %u (%u bytes)", + ntohs (hdr->type), ntohs (hdr->size)); + break; } + return GNUNET_OK; +} -#if 0 - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Helper finished\n"); -#endif -} /** - * Function to print mac addresses nice * - * @param pointer to 6 byte with the mac address - * @return pointer to the chars which hold the print out + * Task to (periodically) send a HELLO beacon + * + * @param cls pointer to the plugin struct + * @param tc scheduler context */ -static const char * -macprinter (const u_int8_t * mac) +static void +send_hello_beacon (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - static char macstr[20]; + struct Plugin *plugin = cls; + uint16_t size; + uint16_t hello_size; + struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radioHeader; + const struct GNUNET_MessageHeader *hello; + + hello = plugin->env->get_our_hello (); + hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello); + GNUNET_assert (sizeof (struct WlanHeader) + hello_size <= WLAN_MTU); + size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + hello_size; + { + char buf[size] GNUNET_ALIGN; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Sending %u byte HELLO beacon\n", + (unsigned int) size); + radioHeader = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage*) buf; + get_radiotap_header (NULL, radioHeader, size); + get_wlan_header (plugin, &radioHeader->frame, &bc_all_mac, size); + memcpy (&radioHeader[1], hello, hello_size); + if (NULL != + GNUNET_HELPER_send (plugin->suid_helper, + &radioHeader->header, + GNUNET_YES /* can drop */, + NULL, NULL)) + GNUNET_STATISTICS_update (plugin->env->stats, _("# HELLO beacons sent via WLAN"), + 1, GNUNET_NO); + } + plugin->beacon_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply + (HELLO_BEACON_SCALING_FACTOR, + plugin->mac_count + 1), + &send_hello_beacon, + plugin); - GNUNET_snprintf (macstr, sizeof (macstr), "%X:%X:%X:%X:%X:%X", mac[0], mac[1], - mac[2], mac[3], mac[4], mac[5]); - return macstr; } + /** - * Function for the scheduler if a mac endpoint times out - * @param cls pointer to the MacEndpoint - * @param tc pointer to the GNUNET_SCHEDULER_TaskContext + * Another peer has suggested an address for this + * peer and transport plugin. Check that this could be a valid + * address. If so, consider adding it to the list + * of addresses. + * + * @param cls closure + * @param addr pointer to the address + * @param addrlen length of addr + * @return GNUNET_OK if this is a plausible address for this peer + * and transport */ -static void -macendpoint_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +static int +wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) { - struct MacEndpoint *endpoint = cls; + struct Plugin *plugin = cls; - GNUNET_assert (endpoint != NULL); - endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK; - if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) - { - return; + if (addrlen != sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; } - if (GNUNET_TIME_absolute_get_remaining - (GNUNET_TIME_absolute_add - (endpoint->last_activity, MACENDPOINT_TIMEOUT)).rel_value == 0) + if (GNUNET_YES != plugin->have_mac) { - GNUNET_assert (endpoint->plugin != NULL); - GNUNET_STATISTICS_update (endpoint->plugin->env->stats, - _("# wlan mac endpoints timeouts"), 1, GNUNET_NO); - free_macendpoint (endpoint->plugin, endpoint); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Rejecting MAC `%s': I don't know my MAC!\n", + mac_to_string (addr)); + return GNUNET_NO; /* don't know my MAC */ } - else + if (0 != memcmp (addr, + &plugin->mac_address, + addrlen)) { - endpoint->timeout_task = - GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout, - endpoint); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Rejecting MAC `%s': not my MAC!\n", + mac_to_string (addr)); + return GNUNET_NO; /* not my MAC */ } + return GNUNET_OK; } + /** - * function to create an macendpoint - * @param plugin pointer to the plugin struct - * @param addr pointer to the macaddress - * @return returns a macendpoint + * Function called for a quick conversion of the binary address to + * a numeric address. Note that the caller must not free the + * address and that the next call to this function is allowed + * to override the address again. + * + * @param cls closure + * @param addr binary address + * @param addrlen length of the address + * @return string representing the same address */ -static struct MacEndpoint * -create_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr) +static const char * +wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) { - struct MacEndpoint *newend = GNUNET_malloc (sizeof (struct MacEndpoint)); - - GNUNET_assert (plugin != NULL); - GNUNET_STATISTICS_update (plugin->env->stats, - _("# wlan mac endpoints created"), 1, GNUNET_NO); - newend->addr = *addr; - newend->plugin = plugin; - newend->addr = *addr; - newend->fragment_messages_out_count = 0; - newend->defrag = - GNUNET_DEFRAGMENT_context_create (plugin->env->stats, WLAN_MTU, - MESSAGES_IN_DEFRAG_QUEUE_PER_MAC, - newend, &wlan_data_message_handler, - &add_ack_for_send); - newend->last_activity = GNUNET_TIME_absolute_get (); - newend->timeout_task = - GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout, - newend); + const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac; - plugin->mac_count++; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"), - plugin->mac_count, GNUNET_NO); - GNUNET_CONTAINER_DLL_insert_tail (plugin->mac_head, plugin->mac_tail, newend); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "New Mac Endpoint %p: %s\n", newend, - wlan_plugin_address_to_string (NULL, newend->addr.mac, 6)); - return newend; + if (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress) != addrlen) + { + GNUNET_break (0); + return NULL; + } + mac = addr; + return GNUNET_strdup (mac_to_string (mac)); } + /** - * Function used for to process the data from the suid process + * Convert the transports address to a nice, human-readable format. * - * @param cls the plugin handle - * @param client client that send the data (not used) - * @param hdr header of the GNUNET_MessageHeader + * @param cls closure + * @param type name of the transport that generated the address + * @param addr one of the addresses of the host, NULL for the last address + * the specific address format depends on the transport + * @param addrlen length of the address + * @param numeric should (IP) addresses be displayed in numeric form? + * @param timeout after how long should we give up? + * @param asc function to call on each string + * @param asc_cls closure for asc */ static void -wlan_process_helper (void *cls, void *client, - const struct GNUNET_MessageHeader *hdr) +wlan_plugin_address_pretty_printer (void *cls, const char *type, + const void *addr, size_t addrlen, + int numeric, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_AddressStringCallback asc, + void *asc_cls) { - struct Plugin *plugin = cls; - struct ieee80211_frame *wlanIeeeHeader = NULL; - struct Session_light *session_light = NULL; - struct Radiotap_rx *rxinfo; - const struct GNUNET_MessageHeader *temp_hdr = NULL; - - int datasize = 0; - int pos; + const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac; + char *ret; - GNUNET_assert (plugin != NULL); - switch (ntohs (hdr->type)) + if (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress) != addrlen) { - case GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA: - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA size: %u\n", - ntohs (hdr->size)); - GNUNET_STATISTICS_update (plugin->env->stats, - _("# wlan WLAN_HELPER_DATA received"), 1, - GNUNET_NO); - //call wlan_process_helper with the message inside, later with wlan: analyze signal - if (ntohs (hdr->size) < - sizeof (struct ieee80211_frame) + - 2 * sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_rx)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Size of packet is too small; size: %u min size: %u\n", - ntohs (hdr->size), - sizeof (struct ieee80211_frame) + - sizeof (struct GNUNET_MessageHeader)); - //GNUNET_break (0); - /* FIXME: restart SUID process */ - return; - } - - rxinfo = (struct Radiotap_rx *) &hdr[1]; - wlanIeeeHeader = (struct ieee80211_frame *) &rxinfo[1]; - - //process only if it is an broadcast or for this computer both with the gnunet bssid - - //check for bssid - if (memcmp - (&(wlanIeeeHeader->i_addr3), &mac_bssid_gnunet, - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) - { - //check for broadcast or mac - if ((memcmp - (&(wlanIeeeHeader->i_addr1), &bc_all_mac, - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) || - (memcmp - (&(wlanIeeeHeader->i_addr1), &(plugin->mac_address), - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)) - { - //if packet is from us return - if ((memcmp - (&(wlanIeeeHeader->i_addr2), &(plugin->mac_address), - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)) - { - return; - } - // process the inner data - - - datasize = - ntohs (hdr->size) - sizeof (struct ieee80211_frame) - - sizeof (struct GNUNET_MessageHeader) - sizeof (struct Radiotap_rx); - - session_light = GNUNET_malloc (sizeof (struct Session_light)); - memcpy (&session_light->addr, &(wlanIeeeHeader->i_addr2), - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); - //session_light->session = search_session(plugin,session_light->addr); - GNUNET_STATISTICS_update (plugin->env->stats, - _("# wlan messages for this client received"), - 1, GNUNET_NO); - - pos = 0; - while (pos < datasize) - { - temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1] + pos; - if (ntohs (temp_hdr->size) <= datasize + pos) - { - GNUNET_STATISTICS_update (plugin->env->stats, - _ - ("# wlan messages inside WLAN_HELPER_DATA received"), - 1, GNUNET_NO); - wlan_data_helper (plugin, session_light, temp_hdr, rxinfo); - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Size of packet is too small; size: %u > size of packet: %u\n", - ntohs (temp_hdr->size), datasize + pos); - } - pos += ntohs (temp_hdr->size); - - } - - //clean up - GNUNET_free (session_light); - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_process_helper got wrong MAC: %s\n", - macprinter (wlanIeeeHeader->i_addr1)); - } - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_process_helper got wrong BSSID: %s\n", - macprinter (wlanIeeeHeader->i_addr2)); - } - break; - case GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL: - //TODO more control messages - if (ntohs (hdr->size) != sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage)) - { - GNUNET_break (0); - /* FIXME: restart SUID process */ - return; - } - memcpy (&plugin->mac_address, &hdr[1], sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Received WLAN_HELPER_CONTROL message with transport of address %s\n", - wlan_plugin_address_to_string (cls, &plugin->mac_address, - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))); - plugin->env->notify_address (plugin->env->cls, GNUNET_YES, - &plugin->mac_address, - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); - break; - default: - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "Func wlan_process_helper got unknown message with number %u, size %u\n", - ntohs (hdr->type), ntohs (hdr->size)); - -#if DEBUG_WLAN > 1 - hexdump (hdr, GNUNET_MIN (ntohs (hdr->size), 256)); -#endif - GNUNET_break (0); + /* invalid address */ + LOG (GNUNET_ERROR_TYPE_WARNING, + _("WLAN address with invalid size encountered\n")); + asc (asc_cls, NULL); return; } + mac = addr; + ret = GNUNET_strdup (mac_to_string (mac)); + asc (asc_cls, ret); + GNUNET_free (ret); + asc (asc_cls, NULL); } + /** - * Exit point from the plugin. + * Exit point from the plugin. + * * @param cls pointer to the api struct */ - -//FIXME cleanup void * libgnunet_plugin_transport_wlan_done (void *cls) { struct GNUNET_TRANSPORT_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; - struct MacEndpoint *endpoint = plugin->mac_head; + struct MacEndpoint *endpoint; struct MacEndpoint *endpoint_next; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "libgnunet_plugin_transport_wlan_done started\n"); - wlan_transport_stop_wlan_helper (plugin); - - GNUNET_assert (cls != NULL); - //free sessions - while (endpoint != NULL) + if (NULL == plugin) + { + GNUNET_free (api); + return NULL; + } + if (GNUNET_SCHEDULER_NO_TASK != plugin->beacon_task) + { + GNUNET_SCHEDULER_cancel (plugin->beacon_task); + plugin->beacon_task = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != plugin->suid_helper) + { + GNUNET_HELPER_stop (plugin->suid_helper); + plugin->suid_helper = NULL; + } + endpoint_next = plugin->mac_head; + while (NULL != (endpoint = endpoint_next)) { endpoint_next = endpoint->next; - free_macendpoint (plugin, endpoint); - endpoint = endpoint_next; - + free_macendpoint (endpoint); + } + if (NULL != plugin->fragment_data_tokenizer) + { + GNUNET_SERVER_mst_destroy (plugin->fragment_data_tokenizer); + plugin->fragment_data_tokenizer = NULL; + } + if (NULL != plugin->wlan_header_payload_tokenizer) + { + GNUNET_SERVER_mst_destroy (plugin->wlan_header_payload_tokenizer); + plugin->wlan_header_payload_tokenizer = NULL; + } + if (NULL != plugin->helper_payload_tokenizer) + { + GNUNET_SERVER_mst_destroy (plugin->helper_payload_tokenizer); + plugin->helper_payload_tokenizer = NULL; } - - - if (plugin->suid_tokenizer != NULL) - GNUNET_SERVER_mst_destroy (plugin->suid_tokenizer); - - if (plugin->data_tokenizer != NULL) - GNUNET_SERVER_mst_destroy (plugin->data_tokenizer); - GNUNET_free_non_null (plugin->interface); GNUNET_free (plugin); GNUNET_free (api); return NULL; } + +/** + * Function called to convert a string address to + * a binary address. + * + * @param cls closure ('struct Plugin*') + * @param addr string address + * @param addrlen length of the address + * @param buf location to store the buffer + * @param added location to store the number of bytes in the buffer. + * If the function returns GNUNET_SYSERR, its contents are undefined. + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +static int +wlan_string_to_address (void *cls, const char *addr, uint16_t addrlen, + void **buf, size_t *added) +{ + struct GNUNET_TRANSPORT_WLAN_MacAddress *mac; + unsigned int a[6]; + unsigned int i; + + if ((NULL == addr) || (addrlen == 0)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if ('\0' != addr[addrlen - 1]) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (strlen (addr) != addrlen - 1) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (6 != SSCANF (addr, + "%X:%X:%X:%X:%X:%X", + &a[0], &a[1], &a[2], &a[3], &a[4], &a[5])) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + mac = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); + for (i=0;i<6;i++) + mac->mac[i] = a[i]; + *buf = mac; + *added = sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress); + return GNUNET_OK; +} + + /** * Entry point for the plugin. * @@ -3129,35 +1636,107 @@ libgnunet_plugin_transport_wlan_done (void *cls) void * libgnunet_plugin_transport_wlan_init (void *cls) { - //struct GNUNET_SERVICE_Context *service; struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; struct GNUNET_TRANSPORT_PluginFunctions *api; struct Plugin *plugin; - - GNUNET_assert (cls != NULL); + char *interface; + unsigned long long testmode; + + /* check for 'special' mode */ + if (NULL == env->receive) + { + /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully + initialze the plugin or the API */ + api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); + api->cls = NULL; + api->address_pretty_printer = &wlan_plugin_address_pretty_printer; + api->address_to_string = &wlan_plugin_address_to_string; + api->string_to_address = &wlan_string_to_address; + return api; + } + + testmode = 0; + /* check configuration */ + if ( (GNUNET_YES == + GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "TESTMODE")) && + ( (GNUNET_SYSERR == + GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan", + "TESTMODE", &testmode)) || + (testmode > 2) ) ) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Invalid configuration option `%s' in section `%s'\n"), + "TESTMODE", + "transport-wlan"); + return NULL; + } + if ( (0 == testmode) && + (GNUNET_YES != GNUNET_OS_check_helper_binary ("gnunet-helper-transport-wlan")) ) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Helper binary `%s' not SUID, cannot run WLAN transport\n"), + "gnunet-helper-transport-wlan"); + return NULL; + } + if (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_string + (env->cfg, "transport-wlan", "INTERFACE", + &interface)) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Missing configuration option `%s' in section `%s'\n"), + "INTERFACE", + "transport-wlan"); + return NULL; + } plugin = GNUNET_malloc (sizeof (struct Plugin)); + plugin->interface = interface; plugin->env = env; - plugin->pendingsessions = 0; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"), - plugin->pendingsessions, GNUNET_NO); - plugin->mac_count = 0; - GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"), - plugin->mac_count, GNUNET_NO); - plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; - plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; - plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_STATISTICS_set (plugin->env->stats, _("# WLAN sessions allocated"), + 0, GNUNET_NO); + GNUNET_STATISTICS_set (plugin->env->stats, _("# WLAN MAC endpoints allocated"), + 0, 0); GNUNET_BANDWIDTH_tracker_init (&plugin->tracker, GNUNET_BANDWIDTH_value_init (100 * 1024 * 1024 / 8), 100); - - plugin->suid_tokenizer = - GNUNET_SERVER_mst_create (&wlan_process_helper, plugin); - - plugin->data_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); - - //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); - //plugin->pending_Sessions_head = GNUNET_malloc (sizeof (struct Sessionqueue)); + plugin->fragment_data_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); + plugin->wlan_header_payload_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); + plugin->helper_payload_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin); + plugin->beacon_task = GNUNET_SCHEDULER_add_now (&send_hello_beacon, + plugin); + switch (testmode) + { + case 0: /* normal */ + plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan"; + plugin->helper_argv[1] = interface; + plugin->helper_argv[2] = NULL; + plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan", + plugin->helper_argv, + &handle_helper_message, + plugin); + break; + case 1: /* testmode, peer 1 */ + plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan-dummy"; + plugin->helper_argv[1] = (char *) "1"; + plugin->helper_argv[2] = NULL; + plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan-dummy", + plugin->helper_argv, + &handle_helper_message, + plugin); + break; + case 2: /* testmode, peer 2 */ + plugin->helper_argv[0] = (char *) "gnunet-helper-transport-wlan-dummy"; + plugin->helper_argv[1] = (char *) "2"; + plugin->helper_argv[2] = NULL; + plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan-dummy", + plugin->helper_argv, + &handle_helper_message, + plugin); + break; + default: + GNUNET_assert (0); + } api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); api->cls = plugin; @@ -3167,35 +1746,9 @@ libgnunet_plugin_transport_wlan_init (void *cls) api->address_pretty_printer = &wlan_plugin_address_pretty_printer; api->check_address = &wlan_plugin_address_suggested; api->address_to_string = &wlan_plugin_address_to_string; - - //read config - - if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "TESTMODE")) - { - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan", - "TESTMODE", &(plugin->testmode))) - plugin->testmode = 0; //default value - } - - if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "INTERFACE")) - { - if (GNUNET_CONFIGURATION_get_value_string - (env->cfg, "transport-wlan", "INTERFACE", - &(plugin->interface)) != GNUNET_YES) - { - libgnunet_plugin_transport_wlan_done (api); - return NULL; - } - } - - //start the plugin - wlan_transport_start_wlan_helper (plugin); - set_next_beacon_time (plugin); - set_next_send (plugin); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, - "wlan init finished\n"); + api->string_to_address = &wlan_string_to_address; return api; } + /* end of plugin_transport_wlan.c */ diff --git a/src/transport/plugin_transport_wlan.h b/src/transport/plugin_transport_wlan.h index 9e1bc4f..2b70fc0 100644 --- a/src/transport/plugin_transport_wlan.h +++ b/src/transport/plugin_transport_wlan.h @@ -34,7 +34,27 @@ */ #define MAC_ADDR_SIZE 6 +/** + * Value for "Management" in the 'frame_control' field of the + * struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame. + */ +#define IEEE80211_FC0_TYPE_MGT 0x00 + +/** + * Value for "Control" in the 'frame_control' field of the + * struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame. + */ +#define IEEE80211_FC0_TYPE_CTL 0x04 + +/** + * Value for DATA in the 'frame_control' field of the + * struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame. + */ +#define IEEE80211_FC0_TYPE_DATA 0x08 + + GNUNET_NETWORK_STRUCT_BEGIN + /** * A MAC Address. */ @@ -59,26 +79,73 @@ struct GNUNET_TRANSPORT_WLAN_HelperControlMessage */ struct GNUNET_TRANSPORT_WLAN_MacAddress mac; }; -GNUNET_NETWORK_STRUCT_END + /** - * GNUnet bssid + * generic definitions for IEEE 802.11 frames */ -static const struct GNUNET_TRANSPORT_WLAN_MacAddress mac_bssid_gnunet = { - {0x13, 0x22, 0x33, 0x44, 0x55, 0x66} -}; +struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame +{ + /** + * 802.11 Frame Control field. A bitmask. The overall field is a + * 16-bit mask of the respecitve fields. The lowest two bits should + * be 0, then comes the "type" (2 bits, see IEEE80211_FC0_TYPE_* + * constants), followed by 4-bit subtype (all zeros for ad-hoc), + * followed by various flags (to DS, from DS, more frag, retry, + * power management, more data, WEP, strict), all of which we also + * keep at zero. + */ + uint16_t frame_control GNUNET_PACKED; + + /** + * Microseconds to reserve link (duration), 0 by default + */ + uint16_t duration GNUNET_PACKED; + + /** + * Address 1: destination address in ad-hoc mode or AP, BSSID if station, + */ + struct GNUNET_TRANSPORT_WLAN_MacAddress addr1; + + /** + * Address 2: source address if in ad-hoc-mode or station, BSSID if AP + */ + struct GNUNET_TRANSPORT_WLAN_MacAddress addr2; + + /** + * Address 3: BSSID in ad-hoc mode, Destination if station, source if AP + */ + struct GNUNET_TRANSPORT_WLAN_MacAddress addr3; + + /** + * 802.11 sequence control field; contains fragment number an sequence + * number (we set this to all zeros). + */ + uint16_t sequence_control GNUNET_PACKED; + + /** + * Link layer control (LLC). Set to a GNUnet-specific value. + */ + u_int8_t llc[4]; + + /* payload */ + +} GNUNET_PACKED; + /** - * Broadcast MAC + * Message from the plugin to the WLAN helper: send the given message with the + * given connection parameters. */ -static const struct GNUNET_TRANSPORT_WLAN_MacAddress bc_all_mac = { - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} -}; +struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage +{ + /** + * Type is 'GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER'. + */ + struct GNUNET_MessageHeader header; -struct Radiotap_Send -{ /** * wlan send rate */ @@ -93,60 +160,100 @@ struct Radiotap_Send * Transmit power expressed as unitless distance from max power set at factory calibration. * 0 is max power. Monotonically nondecreasing with lower power levels. */ - uint16_t tx_power; + uint16_t tx_power GNUNET_PACKED; + + /** + * IEEE Frame to transmit (the sender MAC address will be overwritten by the helper as it does not + * trust the plugin to set it correctly). + */ + struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame; + + /* actual payload follows */ }; +/** + * Message from the WLAN helper to the plugin: we have received the given message with the + * given performance characteristics. + */ /** * struct to represent infos gathered form the radiotap fields, see RadiotapHeader for more Infos */ -struct Radiotap_rx +struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage { + + /** + * Type is 'GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER'. + */ + struct GNUNET_MessageHeader header; + /** - * FIXME: not initialized properly so far. (supposed to contain - * information about which of the fields below are actually valid). + * Information about which of the fields below are actually valid. + * 0 for none. FIXME: not properly initialized so far (always zero). */ - uint32_t ri_present; + uint32_t ri_present GNUNET_PACKED; /** - * IEEE80211_RADIOTAP_TSFT + * IEEE80211_RADIOTAP_TSFT, 0 if unknown. */ - uint64_t ri_mactime; + uint64_t ri_mactime GNUNET_PACKED; /** * from radiotap * either IEEE80211_RADIOTAP_DBM_ANTSIGNAL - * or IEEE80211_RADIOTAP_DB_ANTSIGNAL + * or IEEE80211_RADIOTAP_DB_ANTSIGNAL, 0 if unknown. */ - int32_t ri_power; + int32_t ri_power GNUNET_PACKED; /** * either IEEE80211_RADIOTAP_DBM_ANTNOISE - * or IEEE80211_RADIOTAP_DB_ANTNOISE + * or IEEE80211_RADIOTAP_DB_ANTNOISE, 0 if unknown. */ - int32_t ri_noise; + int32_t ri_noise GNUNET_PACKED; /** - * IEEE80211_RADIOTAP_CHANNEL + * IEEE80211_RADIOTAP_CHANNEL, 0 if unknown. */ - uint32_t ri_channel; + uint32_t ri_channel GNUNET_PACKED; /** - * Frequency we use. FIXME: not properly initialized so far! + * Frequency we use. 0 if unknown. */ - uint32_t ri_freq; + uint32_t ri_freq GNUNET_PACKED; /** - * IEEE80211_RADIOTAP_RATE * 50000 + * IEEE80211_RADIOTAP_RATE * 50000, 0 if unknown. */ - uint32_t ri_rate; + uint32_t ri_rate GNUNET_PACKED; /** - * IEEE80211_RADIOTAP_ANTENNA + * IEEE80211_RADIOTAP_ANTENNA, 0 if unknown. */ - uint32_t ri_antenna; + uint32_t ri_antenna GNUNET_PACKED; + + /** + * IEEE Frame. + */ + struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame; + + /* followed by payload */ }; +GNUNET_NETWORK_STRUCT_END +/** + * GNUnet bssid + */ +static const struct GNUNET_TRANSPORT_WLAN_MacAddress mac_bssid_gnunet = { + {0x13, 0x22, 0x33, 0x44, 0x55, 0x66} +}; + + +/** + * Broadcast MAC + */ +static const struct GNUNET_TRANSPORT_WLAN_MacAddress bc_all_mac = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; #endif diff --git a/src/transport/template_cfg_peer1.conf b/src/transport/template_cfg_peer1.conf index ba05e93..2b8e9b2 100644 --- a/src/transport/template_cfg_peer1.conf +++ b/src/transport/template_cfg_peer1.conf @@ -17,6 +17,9 @@ TIMEOUT = 5 s [transport-udp] BROADCAST = NO +[transport-unix] +PORT = 12007 + [arm] PORT = 12005 DEFAULTSERVICES = transport diff --git a/src/transport/template_cfg_peer2.conf b/src/transport/template_cfg_peer2.conf index 0a0e74a..3b86137 100644 --- a/src/transport/template_cfg_peer2.conf +++ b/src/transport/template_cfg_peer2.conf @@ -17,6 +17,9 @@ TIMEOUT = 5 s [transport-udp] BROADCAST = NO +[transport-unix] +PORT = 12017 + [arm] PORT = 12014 DEFAULTSERVICES = transport diff --git a/src/transport/test_quota_compliance_tcp_asymmetric_peer1.conf b/src/transport/test_quota_compliance_tcp_asymmetric_peer1.conf index a7bac62..8a1dad5 100644 --- a/src/transport/test_quota_compliance_tcp_asymmetric_peer1.conf +++ b/src/transport/test_quota_compliance_tcp_asymmetric_peer1.conf @@ -27,6 +27,7 @@ UNIXPATH = /tmp/test_quota_compliance_tcp_peerinfo_peer1.sock [transport] PORT = 4091 +PLUGINS = tcp UNIXPATH = /tmp/test_quota_compliance_tcp_transport_peer1.sock diff --git a/src/transport/test_quota_compliance_tcp_asymmetric_peer2.conf b/src/transport/test_quota_compliance_tcp_asymmetric_peer2.conf index 75a4fe9..bbfa8ec 100644 --- a/src/transport/test_quota_compliance_tcp_asymmetric_peer2.conf +++ b/src/transport/test_quota_compliance_tcp_asymmetric_peer2.conf @@ -26,5 +26,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock diff --git a/src/transport/test_quota_compliance_tcp_peer1.conf b/src/transport/test_quota_compliance_tcp_peer1.conf index ff63514..29e56fe 100644 --- a/src/transport/test_quota_compliance_tcp_peer1.conf +++ b/src/transport/test_quota_compliance_tcp_peer1.conf @@ -27,6 +27,7 @@ UNIXPATH = /tmp/test_quota_compliance_tcp_peerinfo_peer1.sock [transport] PORT = 4091 +PLUGINS = tcp UNIXPATH = /tmp/test_quota_compliance_tcp_transport_peer1.sock diff --git a/src/transport/test_quota_compliance_tcp_peer2.conf b/src/transport/test_quota_compliance_tcp_peer2.conf index 18b199c..5da60d0 100644 --- a/src/transport/test_quota_compliance_tcp_peer2.conf +++ b/src/transport/test_quota_compliance_tcp_peer2.conf @@ -26,5 +26,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c index 5fb81e1..f944fac 100644 --- a/src/transport/test_transport_api.c +++ b/src/transport/test_transport_api.c @@ -37,8 +37,6 @@ #include "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO -#define VERBOSE_ARM GNUNET_NO #define START_ARM GNUNET_YES @@ -52,9 +50,9 @@ */ #define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) -#define MSIZE 2600 +#define TEST_MESSAGE_SIZE 2600 -#define MTYPE 12345 +#define TEST_MESSAGE_TYPE 12345 static char *test_source; @@ -65,32 +63,29 @@ static char *test_name; static int ok; static int s_started; + static int s_connected; + static int s_sending; static GNUNET_SCHEDULER_TaskIdentifier die_task; static GNUNET_SCHEDULER_TaskIdentifier send_task; -struct PeerContext *p1; +static struct PeerContext *p1; -struct PeerContext *p2; +static struct PeerContext *p2; static GNUNET_TRANSPORT_TESTING_ConnectRequest cc; -struct GNUNET_TRANSPORT_TransmitHandle *th; +static struct GNUNET_TRANSPORT_TransmitHandle *th; -struct GNUNET_TRANSPORT_TESTING_handle *tth; +static struct GNUNET_TRANSPORT_TESTING_handle *tth; -char *cfg_file_p1; +static char *cfg_file_p1; -char *cfg_file_p2; +static char *cfg_file_p2; -#if VERBOSE -#define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) -#else -#define OKPP do { ok++; } while (0) -#endif static void end () @@ -135,9 +130,9 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not ready to send data\n")); if (s_started == GNUNET_NO) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peers were not started n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peers were not started \n")); else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peers were started n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peers were started \n")); if (s_connected == GNUNET_NO) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not connected\n")); @@ -186,8 +181,8 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_i2s (&t->id)); GNUNET_free (ps); - if ((MTYPE == ntohs (message->type)) && - (MSIZE == ntohs (message->size))) + if ((TEST_MESSAGE_TYPE == ntohs (message->type)) && + (TEST_MESSAGE_SIZE == ntohs (message->size))) { ok = 0; end (); @@ -220,13 +215,13 @@ notify_ready (void *cls, size_t size, void *buf) return 0; } - GNUNET_assert (size >= MSIZE); - + GNUNET_assert (size >= TEST_MESSAGE_SIZE); if (buf != NULL) { + memset (buf, '\0', TEST_MESSAGE_SIZE); hdr = buf; - hdr->size = htons (MSIZE); - hdr->type = htons (MTYPE); + hdr->size = htons (TEST_MESSAGE_SIZE); + hdr->type = htons (TEST_MESSAGE_TYPE); } char *ps = GNUNET_strdup (GNUNET_i2s (&p2->id)); @@ -236,7 +231,7 @@ notify_ready (void *cls, size_t size, void *buf) GNUNET_i2s (&p->id)); GNUNET_free (ps); - return MSIZE; + return TEST_MESSAGE_SIZE; } @@ -254,7 +249,7 @@ sendtask (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) p2->no, GNUNET_i2s (&p2->id), p1->no, receiver_s); GNUNET_free (receiver_s); s_sending = GNUNET_YES; - th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, MSIZE, 0, + th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, TEST_MESSAGE_SIZE, 0, TIMEOUT_TRANSMIT, ¬ify_ready, p1); } @@ -302,6 +297,7 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) th = NULL; } + static void testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) { @@ -317,8 +313,7 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) } - -void +static void start_cb (struct PeerContext *p, void *cls) { static int started; @@ -344,6 +339,7 @@ start_cb (struct PeerContext *p, void *cls) } + static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) @@ -381,9 +377,6 @@ check () static char *const argv[] = { "test-transport-api", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -413,13 +406,8 @@ main (int argc, char *argv[]) &test_plugin); GNUNET_log_setup (test_name, -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); - tth = GNUNET_TRANSPORT_TESTING_init (); GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p1, 1); diff --git a/src/transport/test_transport_api_bidirectional_connect.c b/src/transport/test_transport_api_bidirectional_connect.c index 604554c..2c4eeab 100644 --- a/src/transport/test_transport_api_bidirectional_connect.c +++ b/src/transport/test_transport_api_bidirectional_connect.c @@ -35,10 +35,6 @@ #include "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO -#define VERBOSE_ARM GNUNET_NO - -#define START_ARM GNUNET_YES /** * How long until we give up on transmitting the message? @@ -64,26 +60,20 @@ static GNUNET_SCHEDULER_TaskIdentifier die_task; static GNUNET_SCHEDULER_TaskIdentifier send_task; -struct PeerContext *p1; +static struct PeerContext *p1; -struct PeerContext *p2; +static struct PeerContext *p2; static GNUNET_TRANSPORT_TESTING_ConnectRequest cc1; static GNUNET_TRANSPORT_TESTING_ConnectRequest cc2; -struct GNUNET_TRANSPORT_TransmitHandle *th; - -struct GNUNET_TRANSPORT_TESTING_handle *tth; +static struct GNUNET_TRANSPORT_TransmitHandle *th; -char *cfg_file_p1; +static struct GNUNET_TRANSPORT_TESTING_handle *tth; -char *cfg_file_p2; +static char *cfg_file_p1; -#if VERBOSE -#define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) -#else -#define OKPP do { ok++; } while (0) -#endif +static char *cfg_file_p2; static void @@ -97,9 +87,11 @@ end () if (die_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (die_task); - if (th != NULL) + if (NULL != th) + { GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); - th = NULL; + th = NULL; + } GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); @@ -109,24 +101,27 @@ static void end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { die_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Fail! Stopping peers\n"); - - if (send_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (send_task); - if (cc2 != NULL) + if (NULL != cc2) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Fail! Could not connect peers\n")); GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc2); cc2 = NULL; } - - if (th != NULL) + if (NULL != cc1) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Fail! Could not connect peers\n")); + GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc1); + cc1 = NULL; + } + if (NULL != th) + { GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); - th = NULL; - + th = NULL; + } if (p1 != NULL) GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); if (p2 != NULL) @@ -270,6 +265,7 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) th = NULL; } + static void testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) { @@ -293,7 +289,8 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL); } -void + +static void start_cb (struct PeerContext *p, void *cls) { static int started; @@ -353,9 +350,6 @@ check () static char *const argv[] = { "test-transport-api", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -382,11 +376,7 @@ main (int argc, char *argv[]) GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name); GNUNET_log_setup (test_name, -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source); diff --git a/src/transport/test_transport_api_bidirectional_connect_peer1.conf b/src/transport/test_transport_api_bidirectional_connect_peer1.conf index 21591b5..49fc662 100644 --- a/src/transport/test_transport_api_bidirectional_connect_peer1.conf +++ b/src/transport/test_transport_api_bidirectional_connect_peer1.conf @@ -3,29 +3,44 @@ SERVICEHOME = /tmp/test-transport/api-tcp-p1/ DEFAULTCONFIG = test_transport_api_bidirectional_connect_peer1.conf -[transport-tcp] -PORT = 12000 -TIMEOUT = 5 s - [arm] -PORT = 12005 +PORT = 12000 DEFAULTSERVICES = transport UNIXPATH = /tmp/gnunet-p1-service-arm.sock [statistics] -PORT = 12004 +PORT = 12001 UNIXPATH = /tmp/gnunet-p1-service-statistics.sock [resolver] -PORT = 12003 +PORT = 12002 UNIXPATH = /tmp/gnunet-p1-service-resolver.sock [peerinfo] -PORT = 12002 +PORT = 12003 UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] -PORT = 12001 +PORT = 12004 UNIXPATH = /tmp/gnunet-p1-service-transport.sock #DEBUG = YES +[transport-tcp] +PORT = 12005 +TIMEOUT = 5 s + +[transport-udp] +PORT = 12006 +TIMEOUT = 5 s + +[transport-unix] +PORT = 12007 +TIMEOUT = 5 s + +[transport-http] +PORT = 12008 +TIMEOUT = 5 s + +[transport-https] +PORT = 12009 +TIMEOUT = 5 s \ No newline at end of file diff --git a/src/transport/test_transport_api_bidirectional_connect_peer2.conf b/src/transport/test_transport_api_bidirectional_connect_peer2.conf index db3ba8c..2d64351 100644 --- a/src/transport/test_transport_api_bidirectional_connect_peer2.conf +++ b/src/transport/test_transport_api_bidirectional_connect_peer2.conf @@ -3,17 +3,13 @@ SERVICEHOME = /tmp/test-transport/api-tcp-p2/ DEFAULTCONFIG = test_transport_api_bidirectional_connect_peer2.conf -[transport-tcp] -PORT = 12015 -TIMEOUT = 5 s - [arm] -PORT = 12014 +PORT = 12010 DEFAULTSERVICES = transport UNIXPATH = /tmp/gnunet-p2-service-arm.sock [statistics] -PORT = 12013 +PORT = 12011 UNIXPATH = /tmp/gnunet-p2-service-statistics.sock [resolver] @@ -21,10 +17,29 @@ PORT = 12012 UNIXPATH = /tmp/gnunet-p2-service-resolver.sock [peerinfo] -PORT = 12011 +PORT = 12013 UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] -PORT = 12010 +PORT = 12014 UNIXPATH = /tmp/gnunet-p2-service-transport.sock +[transport-tcp] +PORT = 12015 +TIMEOUT = 5 s + +[transport-udp] +PORT = 12016 +TIMEOUT = 5 s + +[transport-unix] +PORT = 12017 +TIMEOUT = 5 s + +[transport-http] +PORT = 12018 +TIMEOUT = 5 s + +[transport-https] +PORT = 12019 +TIMEOUT = 5 s \ No newline at end of file diff --git a/src/transport/test_transport_api_blacklisting.c b/src/transport/test_transport_api_blacklisting.c index f8f6040..909ea57 100644 --- a/src/transport/test_transport_api_blacklisting.c +++ b/src/transport/test_transport_api_blacklisting.c @@ -61,9 +61,9 @@ struct GNUNET_TRANSPORT_TESTING_handle *tth; */ #define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) -#define MSIZE 2600 +#define TEST_MESSAGE_SIZE 2600 -#define MTYPE 12345 +#define TEST_MESSAGE_TYPE 12345 static int ok; @@ -212,8 +212,8 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_i2s (&t->id)); GNUNET_free (ps); - if ((MTYPE == ntohs (message->type)) && - (MSIZE == ntohs (message->size))) + if ((TEST_MESSAGE_TYPE == ntohs (message->type)) && + (TEST_MESSAGE_SIZE == ntohs (message->size))) { ok = 0; shutdown_task = GNUNET_SCHEDULER_add_now(&end, NULL); @@ -249,13 +249,13 @@ notify_ready (void *cls, size_t size, void *buf) return 0; } - GNUNET_assert (size >= MSIZE); + GNUNET_assert (size >= TEST_MESSAGE_SIZE); if (buf != NULL) { hdr = buf; - hdr->size = htons (MSIZE); - hdr->type = htons (MTYPE); + hdr->size = htons (TEST_MESSAGE_SIZE); + hdr->type = htons (TEST_MESSAGE_TYPE); } char *ps = GNUNET_strdup (GNUNET_i2s (&p2->id)); @@ -265,7 +265,7 @@ notify_ready (void *cls, size_t size, void *buf) GNUNET_i2s (&p->id)); GNUNET_free (ps); - return MSIZE; + return TEST_MESSAGE_SIZE; } static void @@ -282,7 +282,7 @@ sendtask (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) p2->no, GNUNET_i2s (&p2->id), p1->no, receiver_s); GNUNET_free (receiver_s); - th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, MSIZE, 0, + th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, TEST_MESSAGE_SIZE, 0, TIMEOUT_TRANSMIT, ¬ify_ready, p1); } diff --git a/src/transport/test_transport_api_disconnect_tcp_peer1.conf b/src/transport/test_transport_api_disconnect_tcp_peer1.conf index 8bfa374..ebb4fd4 100644 --- a/src/transport/test_transport_api_disconnect_tcp_peer1.conf +++ b/src/transport/test_transport_api_disconnect_tcp_peer1.conf @@ -26,6 +26,7 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12001 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p1-service-transport.sock #DEBUG = YES diff --git a/src/transport/test_transport_api_disconnect_tcp_peer2.conf b/src/transport/test_transport_api_disconnect_tcp_peer2.conf index 6bb7fad..fe6d19b 100644 --- a/src/transport/test_transport_api_disconnect_tcp_peer2.conf +++ b/src/transport/test_transport_api_disconnect_tcp_peer2.conf @@ -26,5 +26,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock diff --git a/src/transport/test_transport_api_limited_sockets.c b/src/transport/test_transport_api_limited_sockets.c index 8b8cdc0..e6ad84a 100644 --- a/src/transport/test_transport_api_limited_sockets.c +++ b/src/transport/test_transport_api_limited_sockets.c @@ -18,7 +18,7 @@ Boston, MA 02111-1307, USA. */ /** - * @file transport/test_transport_api.c + * @file transport/test_transport_api_limited_sockets.c * @brief base test case for transport implementations * * This test case serves as a base for tcp, udp, and udp-nat @@ -69,19 +69,19 @@ static GNUNET_SCHEDULER_TaskIdentifier die_task; static GNUNET_SCHEDULER_TaskIdentifier send_task; -struct PeerContext *p1; +static struct PeerContext *p1; -struct PeerContext *p2; +static struct PeerContext *p2; static GNUNET_TRANSPORT_TESTING_ConnectRequest cc; -struct GNUNET_TRANSPORT_TransmitHandle *th; +static struct GNUNET_TRANSPORT_TransmitHandle *th; -struct GNUNET_TRANSPORT_TESTING_handle *tth; +static struct GNUNET_TRANSPORT_TESTING_handle *tth; -char *cfg_file_p1; +static char *cfg_file_p1; -char *cfg_file_p2; +static char *cfg_file_p2; #if VERBOSE #define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) @@ -228,7 +228,7 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &sendtask, NULL); } -void +static void start_cb (struct PeerContext *p, void *cls) { static int started; @@ -334,11 +334,10 @@ main (int argc, char *argv[]) int res; res = getrlimit (RLIMIT_NOFILE, &r_file_old); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Maximum number of open files was: %u/%u\n", r_file_old.rlim_cur, r_file_old.rlim_max); - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting maximum number of open files to: %u\n", MAX_FILES); r_file_new.rlim_cur = MAX_FILES; r_file_new.rlim_max = r_file_old.rlim_max; @@ -367,7 +366,7 @@ main (int argc, char *argv[]) GNUNET_free (test_name); #if HAVE_SETRLIMIT - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Restoring previous value maximum number of open files\n"); res = setrlimit (RLIMIT_NOFILE, &r_file_old); if (res != 0) @@ -376,8 +375,7 @@ main (int argc, char *argv[]) return 0; } #endif - return ret; } -/* end of test_transport_api.c */ +/* end of test_transport_api_limited_sockets.c */ diff --git a/src/transport/test_transport_api_limited_sockets_tcp_peer1.conf b/src/transport/test_transport_api_limited_sockets_tcp_peer1.conf index dee44f6..d29b946 100644 --- a/src/transport/test_transport_api_limited_sockets_tcp_peer1.conf +++ b/src/transport/test_transport_api_limited_sockets_tcp_peer1.conf @@ -26,6 +26,7 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12001 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p1-service-transport.sock diff --git a/src/transport/test_transport_api_limited_sockets_tcp_peer2.conf b/src/transport/test_transport_api_limited_sockets_tcp_peer2.conf index 04324f4..3c0e496 100644 --- a/src/transport/test_transport_api_limited_sockets_tcp_peer2.conf +++ b/src/transport/test_transport_api_limited_sockets_tcp_peer2.conf @@ -26,5 +26,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock diff --git a/src/transport/test_transport_api_reliability.c b/src/transport/test_transport_api_reliability.c index f719a42..759241c 100644 --- a/src/transport/test_transport_api_reliability.c +++ b/src/transport/test_transport_api_reliability.c @@ -243,7 +243,7 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, if (0 != memcmp (cbuf, &hdr[1], s - sizeof (struct TestMessage))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Expected message %u with bits %u, but body did not match\n", n, + "Expected message %u with bits %u, but body did not match at position %u\n", n, (unsigned char) n); if (die_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (die_task); diff --git a/src/transport/test_transport_api_reliability_tcp_nat_peer1.conf b/src/transport/test_transport_api_reliability_tcp_nat_peer1.conf index 2f0b3ba..ffd3d2f 100644 --- a/src/transport/test_transport_api_reliability_tcp_nat_peer1.conf +++ b/src/transport/test_transport_api_reliability_tcp_nat_peer1.conf @@ -31,6 +31,7 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 29542 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p1-service-transport.sock diff --git a/src/transport/test_transport_api_reliability_tcp_nat_peer2.conf b/src/transport/test_transport_api_reliability_tcp_nat_peer2.conf index 20ca7a0..c6020ff 100644 --- a/src/transport/test_transport_api_reliability_tcp_nat_peer2.conf +++ b/src/transport/test_transport_api_reliability_tcp_nat_peer2.conf @@ -30,6 +30,7 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 45923 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock diff --git a/src/transport/test_transport_api_reliability_tcp_peer1.conf b/src/transport/test_transport_api_reliability_tcp_peer1.conf index a05165a..3be982d 100644 --- a/src/transport/test_transport_api_reliability_tcp_peer1.conf +++ b/src/transport/test_transport_api_reliability_tcp_peer1.conf @@ -26,5 +26,6 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12001 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p1-service-transport.sock diff --git a/src/transport/test_transport_api_reliability_tcp_peer2.conf b/src/transport/test_transport_api_reliability_tcp_peer2.conf index 2ceff2c..62575a9 100644 --- a/src/transport/test_transport_api_reliability_tcp_peer2.conf +++ b/src/transport/test_transport_api_reliability_tcp_peer2.conf @@ -26,5 +26,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock #DEBUG = YES diff --git a/src/transport/test_transport_api_restart_1peer.c b/src/transport/test_transport_api_restart_1peer.c index b414805..b7fc7ab 100644 --- a/src/transport/test_transport_api_restart_1peer.c +++ b/src/transport/test_transport_api_restart_1peer.c @@ -36,8 +36,6 @@ #include "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO -#define VERBOSE_ARM GNUNET_NO #define START_ARM GNUNET_YES @@ -63,32 +61,26 @@ static GNUNET_SCHEDULER_TaskIdentifier send_task; static GNUNET_SCHEDULER_TaskIdentifier reconnect_task; -struct PeerContext *p1; +static struct PeerContext *p1; -int p1_connected; +static int p1_connected; -struct PeerContext *p2; +static struct PeerContext *p2; -int p2_connected; +static int p2_connected; static GNUNET_TRANSPORT_TESTING_ConnectRequest cc; -struct GNUNET_TRANSPORT_TransmitHandle *th; +static struct GNUNET_TRANSPORT_TransmitHandle *th; -struct GNUNET_TRANSPORT_TESTING_handle *tth; +static struct GNUNET_TRANSPORT_TESTING_handle *tth; -char *cfg_file_p1; +static char *cfg_file_p1; -char *cfg_file_p2; +static char *cfg_file_p2; static int restarted; -#if VERBOSE -#define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) -#else -#define OKPP do { ok++; } while (0) -#endif - static void end () @@ -112,7 +104,9 @@ end () th = NULL; GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); + p1 = NULL; GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); + p2 = NULL; } static void @@ -338,16 +332,16 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) { struct PeerContext *p = cls; - if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity))) + if ( (NULL != p1) && + (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity)))) { p1_connected = GNUNET_NO; } - if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity))) + if ( (NULL != p2) && + (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity)))) { p2_connected = GNUNET_NO; } - - char *ps = GNUNET_strdup (GNUNET_i2s (&p->id)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -358,6 +352,9 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) if (th != NULL) GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); th = NULL; + if (GNUNET_SCHEDULER_NO_TASK != send_task) + GNUNET_SCHEDULER_cancel (send_task); + send_task = GNUNET_SCHEDULER_NO_TASK; } static void @@ -375,7 +372,7 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) -void +static void start_cb (struct PeerContext *p, void *cls) { static int started; @@ -434,9 +431,6 @@ check () static char *const argv[] = { "test-transport-api", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -461,30 +455,17 @@ main (int argc, char *argv[]) int ret; GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name); - - GNUNET_log_setup (test_name, -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); - tth = GNUNET_TRANSPORT_TESTING_init (); - GNUNET_asprintf (&cfg_file_p1, "test_transport_api_tcp_peer1.conf"); GNUNET_asprintf (&cfg_file_p2, "test_transport_api_tcp_peer2.conf"); - ret = check (); - GNUNET_free (cfg_file_p1); GNUNET_free (cfg_file_p2); - GNUNET_free (test_name); - GNUNET_TRANSPORT_TESTING_done (tth); - return ret; } diff --git a/src/transport/test_transport_api_restart_2peers.c b/src/transport/test_transport_api_restart_2peers.c index 86758df..1d7790c 100644 --- a/src/transport/test_transport_api_restart_2peers.c +++ b/src/transport/test_transport_api_restart_2peers.c @@ -36,20 +36,17 @@ #include "transport.h" #include "transport-testing.h" -#define VERBOSE GNUNET_NO -#define VERBOSE_ARM GNUNET_NO - #define START_ARM GNUNET_YES /** * How long until we give up on transmitting the message? */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90) /** * How long until we give up on transmitting the message? */ -#define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) +#define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) #define MTYPE 12345 @@ -63,34 +60,27 @@ static GNUNET_SCHEDULER_TaskIdentifier send_task; static GNUNET_SCHEDULER_TaskIdentifier reconnect_task; -struct PeerContext *p1; +static struct PeerContext *p1; -struct PeerContext *p2; +static struct PeerContext *p2; static GNUNET_TRANSPORT_TESTING_ConnectRequest cc; -struct GNUNET_TRANSPORT_TransmitHandle *th; +static struct GNUNET_TRANSPORT_TransmitHandle *th; -struct GNUNET_TRANSPORT_TESTING_handle *tth; +static struct GNUNET_TRANSPORT_TESTING_handle *tth; -char *cfg_file_p1; +static char *cfg_file_p1; -char *cfg_file_p2; +static char *cfg_file_p2; static int restarted; -#if VERBOSE -#define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) -#else -#define OKPP do { ok++; } while (0) -#endif - static void end () { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peers\n"); - if (send_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (send_task); send_task = GNUNET_SCHEDULER_NO_TASK; @@ -111,18 +101,17 @@ end () GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); } + static void end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { die_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Fail! Stopping peers\n"); - if (restarted == GNUNET_YES) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peer was restarted\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peer was restarted, but communication did not resume\n"); if (restarted == GNUNET_NO) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peer was NOT restarted\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peer was NOT (even) restarted\n"); if (reconnect_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (reconnect_task); @@ -151,35 +140,34 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) ok = GNUNET_SYSERR; } + static void reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct PeerContext *p = cls; reconnect_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_TRANSPORT_try_connect (p1->th, &p2->id); reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect, p); } + static void restart_cb (struct PeerContext *p, void *cls) { static int c; c++; - if (c != 2) return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Restarted peer %u (`%4s'), issuing reconnect\n", p->no, GNUNET_i2s (&p->id)); - reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, p); } + static void restart (struct PeerContext *p, char *cfg_file) { @@ -187,9 +175,9 @@ restart (struct PeerContext *p, char *cfg_file) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Restarting peer %u (`%4s')\n", p->no, GNUNET_i2s (&p->id)); GNUNET_TRANSPORT_TESTING_restart_peer (tth, p, cfg_file, &restart_cb, p); - return; } + static void notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, @@ -248,7 +236,6 @@ notify_ready (void *cls, size_t size, void *buf) struct GNUNET_MessageHeader *hdr; th = NULL; - if (buf == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -345,8 +332,12 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) if (th != NULL) GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); th = NULL; + if (GNUNET_SCHEDULER_NO_TASK != send_task) + GNUNET_SCHEDULER_cancel (send_task); + send_task = GNUNET_SCHEDULER_NO_TASK; } + static void testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) { @@ -361,8 +352,7 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) } - -void +static void start_cb (struct PeerContext *p, void *cls) { static int started; @@ -387,6 +377,7 @@ start_cb (struct PeerContext *p, void *cls) } + static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) @@ -420,9 +411,6 @@ check () static char *const argv[] = { "test-transport-api", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -436,41 +424,29 @@ check () ok = 1; GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, test_name, - "nohelp", options, &run, &ok); + "nohelp", options, &run, NULL); return ok; } + int main (int argc, char *argv[]) { int ret; GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name); - - GNUNET_log_setup (test_name, -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); - tth = GNUNET_TRANSPORT_TESTING_init (); - GNUNET_asprintf (&cfg_file_p1, "test_transport_api_tcp_peer1.conf"); GNUNET_asprintf (&cfg_file_p2, "test_transport_api_tcp_peer2.conf"); - ret = check (); - GNUNET_free (cfg_file_p1); GNUNET_free (cfg_file_p2); - GNUNET_free (test_name); - GNUNET_TRANSPORT_TESTING_done (tth); - return ret; } diff --git a/src/transport/test_transport_api_tcp_nat_peer1.conf b/src/transport/test_transport_api_tcp_nat_peer1.conf index 78afb3d..73f36f3 100644 --- a/src/transport/test_transport_api_tcp_nat_peer1.conf +++ b/src/transport/test_transport_api_tcp_nat_peer1.conf @@ -31,6 +31,7 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 29542 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p1-service-transport.sock #DEBUG = YES diff --git a/src/transport/test_transport_api_tcp_nat_peer2.conf b/src/transport/test_transport_api_tcp_nat_peer2.conf index d94ebb1..0bf50fd 100644 --- a/src/transport/test_transport_api_tcp_nat_peer2.conf +++ b/src/transport/test_transport_api_tcp_nat_peer2.conf @@ -30,5 +30,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 45923 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock #DEBUG = YES diff --git a/src/transport/test_transport_api_tcp_peer1.conf b/src/transport/test_transport_api_tcp_peer1.conf index 8bfa374..9532b73 100644 --- a/src/transport/test_transport_api_tcp_peer1.conf +++ b/src/transport/test_transport_api_tcp_peer1.conf @@ -27,5 +27,6 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12001 UNIXPATH = /tmp/gnunet-p1-service-transport.sock +PLUGINS = tcp #DEBUG = YES diff --git a/src/transport/test_transport_api_tcp_peer2.conf b/src/transport/test_transport_api_tcp_peer2.conf index 6bb7fad..fe6d19b 100644 --- a/src/transport/test_transport_api_tcp_peer2.conf +++ b/src/transport/test_transport_api_tcp_peer2.conf @@ -26,5 +26,6 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock diff --git a/src/transport/test_transport_api_timeout.c b/src/transport/test_transport_api_timeout.c index 9ce701a..8b92dce 100644 --- a/src/transport/test_transport_api_timeout.c +++ b/src/transport/test_transport_api_timeout.c @@ -40,8 +40,6 @@ #define VERBOSE GNUNET_NO -#define VERBOSE_ARM GNUNET_NO - #define START_ARM GNUNET_YES /** @@ -65,19 +63,19 @@ static GNUNET_SCHEDULER_TaskIdentifier die_task; static GNUNET_SCHEDULER_TaskIdentifier timer_task; -struct GNUNET_TRANSPORT_TESTING_handle *tth; +static struct GNUNET_TRANSPORT_TESTING_handle *tth; -struct PeerContext *p1; +static struct PeerContext *p1; -struct PeerContext *p2; +static struct PeerContext *p2; static GNUNET_TRANSPORT_TESTING_ConnectRequest cc; -struct GNUNET_TRANSPORT_TransmitHandle *th; +static struct GNUNET_TRANSPORT_TransmitHandle *th; -char *cfg_file_p1; +static char *cfg_file_p1; -char *cfg_file_p2; +static char *cfg_file_p2; static struct GNUNET_TIME_Relative time_running; @@ -192,6 +190,7 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) th = NULL; } + static void timer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -235,7 +234,7 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) shutdown_flag = GNUNET_NO; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Waiting for %llu seconds\n", (WAIT.rel_value) / 1000); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Waiting for %llu seconds\n", (WAIT.rel_value) / 1000); if (die_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (die_task); @@ -244,7 +243,8 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) timer_task = GNUNET_SCHEDULER_add_now (&timer, NULL); } -void + +static void start_cb (struct PeerContext *p, void *cls) { static int started; @@ -299,9 +299,6 @@ check () static char *const argv[] = { "test-transport-api-timeout", "-c", "test_transport_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; static struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -329,11 +326,7 @@ main (int argc, char *argv[]) GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name); GNUNET_log_setup (test_name, -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source); diff --git a/src/transport/test_transport_api_timeout_tcp_peer1.conf b/src/transport/test_transport_api_timeout_tcp_peer1.conf index 89beecb..ecb599f 100644 --- a/src/transport/test_transport_api_timeout_tcp_peer1.conf +++ b/src/transport/test_transport_api_timeout_tcp_peer1.conf @@ -26,6 +26,7 @@ UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock [transport] PORT = 12001 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p1-service-transport.sock diff --git a/src/transport/test_transport_api_timeout_tcp_peer2.conf b/src/transport/test_transport_api_timeout_tcp_peer2.conf index a21c4f5..ba2e27e 100644 --- a/src/transport/test_transport_api_timeout_tcp_peer2.conf +++ b/src/transport/test_transport_api_timeout_tcp_peer2.conf @@ -28,6 +28,7 @@ UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock [transport] PORT = 12010 +PLUGINS = tcp UNIXPATH = /tmp/gnunet-p2-service-transport.sock diff --git a/src/transport/test_transport_defaults.conf b/src/transport/test_transport_defaults.conf index f553377..0939a79 100644 --- a/src/transport/test_transport_defaults.conf +++ b/src/transport/test_transport_defaults.conf @@ -41,9 +41,15 @@ AUTOSTART = NO [chat] AUTOSTART = NO +[namestore] +AUTOSTART = NO + [vpn] AUTOSTART = NO +[lockmanager] +AUTOSTART = NO + [nat] DISABLEV6 = YES BINDTO = 127.0.0.1 diff --git a/src/transport/transport-testing.c b/src/transport/transport-testing.c index 752106b..695c048 100644 --- a/src/transport/transport-testing.c +++ b/src/transport/transport-testing.c @@ -52,6 +52,7 @@ get_host_key (struct GNUNET_TRANSPORT_TESTING_handle *tth) return NULL; } + static struct PeerContext * find_peer_context (struct GNUNET_TRANSPORT_TESTING_handle *tth, const struct GNUNET_PeerIdentity *peer) @@ -69,7 +70,8 @@ find_peer_context (struct GNUNET_TRANSPORT_TESTING_handle *tth, return t; } -struct ConnectingContext * + +static struct ConnectingContext * find_connecting_context (struct GNUNET_TRANSPORT_TESTING_handle *tth, struct PeerContext *p1, struct PeerContext *p2) { @@ -88,6 +90,7 @@ find_connecting_context (struct GNUNET_TRANSPORT_TESTING_handle *tth, return cc; } + static void notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *ats, uint32_t ats_count) @@ -134,6 +137,7 @@ notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, } } + static void notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) { @@ -167,6 +171,7 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) p->nd (p->cb_cls, peer); } + static void notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, @@ -180,6 +185,7 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, p->rec (p->cb_cls, peer, message, ats, ats_count); } + static void get_hello (void *cb_cls, const struct GNUNET_MessageHeader *message) { @@ -307,11 +313,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", "-c", cfgname, -#if VERBOSE_PEERS - "-L", "DEBUG", -#else "-L", "ERROR", -#endif NULL); p->no = peer_id; @@ -361,10 +363,8 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_handle GNUNET_assert (p->servicehome != NULL); /* shutdown */ -#if VERBOSE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", "Stopping peer %u (`%s')\n", p->no, GNUNET_i2s (&p->id)); -#endif if (p->ghh != NULL) GNUNET_TRANSPORT_get_hello_cancel (p->ghh); p->ghh = NULL; @@ -377,7 +377,7 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_handle if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (p->arm_proc); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } if (p->hello != NULL) @@ -390,11 +390,8 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_handle /* start */ -#if VERBOSE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", "Restarting peer %u (`%s')\n", p->no, GNUNET_i2s (&p->id)); -#endif - sleep (5); // YUCK! if (GNUNET_DISK_file_test (cfgname) == GNUNET_NO) @@ -424,11 +421,7 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_handle GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", "-c", cfgname, -#if VERBOSE_PEERS - "-L", "DEBUG", -#else "-L", "ERROR", -#endif NULL); p->th = @@ -451,6 +444,7 @@ fail: return GNUNET_SYSERR; } + /** * shutdown the given peer * @param tth testing handle @@ -461,53 +455,49 @@ GNUNET_TRANSPORT_TESTING_stop_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth, struct PeerContext *p) { GNUNET_assert (p != NULL); - if (p->ghh != NULL) + { GNUNET_TRANSPORT_get_hello_cancel (p->ghh); - p->ghh = NULL; - + p->ghh = NULL; + } if (p->th != NULL) GNUNET_TRANSPORT_disconnect (p->th); - if (NULL != p->arm_proc) { if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (p->arm_proc); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } - if (p->hostkeyfile != NULL) { GNUNET_DISK_directory_remove (p->hostkeyfile); GNUNET_free (p->hostkeyfile); } - if (p->servicehome != NULL) { GNUNET_DISK_directory_remove (p->servicehome); GNUNET_free (p->servicehome); } - if (p->hello != NULL) + { GNUNET_free (p->hello); - p->hello = NULL; - + p->hello = NULL; + } if (p->cfg != NULL) + { GNUNET_CONFIGURATION_destroy (p->cfg); - p->cfg = NULL; - + p->cfg = NULL; + } GNUNET_CONTAINER_DLL_remove (tth->p_head, tth->p_tail, p); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", "Peer %u (`%s') stopped \n", p->no, GNUNET_i2s (&p->id)); - GNUNET_free (p); - p = NULL; } + /** * Connect the given peers and call the callback when both peers report the * inbound connection. Remarks: start_peer's notify_connect callback can be called @@ -534,24 +524,18 @@ GNUNET_TRANSPORT_TESTING_connect_peers (struct GNUNET_TRANSPORT_TESTING_handle * GNUNET_assert (p1 != NULL); GNUNET_assert (p2 != NULL); - cc->p1 = p1; cc->p2 = p2; - cc->cb = cb; if (cls != NULL) cc->cb_cls = cls; else cc->cb_cls = cc; - cc->th_p1 = p1->th; cc->th_p2 = p2->th; - GNUNET_assert (cc->th_p1 != NULL); GNUNET_assert (cc->th_p2 != NULL); - GNUNET_CONTAINER_DLL_insert (tth->cc_head, tth->cc_tail, cc); - cc->tct = GNUNET_SCHEDULER_add_now (&try_connect, cc); GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", "New connect request %X\n", cc); @@ -559,6 +543,7 @@ GNUNET_TRANSPORT_TESTING_connect_peers (struct GNUNET_TRANSPORT_TESTING_handle * return cc; } + /** * Cancel the request to connect two peers * Tou MUST cancel the request if you stop the peers before the peers connected succesfully @@ -627,6 +612,7 @@ GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_handle *tth) tth = NULL; } + /** * Initialize the transport testing * @return transport testing handle @@ -661,7 +647,7 @@ GNUNET_TRANSPORT_TESTING_init () return NULL; } - if (GNUNET_YES != GNUNET_DISK_file_size (hostkeys_file, &fs, GNUNET_YES)) + if (GNUNET_OK != GNUNET_DISK_file_size (hostkeys_file, &fs, GNUNET_YES, GNUNET_YES)) fs = 0; if (0 != (fs % HOSTKEYFILESIZE)) @@ -722,6 +708,7 @@ extract_filename (const char *file) return res; } + /** * Extracts the test filename from an absolute file name and removes the extension * @param file absolute file name @@ -781,7 +768,8 @@ GNUNET_TRANSPORT_TESTING_get_test_source_name (const char *file, char **dest) /** - * Extracts the plugin anme from an absolute file name and the test name + * Extracts the plugin name from an absolute file name and the test name + * * @param file absolute file name * @param test test name * @param dest where to store result @@ -790,43 +778,39 @@ void GNUNET_TRANSPORT_TESTING_get_test_plugin_name (const char *file, const char *test, char **dest) { + char *filename; + char *dotexe; char *e = extract_filename (file); char *t = extract_filename (test); - char *filename = NULL; - char *dotexe; - - if (e == NULL) + if (NULL == e) goto fail; - /* remove "lt-" */ filename = strstr (e, "tes"); - if (filename == NULL) + if (NULL == filename) goto fail; - /* remove ".exe" */ if (NULL != (dotexe = strstr (filename, ".exe"))) dotexe[0] = '\0'; /* find last _ */ filename = strstr (filename, t); - if (filename == NULL) + if (NULL == filename) goto fail; - /* copy plugin */ filename += strlen (t); - filename++; + if ('\0' != *filename) + filename++; GNUNET_asprintf (dest, "%s", filename); goto suc; - fail: (*dest) = NULL; suc: GNUNET_free (t); GNUNET_free (e); - } + /** * This function takes the filename (e.g. argv[0), removes a "lt-"-prefix and * if existing ".exe"-prefix and adds the peer-number @@ -843,30 +827,23 @@ GNUNET_TRANSPORT_TESTING_get_config_name (const char *file, char **dest, char *backup = filename; char *dotexe; - if (filename == NULL) + if (NULL == filename) goto fail; - /* remove "lt-" */ filename = strstr (filename, "tes"); - if (filename == NULL) + if (NULL == filename) goto fail; - /* remove ".exe" */ if (NULL != (dotexe = strstr (filename, ".exe"))) dotexe[0] = '\0'; - - goto suc; - + GNUNET_asprintf (dest, "%s_peer%u.conf", filename, count); + GNUNET_free (backup); + return; fail: (*dest) = NULL; - return; - -suc: - /* create cfg filename */ - GNUNET_asprintf (dest, "%s_peer%u.conf", filename, count); GNUNET_free (backup); } -/* end of transport_testing.h */ +/* end of transport-testing.c */ diff --git a/src/transport/transport.conf.in b/src/transport/transport.conf.in index ff81ff0..9a6f5d9 100644 --- a/src/transport/transport.conf.in +++ b/src/transport/transport.conf.in @@ -9,7 +9,7 @@ BINARY = gnunet-service-transport NEIGHBOUR_LIMIT = 50 ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; -PLUGINS = tcp +PLUGINS = tcp udp UNIXPATH = /tmp/gnunet-service-transport.sock BLACKLIST_FILE = $SERVICEHOME/blacklist # This could possibly be relaxed @@ -25,6 +25,8 @@ UNIX_MATCH_GID = YES # REJECT_FROM6 = # PREFIX = valgrind --leak-check=full +[transport-unix] +PORT = 22086 [transport-tcp] # Use 0 to ONLY advertise as a peer behind NAT (no port binding) diff --git a/src/transport/transport.h b/src/transport/transport.h index ff68188..e0b8819 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -33,11 +33,6 @@ #define DEBUG_TRANSPORT GNUNET_EXTRA_LOGGING -#define DEBUG_TRANSPORT_TIMEOUT GNUNET_EXTRA_LOGGING - -#define DEBUG_TRANSPORT_DISCONNECT GNUNET_EXTRA_LOGGING - -#define DEBUG_TRANSPORT_API GNUNET_EXTRA_LOGGING /** * For how long do we allow unused bandwidth @@ -289,7 +284,7 @@ struct AddressLookupMessage { /** - * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP + * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING */ struct GNUNET_MessageHeader header; diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c index 9ff5cec..b97a245 100644 --- a/src/transport/transport_api.c +++ b/src/transport/transport_api.c @@ -342,10 +342,8 @@ neighbour_add (struct GNUNET_TRANSPORT_Handle *h, { struct Neighbour *n; -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating entry for neighbour `%4s'.\n", GNUNET_i2s (pid)); -#endif n = GNUNET_malloc (sizeof (struct Neighbour)); n->id = *pid; n->h = h; @@ -416,10 +414,8 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_assert (h->client != NULL); if (msg == NULL) { -#if DEBUG_TRANSPORT_API - LOG (GNUNET_ERROR_TYPE_INFO, + LOG (GNUNET_ERROR_TYPE_DEBUG, "Error receiving from transport service, disconnecting temporarily.\n"); -#endif disconnect_and_schedule_reconnect (h); return; } @@ -435,11 +431,9 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); break; } -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving (my own) `%s' message, I am `%4s'.\n", "HELLO", GNUNET_i2s (&me)); -#endif GNUNET_free_non_null (h->my_hello); h->my_hello = NULL; if (size < sizeof (struct GNUNET_MessageHeader)) @@ -474,10 +468,8 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) break; } ats = (const struct GNUNET_ATS_Information *) &cim[1]; -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving `%s' message for `%4s'.\n", "CONNECT", GNUNET_i2s (&cim->id)); -#endif n = neighbour_find (h, &cim->id); if (n != NULL) { @@ -496,10 +488,8 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) } dim = (const struct DisconnectInfoMessage *) msg; GNUNET_break (ntohl (dim->reserved) == 0); -#if DEBUG_TRANSPORT_API_DISCONNECT LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving `%s' message for `%4s'.\n", "DISCONNECT", GNUNET_i2s (&dim->peer)); -#endif n = neighbour_find (h, &dim->peer); if (n == NULL) { @@ -515,10 +505,8 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) break; } okm = (const struct SendOkMessage *) msg; -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving `%s' message, transmission %s.\n", "SEND_OK", ntohl (okm->success) == GNUNET_OK ? "succeeded" : "failed"); -#endif n = neighbour_find (h, &okm->peer); if (n == NULL) break; @@ -536,9 +524,7 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_RECV: -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving `%s' message.\n", "RECV"); -#endif if (size < sizeof (struct InboundMessage) + sizeof (struct GNUNET_MessageHeader)) { @@ -555,10 +541,8 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); break; } -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u from `%4s'.\n", ntohs (imm->type), GNUNET_i2s (&im->peer)); -#endif n = neighbour_find (h, &im->peer); if (n == NULL) { @@ -569,9 +553,7 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) h->rec (h->cls, &im->peer, imm, ats, ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA: -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving `%s' message.\n", "SET_QUOTA"); -#endif if (size != sizeof (struct QuotaSetMessage)) { GNUNET_break (0); @@ -653,10 +635,8 @@ transport_notify_ready (void *cls, size_t size, void *buf) { GNUNET_CONTAINER_DLL_remove (h->control_head, h->control_tail, th); nret = th->notify (th->notify_cls, size, &cbuf[ret]); -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Added %u bytes of control message at %u\n", nret, ret); -#endif GNUNET_free (th); ret += nret; size -= nret; @@ -714,10 +694,8 @@ transport_notify_ready (void *cls, size_t size, void *buf) } /* if there are more pending messages, try to schedule those */ schedule_transmission (h); -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u bytes to transport service\n", ret); -#endif return ret; } @@ -750,11 +728,9 @@ schedule_transmission_task (void *cls, n->th = NULL; GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap)); n->hn = NULL; -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Signalling timeout for transmission to peer %s due to congestion\n", GNUNET_i2s (&n->id)); -#endif GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL)); GNUNET_free (th); } @@ -771,9 +747,7 @@ schedule_transmission_task (void *cls, return; /* no pending messages */ size = n->th->notify_size + sizeof (struct OutboundMessage); } -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Calling notify_transmit_ready\n"); -#endif h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client, size, GNUNET_TIME_UNIT_FOREVER_REL, @@ -809,11 +783,9 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h) n->th->notify_size); else return; /* no work to be done */ -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling next transmission to service in %llu ms\n", (unsigned long long) delay.rel_value); -#endif h->quota_task = GNUNET_SCHEDULER_add_delayed (delay, &schedule_transmission_task, h); } @@ -835,10 +807,8 @@ schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h, size_t size, { struct GNUNET_TRANSPORT_TransmitHandle *th; -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Control transmit of %u bytes requested\n", size); -#endif th = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_TransmitHandle)); th->notify = notify; th->notify_cls = notify_cls; @@ -866,15 +836,11 @@ send_start (void *cls, size_t size, void *buf) if (buf == NULL) { /* Can only be shutdown, just give up */ -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutdown while trying to transmit `%s' request.\n", "START"); -#endif return 0; } -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "START"); -#endif GNUNET_assert (size >= sizeof (struct StartMessage)); s.header.size = htons (sizeof (struct StartMessage)); s.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_START); @@ -909,9 +875,7 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) /* shutdown, just give up */ return; } -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to transport service.\n"); -#endif GNUNET_assert (h->client == NULL); GNUNET_assert (h->control_head == NULL); GNUNET_assert (h->control_tail == NULL); @@ -940,7 +904,7 @@ disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h) } if (NULL != h->client) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_YES); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } /* Forget about all neighbours that we used to be connected to */ @@ -956,11 +920,9 @@ disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h) th->notify (th->notify_cls, 0, NULL); GNUNET_free (th); } -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling task to reconnect to transport service in %llu ms.\n", h->reconnect_delay.rel_value); -#endif h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h); if (h->reconnect_delay.rel_value == 0) @@ -995,11 +957,9 @@ send_try_connect (void *cls, size_t size, void *buf) GNUNET_free (pid); return 0; } -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request with respect to `%4s'.\n", "REQUEST_CONNECT", GNUNET_i2s (pid)); -#endif GNUNET_assert (size >= sizeof (struct TransportRequestConnectMessage)); msg.header.size = htons (sizeof (struct TransportRequestConnectMessage)); msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT); @@ -1050,16 +1010,12 @@ send_hello (void *cls, size_t size, void *buf) if (buf == NULL) { -#if DEBUG_TRANSPORT_TIMEOUT LOG (GNUNET_ERROR_TYPE_DEBUG, "Timeout while trying to transmit `%s' request.\n", "HELLO"); -#endif GNUNET_free (msg); return 0; } -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "HELLO"); -#endif ssize = ntohs (msg->size); GNUNET_assert (size >= ssize); memcpy (buf, msg, ssize); @@ -1101,11 +1057,9 @@ GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle, } msg = GNUNET_malloc (size); memcpy (msg, hello, size); -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Offering `%s' message of `%4s' to transport for validation.\n", "HELLO", GNUNET_i2s (&peer)); -#endif schedule_control_transmit (handle, size, &send_hello, msg); } @@ -1204,9 +1158,7 @@ GNUNET_TRANSPORT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle) { -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Transport disconnect called!\n"); -#endif /* this disconnects all neighbours... */ if (handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK) disconnect_and_schedule_reconnect (handle); @@ -1291,11 +1243,9 @@ GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle *handle, delay = GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker, size); if (delay.rel_value > timeout.rel_value) delay.rel_value = 0; /* notify immediately (with failure) */ -#if DEBUG_TRANSPORT_API LOG (GNUNET_ERROR_TYPE_DEBUG, "Bandwidth tracker allows next transmission to peer %s in %llu ms\n", GNUNET_i2s (target), (unsigned long long) delay.rel_value); -#endif n->hn = GNUNET_CONTAINER_heap_insert (handle->ready_heap, n, delay.rel_value); schedule_transmission (handle); return th; diff --git a/src/transport/transport_api_address_lookup.c b/src/transport/transport_api_address_lookup.c index 6e03945..655be83 100644 --- a/src/transport/transport_api_address_lookup.c +++ b/src/transport/transport_api_address_lookup.c @@ -155,7 +155,7 @@ static void reconnect (struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx) { GNUNET_assert (GNUNET_NO == pal_ctx->one_shot); - GNUNET_CLIENT_disconnect (pal_ctx->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (pal_ctx->client); pal_ctx->client = NULL; pal_ctx->backoff = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply (pal_ctx->backoff, 2), @@ -294,17 +294,17 @@ peer_address_response_processor (void *cls, /** * Return all the known addresses for a specific peer or all peers. - * Returns continously all address if one_shot is set to GNUNET_NO + * Returns continuously all address if one_shot is set to GNUNET_NO * * CHANGE: Returns the address(es) that we are currently using for this * peer. Upon completion, the 'AddressLookUpCallback' is called one more * time with 'NULL' for the address and the peer. After this, the operation must no - * longer be explicitly cancelled. + * longer be explicitly canceled. * * @param cfg configuration to use * @param peer peer identity to look up the addresses of, CHANGE: allow NULL for all (connected) peers * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL), - * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly cancelled) + * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly canceled) * @param timeout how long is the lookup allowed to take at most (irrelevant if one_shot is set to GNUNET_NO) * @param peer_address_callback function to call with the results * @param peer_address_callback_cls closure for peer_address_callback @@ -354,7 +354,7 @@ GNUNET_TRANSPORT_peer_get_active_addresses_cancel (struct { if (NULL != alc->client) { - GNUNET_CLIENT_disconnect (alc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (alc->client); alc->client = NULL; } if (GNUNET_SCHEDULER_NO_TASK != alc->reconnect_task) diff --git a/src/transport/transport_api_address_to_string.c b/src/transport/transport_api_address_to_string.c index 4d80953..152e573 100644 --- a/src/transport/transport_api_address_to_string.c +++ b/src/transport/transport_api_address_to_string.c @@ -71,7 +71,7 @@ address_response_processor (void *cls, const struct GNUNET_MessageHeader *msg) if (msg == NULL) { alucb->cb (alucb->cb_cls, NULL); - GNUNET_CLIENT_disconnect (alucb->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (alucb->client); GNUNET_free (alucb); return; } @@ -82,7 +82,7 @@ address_response_processor (void *cls, const struct GNUNET_MessageHeader *msg) { /* done! */ alucb->cb (alucb->cb_cls, NULL); - GNUNET_CLIENT_disconnect (alucb->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (alucb->client); GNUNET_free (alucb); return; } @@ -92,7 +92,7 @@ address_response_processor (void *cls, const struct GNUNET_MessageHeader *msg) /* invalid reply */ GNUNET_break (0); alucb->cb (alucb->cb_cls, NULL); - GNUNET_CLIENT_disconnect (alucb->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (alucb->client); GNUNET_free (alucb); return; } @@ -141,13 +141,9 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle GNUNET_break (0); return NULL; } - client = GNUNET_CLIENT_connect ("transport", cfg); - if (client == NULL) + if (NULL == client) return NULL; -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_TRANSPORT_address_to_string\n"); -#endif msg = GNUNET_malloc (len); msg->header.size = htons (len); msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING); @@ -183,7 +179,7 @@ GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *alc) { - GNUNET_CLIENT_disconnect (alc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (alc->client); GNUNET_free (alc); } diff --git a/src/transport/transport_api_blacklist.c b/src/transport/transport_api_blacklist.c index be52623..0464620 100644 --- a/src/transport/transport_api_blacklist.c +++ b/src/transport/transport_api_blacklist.c @@ -168,7 +168,7 @@ static void reconnect (struct GNUNET_TRANSPORT_Blacklist *br) { if (br->client != NULL) - GNUNET_CLIENT_disconnect (br->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (br->client); br->client = GNUNET_CLIENT_connect ("transport", br->cfg); GNUNET_assert (br->client != NULL); br->th = @@ -288,7 +288,7 @@ GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br) GNUNET_CLIENT_notify_transmit_ready_cancel (br->th); br->th = NULL; } - GNUNET_CLIENT_disconnect (br->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (br->client); GNUNET_free (br); } diff --git a/src/tun/Makefile.in b/src/tun/Makefile.in index 3d0f165..896280a 100644 --- a/src/tun/Makefile.in +++ b/src/tun/Makefile.in @@ -185,6 +185,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -218,6 +219,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/util/Makefile.am b/src/util/Makefile.am index cded34d..8414ef2 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -37,6 +37,7 @@ noinst_PROGRAMS = \ gnunet-config-diff \ test_common_logging_dummy + gnunet_config_diff_SOURCES = \ gnunet-config-diff.c gnunet_config_diff_LDADD = \ @@ -98,23 +99,26 @@ libgnunetutil_la_SOURCES = \ service.c \ signal.c \ strings.c \ - time.c + time.c \ + speedup.c libgnunetutil_la_LIBADD = \ $(GCLIBADD) $(WINLIB) \ $(LIBGCRYPT_LIBS) \ $(LTLIBICONV) \ - -lltdl -lz $(XLIB) + -lltdl -lz -lunistring $(XLIB) libgnunetutil_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 7:0:0 + -version-info 8:0:0 bin_PROGRAMS = \ gnunet-service-resolver \ - gnunet-resolver + gnunet-resolver \ + gnunet-rsa + gnunet_service_resolver_SOURCES = \ gnunet-service-resolver.c @@ -133,6 +137,15 @@ gnunet_resolver_LDADD = \ gnunet_resolver_DEPENDENCIES = \ libgnunetutil.la + +gnunet_rsa_SOURCES = \ + gnunet-rsa.c +gnunet_rsa_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) +gnunet_rsa_DEPENDENCIES = \ + libgnunetutil.la + plugin_LTLIBRARIES = \ libgnunet_plugin_test.la @@ -183,6 +196,7 @@ check_PROGRAMS = \ test_resolver_api \ test_scheduler \ test_scheduler_delay \ + test_server_mst_interrupt \ test_server \ test_server_disconnect \ test_server_with_client \ @@ -190,6 +204,7 @@ check_PROGRAMS = \ test_service \ test_strings \ test_time \ + test_speedup \ $(BENCHMARKS) \ test_os_start_process \ test_common_logging_runtime_loglevels @@ -390,6 +405,11 @@ test_scheduler_delay_SOURCES = \ test_scheduler_delay_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la +test_server_mst_interrupt_SOURCES = \ + test_server_mst_interrupt.c +test_server_mst_interrupt_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + test_server_SOURCES = \ test_server.c test_server_LDADD = \ @@ -426,6 +446,11 @@ test_time_SOURCES = \ test_time_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la +test_speedup_SOURCES = \ + test_speedup.c +test_speedup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + perf_crypto_hash_SOURCES = \ perf_crypto_hash.c perf_crypto_hash_LDADD = \ @@ -437,4 +462,5 @@ EXTRA_DIST = \ test_program_data.conf \ test_pseudonym_data.conf \ test_resolver_api_data.conf \ - test_service_data.conf + test_service_data.conf \ + test_speedup_data.conf diff --git a/src/util/Makefile.in b/src/util/Makefile.in index 3c82fbf..5ea0157 100644 --- a/src/util/Makefile.in +++ b/src/util/Makefile.in @@ -40,7 +40,7 @@ target_triplet = @target@ noinst_PROGRAMS = gnunet-config-diff$(EXEEXT) \ test_common_logging_dummy$(EXEEXT) bin_PROGRAMS = gnunet-service-resolver$(EXEEXT) \ - gnunet-resolver$(EXEEXT) + gnunet-resolver$(EXEEXT) gnunet-rsa$(EXEEXT) check_PROGRAMS = test_bio$(EXEEXT) test_client$(EXEEXT) \ test_common_allocation$(EXEEXT) test_common_endian$(EXEEXT) \ test_common_logging$(EXEEXT) test_configuration$(EXEEXT) \ @@ -62,10 +62,12 @@ check_PROGRAMS = test_bio$(EXEEXT) test_client$(EXEEXT) \ test_peer$(EXEEXT) test_plugin$(EXEEXT) test_program$(EXEEXT) \ test_pseudonym$(EXEEXT) test_resolver_api$(EXEEXT) \ test_scheduler$(EXEEXT) test_scheduler_delay$(EXEEXT) \ - test_server$(EXEEXT) test_server_disconnect$(EXEEXT) \ + test_server_mst_interrupt$(EXEEXT) test_server$(EXEEXT) \ + test_server_disconnect$(EXEEXT) \ test_server_with_client$(EXEEXT) $(am__EXEEXT_1) \ test_service$(EXEEXT) test_strings$(EXEEXT) test_time$(EXEEXT) \ - $(am__EXEEXT_2) test_os_start_process$(EXEEXT) \ + test_speedup$(EXEEXT) $(am__EXEEXT_2) \ + test_os_start_process$(EXEEXT) \ test_common_logging_runtime_loglevels$(EXEEXT) subdir = src/util DIST_COMMON = $(dist_pkgcfg_DATA) $(srcdir)/Makefile.am \ @@ -140,7 +142,7 @@ am_libgnunetutil_la_OBJECTS = bandwidth.lo bio.lo client.lo \ os_installation.lo os_network.lo os_priority.lo peer.lo \ plugin.lo program.lo pseudonym.lo resolver_api.lo scheduler.lo \ server.lo server_mst.lo server_nc.lo server_tc.lo service.lo \ - signal.lo strings.lo time.lo + signal.lo strings.lo time.lo speedup.lo libgnunetutil_la_OBJECTS = $(am_libgnunetutil_la_OBJECTS) libgnunetutil_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -162,6 +164,8 @@ am_gnunet_config_diff_OBJECTS = gnunet-config-diff.$(OBJEXT) gnunet_config_diff_OBJECTS = $(am_gnunet_config_diff_OBJECTS) am_gnunet_resolver_OBJECTS = gnunet-resolver.$(OBJEXT) gnunet_resolver_OBJECTS = $(am_gnunet_resolver_OBJECTS) +am_gnunet_rsa_OBJECTS = gnunet-rsa.$(OBJEXT) +gnunet_rsa_OBJECTS = $(am_gnunet_rsa_OBJECTS) am_gnunet_service_resolver_OBJECTS = \ gnunet-service-resolver.$(OBJEXT) gnunet_service_resolver_OBJECTS = \ @@ -345,6 +349,12 @@ am_test_server_disconnect_OBJECTS = test_server_disconnect.$(OBJEXT) test_server_disconnect_OBJECTS = $(am_test_server_disconnect_OBJECTS) test_server_disconnect_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la +am_test_server_mst_interrupt_OBJECTS = \ + test_server_mst_interrupt.$(OBJEXT) +test_server_mst_interrupt_OBJECTS = \ + $(am_test_server_mst_interrupt_OBJECTS) +test_server_mst_interrupt_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la am_test_server_with_client_OBJECTS = \ test_server_with_client.$(OBJEXT) test_server_with_client_OBJECTS = \ @@ -360,6 +370,9 @@ test_server_with_client_unix_DEPENDENCIES = \ am_test_service_OBJECTS = test_service.$(OBJEXT) test_service_OBJECTS = $(am_test_service_OBJECTS) test_service_DEPENDENCIES = $(top_builddir)/src/util/libgnunetutil.la +am_test_speedup_OBJECTS = test_speedup.$(OBJEXT) +test_speedup_OBJECTS = $(am_test_speedup_OBJECTS) +test_speedup_DEPENDENCIES = $(top_builddir)/src/util/libgnunetutil.la am_test_strings_OBJECTS = test_strings.$(OBJEXT) test_strings_OBJECTS = $(am_test_strings_OBJECTS) test_strings_DEPENDENCIES = $(top_builddir)/src/util/libgnunetutil.la @@ -411,9 +424,9 @@ am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgnunet_plugin_test_la_SOURCES) \ $(libgnunetutil_la_SOURCES) $(libgnunetutilwin_la_SOURCES) \ $(gnunet_config_diff_SOURCES) $(gnunet_resolver_SOURCES) \ - $(gnunet_service_resolver_SOURCES) $(perf_crypto_hash_SOURCES) \ - $(test_bio_SOURCES) $(test_client_SOURCES) \ - $(test_common_allocation_SOURCES) \ + $(gnunet_rsa_SOURCES) $(gnunet_service_resolver_SOURCES) \ + $(perf_crypto_hash_SOURCES) $(test_bio_SOURCES) \ + $(test_client_SOURCES) $(test_common_allocation_SOURCES) \ $(test_common_endian_SOURCES) $(test_common_logging_SOURCES) \ $(test_common_logging_dummy_SOURCES) \ $(test_common_logging_runtime_loglevels_SOURCES) \ @@ -439,17 +452,18 @@ SOURCES = $(libgnunet_plugin_test_la_SOURCES) \ $(test_resolver_api_SOURCES) $(test_scheduler_SOURCES) \ $(test_scheduler_delay_SOURCES) $(test_server_SOURCES) \ $(test_server_disconnect_SOURCES) \ + $(test_server_mst_interrupt_SOURCES) \ $(test_server_with_client_SOURCES) \ $(test_server_with_client_unix_SOURCES) \ - $(test_service_SOURCES) $(test_strings_SOURCES) \ - $(test_time_SOURCES) + $(test_service_SOURCES) $(test_speedup_SOURCES) \ + $(test_strings_SOURCES) $(test_time_SOURCES) DIST_SOURCES = $(libgnunet_plugin_test_la_SOURCES) \ $(libgnunetutil_la_SOURCES) \ $(am__libgnunetutilwin_la_SOURCES_DIST) \ $(gnunet_config_diff_SOURCES) $(gnunet_resolver_SOURCES) \ - $(gnunet_service_resolver_SOURCES) $(perf_crypto_hash_SOURCES) \ - $(test_bio_SOURCES) $(test_client_SOURCES) \ - $(test_common_allocation_SOURCES) \ + $(gnunet_rsa_SOURCES) $(gnunet_service_resolver_SOURCES) \ + $(perf_crypto_hash_SOURCES) $(test_bio_SOURCES) \ + $(test_client_SOURCES) $(test_common_allocation_SOURCES) \ $(test_common_endian_SOURCES) $(test_common_logging_SOURCES) \ $(test_common_logging_dummy_SOURCES) \ $(test_common_logging_runtime_loglevels_SOURCES) \ @@ -475,10 +489,11 @@ DIST_SOURCES = $(libgnunet_plugin_test_la_SOURCES) \ $(test_resolver_api_SOURCES) $(test_scheduler_SOURCES) \ $(test_scheduler_delay_SOURCES) $(test_server_SOURCES) \ $(test_server_disconnect_SOURCES) \ + $(test_server_mst_interrupt_SOURCES) \ $(test_server_with_client_SOURCES) \ $(test_server_with_client_unix_SOURCES) \ - $(test_service_SOURCES) $(test_strings_SOURCES) \ - $(test_time_SOURCES) + $(test_service_SOURCES) $(test_speedup_SOURCES) \ + $(test_strings_SOURCES) $(test_time_SOURCES) DATA = $(dist_pkgcfg_DATA) $(pkgcfg_DATA) ETAGS = etags CTAGS = ctags @@ -540,6 +555,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -573,6 +589,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -780,17 +797,18 @@ libgnunetutil_la_SOURCES = \ service.c \ signal.c \ strings.c \ - time.c + time.c \ + speedup.c libgnunetutil_la_LIBADD = \ $(GCLIBADD) $(WINLIB) \ $(LIBGCRYPT_LIBS) \ $(LTLIBICONV) \ - -lltdl -lz $(XLIB) + -lltdl -lz -lunistring $(XLIB) libgnunetutil_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 7:0:0 + -version-info 8:0:0 gnunet_service_resolver_SOURCES = \ gnunet-service-resolver.c @@ -812,6 +830,16 @@ gnunet_resolver_LDADD = \ gnunet_resolver_DEPENDENCIES = \ libgnunetutil.la +gnunet_rsa_SOURCES = \ + gnunet-rsa.c + +gnunet_rsa_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) + +gnunet_rsa_DEPENDENCIES = \ + libgnunetutil.la + plugin_LTLIBRARIES = \ libgnunet_plugin_test.la @@ -1054,6 +1082,12 @@ test_scheduler_delay_SOURCES = \ test_scheduler_delay_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la +test_server_mst_interrupt_SOURCES = \ + test_server_mst_interrupt.c + +test_server_mst_interrupt_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + test_server_SOURCES = \ test_server.c @@ -1096,6 +1130,12 @@ test_time_SOURCES = \ test_time_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la +test_speedup_SOURCES = \ + test_speedup.c + +test_speedup_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + perf_crypto_hash_SOURCES = \ perf_crypto_hash.c @@ -1107,7 +1147,8 @@ EXTRA_DIST = \ test_program_data.conf \ test_pseudonym_data.conf \ test_resolver_api_data.conf \ - test_service_data.conf + test_service_data.conf \ + test_speedup_data.conf all: all-am @@ -1289,6 +1330,9 @@ gnunet-config-diff$(EXEEXT): $(gnunet_config_diff_OBJECTS) $(gnunet_config_diff_ gnunet-resolver$(EXEEXT): $(gnunet_resolver_OBJECTS) $(gnunet_resolver_DEPENDENCIES) @rm -f gnunet-resolver$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_resolver_OBJECTS) $(gnunet_resolver_LDADD) $(LIBS) +gnunet-rsa$(EXEEXT): $(gnunet_rsa_OBJECTS) $(gnunet_rsa_DEPENDENCIES) + @rm -f gnunet-rsa$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_rsa_OBJECTS) $(gnunet_rsa_LDADD) $(LIBS) gnunet-service-resolver$(EXEEXT): $(gnunet_service_resolver_OBJECTS) $(gnunet_service_resolver_DEPENDENCIES) @rm -f gnunet-service-resolver$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_service_resolver_OBJECTS) $(gnunet_service_resolver_LDADD) $(LIBS) @@ -1418,6 +1462,9 @@ test_server$(EXEEXT): $(test_server_OBJECTS) $(test_server_DEPENDENCIES) test_server_disconnect$(EXEEXT): $(test_server_disconnect_OBJECTS) $(test_server_disconnect_DEPENDENCIES) @rm -f test_server_disconnect$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_server_disconnect_OBJECTS) $(test_server_disconnect_LDADD) $(LIBS) +test_server_mst_interrupt$(EXEEXT): $(test_server_mst_interrupt_OBJECTS) $(test_server_mst_interrupt_DEPENDENCIES) + @rm -f test_server_mst_interrupt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_server_mst_interrupt_OBJECTS) $(test_server_mst_interrupt_LDADD) $(LIBS) test_server_with_client$(EXEEXT): $(test_server_with_client_OBJECTS) $(test_server_with_client_DEPENDENCIES) @rm -f test_server_with_client$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_server_with_client_OBJECTS) $(test_server_with_client_LDADD) $(LIBS) @@ -1427,6 +1474,9 @@ test_server_with_client_unix$(EXEEXT): $(test_server_with_client_unix_OBJECTS) $ test_service$(EXEEXT): $(test_service_OBJECTS) $(test_service_DEPENDENCIES) @rm -f test_service$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_service_OBJECTS) $(test_service_LDADD) $(LIBS) +test_speedup$(EXEEXT): $(test_speedup_OBJECTS) $(test_speedup_DEPENDENCIES) + @rm -f test_speedup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_speedup_OBJECTS) $(test_speedup_LDADD) $(LIBS) test_strings$(EXEEXT): $(test_strings_OBJECTS) $(test_strings_DEPENDENCIES) @rm -f test_strings$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_strings_OBJECTS) $(test_strings_LDADD) $(LIBS) @@ -1466,6 +1516,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt_helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-config-diff.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-resolver.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-rsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-resolver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load.Plo@am__quote@ @@ -1486,6 +1537,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_tc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/speedup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strings.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_client.Po@am__quote@ @@ -1529,9 +1581,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_scheduler_delay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server_disconnect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server_mst_interrupt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server_with_client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_server_with_client_unix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_service.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_speedup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_strings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_time.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@ diff --git a/src/util/client.c b/src/util/client.c index 2f09a90..c29b48e 100644 --- a/src/util/client.c +++ b/src/util/client.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2006, 2008, 2009 Christian Grothoff (and other contributing authors) + (C) 2001, 2002, 2006, 2008, 2009, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -26,7 +26,6 @@ * Generic TCP code for reliable, record-oriented TCP * connections between clients and service providers. */ - #include "platform.h" #include "gnunet_common.h" #include "gnunet_client_lib.h" @@ -34,7 +33,6 @@ #include "gnunet_server_lib.h" #include "gnunet_scheduler_lib.h" -#define DEBUG_CLIENT GNUNET_EXTRA_LOGGING /** * How often do we re-try tranmsitting requests before giving up? @@ -53,7 +51,7 @@ struct GNUNET_CLIENT_TransmitHandle /** * Connection state. */ - struct GNUNET_CLIENT_Connection *sock; + struct GNUNET_CLIENT_Connection *client; /** * Function to call to get the data for transmission. @@ -113,7 +111,7 @@ struct TransmitGetResponseContext /** * Client handle. */ - struct GNUNET_CLIENT_Connection *sock; + struct GNUNET_CLIENT_Connection *client; /** * Message to transmit; do not free, allocated @@ -147,9 +145,9 @@ struct GNUNET_CLIENT_Connection { /** - * the socket handle, NULL if not live + * The connection handle, NULL if not live */ - struct GNUNET_CONNECTION_Handle *sock; + struct GNUNET_CONNECTION_Handle *connection; /** * Our configuration. @@ -249,6 +247,79 @@ struct GNUNET_CLIENT_Connection }; +/** + * Try connecting to the server using UNIX domain sockets. + * + * @param service_name name of service to connect to + * @param cfg configuration to use + * @return NULL on error, connection to UNIX otherwise + */ +static struct GNUNET_CONNECTION_Handle * +try_unixpath (const char *service_name, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ +#if AF_UNIX + struct GNUNET_CONNECTION_Handle *connection; + char *unixpath; + + unixpath = NULL; + if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && + (0 < strlen (unixpath))) + { + /* We have a non-NULL unixpath, need to validate it */ + connection = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath); + if (NULL != connection) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n", + unixpath); + GNUNET_free (unixpath); + return connection; + } + } + GNUNET_free_non_null (unixpath); +#endif + return NULL; +} + + +/** + * Try connecting to the server using UNIX domain sockets. + * + * @param service_name name of service to connect to + * @param cfg configuration to use + * @return GNUNET_OK if the configuration is valid, GNUNET_SYSERR if not + */ +static int +test_service_configuration (const char *service_name, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + int ret = GNUNET_SYSERR; + char *hostname = NULL; + unsigned long long port; +#if AF_UNIX + char *unixpath = NULL; + + if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && + (0 < strlen (unixpath))) + ret = GNUNET_OK; + GNUNET_free_non_null (unixpath); +#endif + + if ( (GNUNET_YES == + GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) && + (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port)) && + (port <= 65535) && (0 != port) && + (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME", + &hostname)) && + (0 != strlen (hostname)) ) + ret = GNUNET_OK; + GNUNET_free_non_null (hostname); + return ret; +} + + /** * Try to connect to the service. * @@ -261,34 +332,18 @@ static struct GNUNET_CONNECTION_Handle * do_connect (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt) { - struct GNUNET_CONNECTION_Handle *sock; + struct GNUNET_CONNECTION_Handle *connection; char *hostname; - char *unixpath; unsigned long long port; - sock = NULL; -#if AF_UNIX + connection = NULL; if (0 == (attempt % 2)) { - /* on even rounds, try UNIX */ - unixpath = NULL; - if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */ - { - sock = GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath); - if (sock != NULL) - { -#if DEBUG_CLIENT - LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n", - unixpath); -#endif - GNUNET_free (unixpath); - return sock; - } - } - GNUNET_free_non_null (unixpath); + /* on even rounds, try UNIX first */ + connection = try_unixpath (service_name, cfg); + if (NULL != connection) + return connection; } -#endif - if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) { @@ -319,42 +374,21 @@ do_connect (const char *service_name, port = 0; hostname = NULL; } - if (port == 0) + if (0 == port) { -#if AF_UNIX - if (0 != (attempt % 2)) - { - /* try UNIX */ - unixpath = NULL; - if ((GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", - &unixpath)) && - (0 < strlen (unixpath))) - { - sock = - GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath); - if (sock != NULL) - { - GNUNET_free (unixpath); - GNUNET_free_non_null (hostname); - return sock; - } - } - GNUNET_free_non_null (unixpath); - } -#endif -#if DEBUG_CLIENT + /* if port is 0, try UNIX */ + connection = try_unixpath (service_name, cfg); + if (NULL != connection) + return connection; LOG (GNUNET_ERROR_TYPE_DEBUG, "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n", service_name); -#endif GNUNET_free_non_null (hostname); return NULL; } - - sock = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port); + connection = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port); GNUNET_free (hostname); - return sock; + return connection; } @@ -369,17 +403,21 @@ struct GNUNET_CLIENT_Connection * GNUNET_CLIENT_connect (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct GNUNET_CLIENT_Connection *ret; - struct GNUNET_CONNECTION_Handle *sock; - - sock = do_connect (service_name, cfg, 0); - ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection)); - ret->attempts = 1; - ret->sock = sock; - ret->service_name = GNUNET_strdup (service_name); - ret->cfg = cfg; - ret->back_off = GNUNET_TIME_UNIT_MILLISECONDS; - return ret; + struct GNUNET_CLIENT_Connection *client; + struct GNUNET_CONNECTION_Handle *connection; + + if (GNUNET_OK != + test_service_configuration (service_name, + cfg)) + return NULL; + connection = do_connect (service_name, cfg, 0); + client = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection)); + client->attempts = 1; + client->connection = connection; + client->service_name = GNUNET_strdup (service_name); + client->cfg = cfg; + client->back_off = GNUNET_TIME_UNIT_MILLISECONDS; + return client; } @@ -394,57 +432,57 @@ GNUNET_CLIENT_connect (const char *service_name, * destroyed (unless, of course, there is an error with the server in * which case the message may still be lost). * - * @param finish_pending_write should a transmission already passed to the - * handle be completed? - * @param sock handle to the service connection + * @param client handle to the service connection */ void -GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, - int finish_pending_write) +GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client) { - if (sock->in_receive == GNUNET_YES) + if (GNUNET_YES == client->in_receive) { - GNUNET_CONNECTION_receive_cancel (sock->sock); - sock->in_receive = GNUNET_NO; + GNUNET_CONNECTION_receive_cancel (client->connection); + client->in_receive = GNUNET_NO; } - if (sock->th != NULL) + if (NULL != client->th) { - GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th); - sock->th = NULL; + GNUNET_CLIENT_notify_transmit_ready_cancel (client->th); + client->th = NULL; } - if (NULL != sock->sock) + if (NULL != client->connection) { - GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write); - sock->sock = NULL; + GNUNET_CONNECTION_destroy (client->connection); + client->connection = NULL; } - if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != client->receive_task) { - GNUNET_SCHEDULER_cancel (sock->receive_task); - sock->receive_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_SCHEDULER_cancel (client->receive_task); + client->receive_task = GNUNET_SCHEDULER_NO_TASK; } - if (sock->tag != NULL) + if (NULL != client->tag) { - GNUNET_free (sock->tag); - sock->tag = NULL; + GNUNET_free (client->tag); + client->tag = NULL; } - sock->receiver_handler = NULL; - GNUNET_array_grow (sock->received_buf, sock->received_size, 0); - GNUNET_free (sock->service_name); - GNUNET_free (sock); + client->receiver_handler = NULL; + GNUNET_array_grow (client->received_buf, client->received_size, 0); + GNUNET_free (client->service_name); + GNUNET_free (client); } /** - * Check if message is complete + * Check if message is complete. Sets the "msg_complete" member + * in the client struct. + * + * @param client connection with the buffer to check */ static void -check_complete (struct GNUNET_CLIENT_Connection *conn) +check_complete (struct GNUNET_CLIENT_Connection *client) { - if ((conn->received_pos >= sizeof (struct GNUNET_MessageHeader)) && - (conn->received_pos >= - ntohs (((const struct GNUNET_MessageHeader *) conn->received_buf)-> + if ((client->received_pos >= sizeof (struct GNUNET_MessageHeader)) && + (client->received_pos >= + ntohs (((const struct GNUNET_MessageHeader *) client->received_buf)-> size))) - conn->msg_complete = GNUNET_YES; + client->msg_complete = GNUNET_YES; } @@ -464,54 +502,51 @@ static void receive_helper (void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode) { - struct GNUNET_CLIENT_Connection *conn = cls; + struct GNUNET_CLIENT_Connection *client = cls; struct GNUNET_TIME_Relative remaining; GNUNET_CLIENT_MessageHandler receive_handler; void *receive_handler_cls; - GNUNET_assert (conn->msg_complete == GNUNET_NO); - conn->in_receive = GNUNET_NO; - if ((available == 0) || (conn->sock == NULL) || (errCode != 0)) + GNUNET_assert (GNUNET_NO == client->msg_complete); + GNUNET_assert (GNUNET_YES == client->in_receive); + client->in_receive = GNUNET_NO; + if ((0 == available) || (NULL == client->connection) || (0 != errCode)) { /* signal timeout! */ -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, - "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n", - (unsigned int) available, conn->sock == NULL ? "NULL" : "non-NULL", + "Timeout in receive_helper, available %u, client->connection %s, errCode `%s'\n", + (unsigned int) available, NULL == client->connection ? "NULL" : "non-NULL", STRERROR (errCode)); -#endif - if (NULL != (receive_handler = conn->receiver_handler)) + if (NULL != (receive_handler = client->receiver_handler)) { - receive_handler_cls = conn->receiver_handler_cls; - conn->receiver_handler = NULL; + receive_handler_cls = client->receiver_handler_cls; + client->receiver_handler = NULL; receive_handler (receive_handler_cls, NULL); } return; } - /* FIXME: optimize for common fast case where buf contains the * entire message and we need no copying... */ - /* slow path: append to array */ - if (conn->received_size < conn->received_pos + available) - GNUNET_array_grow (conn->received_buf, conn->received_size, - conn->received_pos + available); - memcpy (&conn->received_buf[conn->received_pos], buf, available); - conn->received_pos += available; - check_complete (conn); + if (client->received_size < client->received_pos + available) + GNUNET_array_grow (client->received_buf, client->received_size, + client->received_pos + available); + memcpy (&client->received_buf[client->received_pos], buf, available); + client->received_pos += available; + check_complete (client); /* check for timeout */ - remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout); - if (remaining.rel_value == 0) + remaining = GNUNET_TIME_absolute_get_remaining (client->receive_timeout); + if (0 == remaining.rel_value) { /* signal timeout! */ - if (NULL != conn->receiver_handler) - conn->receiver_handler (conn->receiver_handler_cls, NULL); + if (NULL != client->receiver_handler) + client->receiver_handler (client->receiver_handler_cls, NULL); return; } /* back to receive -- either for more data or to call callback! */ - GNUNET_CLIENT_receive (conn, conn->receiver_handler, - conn->receiver_handler_cls, remaining); + GNUNET_CLIENT_receive (client, client->receiver_handler, + client->receiver_handler_cls, remaining); } @@ -524,30 +559,28 @@ receive_helper (void *cls, const void *buf, size_t available, static void receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_CLIENT_Connection *sock = cls; - GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler; + struct GNUNET_CLIENT_Connection *client = cls; + GNUNET_CLIENT_MessageHandler handler = client->receiver_handler; const struct GNUNET_MessageHeader *cmsg = - (const struct GNUNET_MessageHeader *) sock->received_buf; - void *handler_cls = sock->receiver_handler_cls; + (const struct GNUNET_MessageHeader *) client->received_buf; + void *handler_cls = client->receiver_handler_cls; uint16_t msize = ntohs (cmsg->size); char mbuf[msize]; struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) mbuf; -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u and size %u\n", ntohs (cmsg->type), msize); -#endif - sock->receive_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_assert (GNUNET_YES == sock->msg_complete); - GNUNET_assert (sock->received_pos >= msize); + client->receive_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_assert (GNUNET_YES == client->msg_complete); + GNUNET_assert (client->received_pos >= msize); memcpy (msg, cmsg, msize); - memmove (sock->received_buf, &sock->received_buf[msize], - sock->received_pos - msize); - sock->received_pos -= msize; - sock->msg_complete = GNUNET_NO; - sock->receiver_handler = NULL; - check_complete (sock); - if (handler != NULL) + memmove (client->received_buf, &client->received_buf[msize], + client->received_pos - msize); + client->received_pos -= msize; + client->msg_complete = GNUNET_NO; + client->receiver_handler = NULL; + check_complete (client); + if (NULL != handler) handler (handler_cls, msg); } @@ -555,17 +588,17 @@ receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) /** * Read from the service. * - * @param sock the service + * @param client the service * @param handler function to call with the message * @param handler_cls closure for handler * @param timeout how long to wait until timing out */ void -GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, +GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *client, GNUNET_CLIENT_MessageHandler handler, void *handler_cls, struct GNUNET_TIME_Relative timeout) { - if (sock->sock == NULL) + if (NULL == client->connection) { /* already disconnected, fail instantly! */ GNUNET_break (0); /* this should not happen in well-written code! */ @@ -573,23 +606,21 @@ GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, handler (handler_cls, NULL); return; } - sock->receiver_handler = handler; - sock->receiver_handler_cls = handler_cls; - sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); - if (GNUNET_YES == sock->msg_complete) + client->receiver_handler = handler; + client->receiver_handler_cls = handler_cls; + client->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); + if (GNUNET_YES == client->msg_complete) { - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task); - sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->receive_task); + client->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, client); } else { - GNUNET_assert (sock->in_receive == GNUNET_NO); - sock->in_receive = GNUNET_YES; -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n"); -#endif - GNUNET_CONNECTION_receive (sock->sock, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, - timeout, &receive_helper, sock); + GNUNET_assert (GNUNET_NO == client->in_receive); + client->in_receive = GNUNET_YES; + GNUNET_CONNECTION_receive (client->connection, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, + timeout, &receive_helper, client); } } @@ -614,25 +645,23 @@ service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls) static void confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg) { - struct GNUNET_CLIENT_Connection *conn = cls; + struct GNUNET_CLIENT_Connection *client = cls; /* We may want to consider looking at the reply in more * detail in the future, for example, is this the * correct service? FIXME! */ - if (msg != NULL) + if (NULL != msg) { -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "Received confirmation that service is running.\n"); -#endif - GNUNET_SCHEDULER_add_continuation (conn->test_cb, conn->test_cb_cls, + GNUNET_SCHEDULER_add_continuation (client->test_cb, client->test_cb_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); } else { - service_test_error (conn->test_cb, conn->test_cb_cls); + service_test_error (client->test_cb, client->test_cb_cls); } - GNUNET_CLIENT_disconnect (conn, GNUNET_NO); + GNUNET_CLIENT_disconnect (client); } @@ -648,27 +677,23 @@ confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg) static size_t write_test (void *cls, size_t size, void *buf) { - struct GNUNET_CLIENT_Connection *conn = cls; + struct GNUNET_CLIENT_Connection *client = cls; struct GNUNET_MessageHeader *msg; if (size < sizeof (struct GNUNET_MessageHeader)) { -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, _("Failure to transmit TEST request.\n")); -#endif - service_test_error (conn->test_cb, conn->test_cb_cls); - GNUNET_CLIENT_disconnect (conn, GNUNET_NO); + service_test_error (client->test_cb, client->test_cb_cls); + GNUNET_CLIENT_disconnect (client); return 0; /* client disconnected */ } -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TEST"); -#endif msg = (struct GNUNET_MessageHeader *) buf; msg->type = htons (GNUNET_MESSAGE_TYPE_TEST); msg->size = htons (sizeof (struct GNUNET_MessageHeader)); - GNUNET_CLIENT_receive (conn, &confirm_handler, conn, + GNUNET_CLIENT_receive (client, &confirm_handler, client, GNUNET_TIME_absolute_get_remaining - (conn->test_deadline)); + (client->test_deadline)); return sizeof (struct GNUNET_MessageHeader); } @@ -695,12 +720,10 @@ GNUNET_CLIENT_service_test (const char *service, char *hostname; unsigned long long port; struct GNUNET_NETWORK_Handle *sock; - struct GNUNET_CLIENT_Connection *conn; + struct GNUNET_CLIENT_Connection *client; -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n", service); -#endif #ifdef AF_UNIX { /* probe UNIX support */ @@ -720,7 +743,7 @@ GNUNET_CLIENT_service_test (const char *service, else { sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); - if (sock != NULL) + if (NULL != sock) { memset (&s_un, 0, sizeof (s_un)); s_un.sun_family = AF_UNIX; @@ -786,7 +809,7 @@ GNUNET_CLIENT_service_test (const char *service, s_in.sin_port = htons (port); sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); - if (sock != NULL) + if (NULL != sock) { if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in, @@ -820,7 +843,7 @@ GNUNET_CLIENT_service_test (const char *service, s_in6.sin6_port = htons (port); sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0); - if (sock != NULL) + if (NULL != sock) { if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6, @@ -852,8 +875,8 @@ GNUNET_CLIENT_service_test (const char *service, GNUNET_free_non_null (hostname); /* non-localhost, try 'connect' method */ - conn = GNUNET_CLIENT_connect (service, cfg); - if (conn == NULL) + client = GNUNET_CLIENT_connect (service, cfg); + if (NULL == client) { LOG (GNUNET_ERROR_TYPE_INFO, _("Could not connect to service `%s', must not be running.\n"), @@ -861,20 +884,18 @@ GNUNET_CLIENT_service_test (const char *service, service_test_error (task, task_cls); return; } - conn->test_cb = task; - conn->test_cb_cls = task_cls; - conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); - - if (NULL == - GNUNET_CLIENT_notify_transmit_ready (conn, - sizeof (struct GNUNET_MessageHeader), - timeout, GNUNET_YES, &write_test, - conn)) + client->test_cb = task; + client->test_cb_cls = task_cls; + client->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); + if (NULL == GNUNET_CLIENT_notify_transmit_ready (client, + sizeof (struct GNUNET_MessageHeader), + timeout, GNUNET_YES, &write_test, + client)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failure to transmit request to service `%s'\n"), service); service_test_error (task, task_cls); - GNUNET_CLIENT_disconnect (conn, GNUNET_NO); + GNUNET_CLIENT_disconnect (client); return; } } @@ -908,47 +929,35 @@ client_delayed_retry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_TIME_Relative delay; th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - { -#if DEBUG_CLIENT - LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed due to shutdown.\n"); -#endif - th->sock->th = NULL; - th->notify (th->notify_cls, 0, NULL); - GNUNET_free (th); - return; - } - th->sock->sock = - do_connect (th->sock->service_name, th->sock->cfg, th->sock->attempts++); - if (NULL == th->sock->sock) + th->client->connection = + do_connect (th->client->service_name, th->client->cfg, th->client->attempts++); + if (NULL == th->client->connection) { /* could happen if we're out of sockets */ delay = GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining - (th->timeout), th->sock->back_off); - th->sock->back_off = + (th->timeout), th->client->back_off); + th->client->back_off = GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply - (th->sock->back_off, 2), + (th->client->back_off, 2), GNUNET_TIME_UNIT_SECONDS); -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed %u times, trying again in %llums.\n", MAX_ATTEMPTS - th->attempts_left, (unsigned long long) delay.rel_value); -#endif th->reconnect_task = GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th); return; } th->th = - GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, th->size, + GNUNET_CONNECTION_notify_transmit_ready (th->client->connection, th->size, GNUNET_TIME_absolute_get_remaining (th->timeout), &client_notify, th); - if (th->th == NULL) + if (NULL == th->th) { GNUNET_break (0); - th->sock->th = NULL; + th->client->th = NULL; th->notify (th->notify_cls, 0, NULL); GNUNET_free (th); return; @@ -969,49 +978,47 @@ static size_t client_notify (void *cls, size_t size, void *buf) { struct GNUNET_CLIENT_TransmitHandle *th = cls; + struct GNUNET_CLIENT_Connection *client = th->client; size_t ret; struct GNUNET_TIME_Relative delay; th->th = NULL; - th->sock->th = NULL; - if (buf == NULL) + client->th = NULL; + if (NULL == buf) { delay = GNUNET_TIME_absolute_get_remaining (th->timeout); delay.rel_value /= 2; - if ((0 != - (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ())) || - (GNUNET_YES != th->auto_retry) || (0 == --th->attempts_left) || + if ((GNUNET_YES != th->auto_retry) || (0 == --th->attempts_left) || (delay.rel_value < 1)) { -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed %u times, giving up.\n", MAX_ATTEMPTS - th->attempts_left); -#endif GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL)); GNUNET_free (th); return 0; } /* auto-retry */ -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect to `%s', automatically trying again.\n", - th->sock->service_name); -#endif - GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO); - th->sock->sock = NULL; - delay = GNUNET_TIME_relative_min (delay, th->sock->back_off); - th->sock->back_off = + client->service_name); + if (GNUNET_YES == client->in_receive) + { + GNUNET_CONNECTION_receive_cancel (client->connection); + client->in_receive = GNUNET_NO; + } + GNUNET_CONNECTION_destroy (client->connection); + client->connection = NULL; + delay = GNUNET_TIME_relative_min (delay, client->back_off); + client->back_off = GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply - (th->sock->back_off, 2), + (client->back_off, 2), GNUNET_TIME_UNIT_SECONDS); -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed %u times, trying again in %llums.\n", MAX_ATTEMPTS - th->attempts_left, (unsigned long long) delay.rel_value); -#endif - th->sock->th = th; + client->th = th; th->reconnect_task = GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th); return 0; @@ -1028,7 +1035,7 @@ client_notify (void *cls, size_t size, void *buf) * are free in the transmission buffer. May call the notify * method immediately if enough space is available. * - * @param sock connection to the service + * @param client connection to the service * @param size number of bytes to send * @param timeout after how long should we give up (and call * notify with buf NULL and size 0)? @@ -1043,7 +1050,7 @@ client_notify (void *cls, size_t size, void *buf) * a handle if the notify callback was queued (can be used to cancel) */ struct GNUNET_CLIENT_TransmitHandle * -GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, +GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client, size_t size, struct GNUNET_TIME_Relative timeout, int auto_retry, @@ -1052,7 +1059,7 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, { struct GNUNET_CLIENT_TransmitHandle *th; - if (NULL != sock->th) + if (NULL != client->th) { /* If this breaks, you most likley called this function twice without waiting * for completion or canceling the request */ @@ -1060,31 +1067,31 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, return NULL; } th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle)); - th->sock = sock; + th->client = client; th->size = size; th->timeout = GNUNET_TIME_relative_to_absolute (timeout); th->auto_retry = auto_retry; th->notify = notify; th->notify_cls = notify_cls; th->attempts_left = MAX_ATTEMPTS; - sock->th = th; - if (sock->sock == NULL) + client->th = th; + if (NULL == client->connection) { th->reconnect_task = - GNUNET_SCHEDULER_add_delayed (sock->back_off, &client_delayed_retry, + GNUNET_SCHEDULER_add_delayed (client->back_off, &client_delayed_retry, th); } else { th->th = - GNUNET_CONNECTION_notify_transmit_ready (sock->sock, size, timeout, + GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, timeout, &client_notify, th); if (NULL == th->th) { GNUNET_break (0); GNUNET_free (th); - sock->th = NULL; + client->th = NULL; return NULL; } } @@ -1101,7 +1108,7 @@ void GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle *th) { - if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != th->reconnect_task) { GNUNET_assert (NULL == th->th); GNUNET_SCHEDULER_cancel (th->reconnect_task); @@ -1112,7 +1119,7 @@ GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle GNUNET_assert (NULL != th->th); GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th); } - th->sock->th = NULL; + th->client->th = NULL; GNUNET_free (th); } @@ -1134,14 +1141,12 @@ transmit_for_response (void *cls, size_t size, void *buf) struct TransmitGetResponseContext *tc = cls; uint16_t msize; - tc->sock->tag = NULL; + tc->client->tag = NULL; msize = ntohs (tc->hdr->size); if (NULL == buf) { -#if DEBUG_CLIENT LOG (GNUNET_ERROR_TYPE_DEBUG, _("Could not submit request, not expecting to receive a response.\n")); -#endif if (NULL != tc->rn) tc->rn (tc->rn_cls, NULL); GNUNET_free (tc); @@ -1149,7 +1154,7 @@ transmit_for_response (void *cls, size_t size, void *buf) } GNUNET_assert (size >= msize); memcpy (buf, tc->hdr, msize); - GNUNET_CLIENT_receive (tc->sock, tc->rn, tc->rn_cls, + GNUNET_CLIENT_receive (tc->client, tc->rn, tc->rn_cls, GNUNET_TIME_absolute_get_remaining (tc->timeout)); GNUNET_free (tc); return msize; @@ -1163,7 +1168,7 @@ transmit_for_response (void *cls, size_t size, void *buf) * will be called with a "NULL" response (in which * case the connection should probably be destroyed). * - * @param sock connection to use + * @param client connection to use * @param hdr message to transmit * @param timeout when to give up (for both transmission * and for waiting for a response) @@ -1178,7 +1183,7 @@ transmit_for_response (void *cls, size_t size, void *buf) * is already pending */ int -GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, +GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *client, const struct GNUNET_MessageHeader *hdr, struct GNUNET_TIME_Relative timeout, int auto_retry, @@ -1188,26 +1193,26 @@ GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, struct TransmitGetResponseContext *tc; uint16_t msize; - if (NULL != sock->th) + if (NULL != client->th) return GNUNET_SYSERR; - GNUNET_assert (sock->tag == NULL); + GNUNET_assert (NULL == client->tag); msize = ntohs (hdr->size); tc = GNUNET_malloc (sizeof (struct TransmitGetResponseContext) + msize); - tc->sock = sock; + tc->client = client; tc->hdr = (const struct GNUNET_MessageHeader *) &tc[1]; memcpy (&tc[1], hdr, msize); tc->timeout = GNUNET_TIME_relative_to_absolute (timeout); tc->rn = rn; tc->rn_cls = rn_cls; if (NULL == - GNUNET_CLIENT_notify_transmit_ready (sock, msize, timeout, auto_retry, + GNUNET_CLIENT_notify_transmit_ready (client, msize, timeout, auto_retry, &transmit_for_response, tc)) { GNUNET_break (0); GNUNET_free (tc); return GNUNET_SYSERR; } - sock->tag = tc; + client->tag = tc; return GNUNET_OK; } diff --git a/src/util/common_logging.c b/src/util/common_logging.c index e19aa8c..2c0fd57 100644 --- a/src/util/common_logging.c +++ b/src/util/common_logging.c @@ -530,6 +530,8 @@ parse_all_definitions () gnunet_force_log_parsed = GNUNET_YES; } #endif + + /** * Setup logging. * @@ -569,30 +571,29 @@ GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile) if (NULL == fn) return GNUNET_SYSERR; dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn)); - altlog_fd = OPEN (fn, O_APPEND | #if WINDOWS + altlog_fd = OPEN (fn, O_APPEND | O_BINARY | -#endif O_WRONLY | O_CREAT, -#if WINDOWS - _S_IREAD | _S_IWRITE + _S_IREAD | _S_IWRITE); #else - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH + altlog_fd = OPEN (fn, O_APPEND | + O_WRONLY | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); #endif - ); if (altlog_fd != -1) { int dup_return; if (GNUNET_stderr != NULL) fclose (GNUNET_stderr); dup_return = dup2 (altlog_fd, 2); - close (altlog_fd); + (void) close (altlog_fd); if (dup_return != -1) { altlog = fdopen (2, "ab"); if (altlog == NULL) { - close (2); + (void) close (2); altlog_fd = -1; } } diff --git a/src/util/configuration.c b/src/util/configuration.c index f24b2c2..308672f 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c @@ -21,7 +21,6 @@ /** * @file src/util/configuration.c * @brief configuration management - * * @author Christian Grothoff */ @@ -197,19 +196,19 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, for (i = strlen (line) - 1; (i >= 0) && (isspace ((unsigned char) line[i])); i--) line[i] = '\0'; - if (1 == sscanf (line, "@INLINE@ %191[^\n]", value)) + if (1 == SSCANF (line, "@INLINE@ %191[^\n]", value)) { /* @INLINE@ value */ if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value)) ret = GNUNET_SYSERR; /* failed to parse included config */ } - else if (1 == sscanf (line, "[%99[^]]]", value)) + else if (1 == SSCANF (line, "[%99[^]]]", value)) { /* [value] */ GNUNET_free (section); section = GNUNET_strdup (value); } - else if (2 == sscanf (line, " %63[^= ] = %191[^\n]", tag, value)) + else if (2 == SSCANF (line, " %63[^= ] = %191[^\n]", tag, value)) { /* tag = value */ /* Strip LF */ @@ -233,7 +232,7 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, } GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]); } - else if (1 == sscanf (line, " %63[^= ] =[^\n]", tag)) + else if (1 == SSCANF (line, " %63[^= ] =[^\n]", tag)) { /* tag = */ GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, ""); @@ -1228,13 +1227,41 @@ static int parse_configuration_file (void *cls, const char *filename) { struct GNUNET_CONFIGURATION_Handle *cfg = cls; + char * ext; int ret; + /* Examine file extension */ + ext = strrchr (filename, '.'); + if ((NULL == ext) || (0 != strcmp (ext, ".conf"))) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename); + return GNUNET_OK; + } + ret = GNUNET_CONFIGURATION_parse (cfg, filename); return ret; } +/** + * Load default configuration. This function will parse the + * defaults from the given defaults_d directory. + * + * @param cfg configuration to update + * @param defaults_d directory with the defaults + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, + const char *defaults_d) +{ + if (GNUNET_SYSERR == + GNUNET_DISK_directory_scan (defaults_d, &parse_configuration_file, cfg)) + return GNUNET_SYSERR; /* no configuration at all found */ + return GNUNET_OK; +} + + /** * Load configuration (starts with defaults, then loads * system-specific configuration). diff --git a/src/util/connection.c b/src/util/connection.c index 8224479..31e6399 100644 --- a/src/util/connection.c +++ b/src/util/connection.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) + (C) 2009, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -44,32 +44,6 @@ #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) -/** - * Possible functions to call after connect failed or succeeded. - */ -enum ConnectContinuations -{ - /** - * Call nothing. - */ - COCO_NONE = 0, - - /** - * Call "receive_again". - */ - COCO_RECEIVE_AGAIN = 1, - - /** - * Call "transmit_ready". - */ - COCO_TRANSMIT_READY = 2, - - /** - * Call "destroy_continuation". - */ - COCO_DESTROY_CONTINUATION = 4 -}; - /** * Transmission handle. There can only be one for each connection. @@ -89,9 +63,9 @@ struct GNUNET_CONNECTION_TransmitHandle void *notify_ready_cls; /** - * Our socket handle. + * Our connection handle. */ - struct GNUNET_CONNECTION_Handle *sh; + struct GNUNET_CONNECTION_Handle *connection; /** * Timeout for receiving (in absolute time). @@ -142,7 +116,7 @@ struct AddressProbe /** * Connection for which we are probing. */ - struct GNUNET_CONNECTION_Handle *h; + struct GNUNET_CONNECTION_Handle *connection; /** * Lenth of addr. @@ -150,14 +124,14 @@ struct AddressProbe socklen_t addrlen; /** - * Task waiting for the socket to finish connecting. + * Task waiting for the connection to finish connecting. */ GNUNET_SCHEDULER_TaskIdentifier task; }; /** - * @brief handle for a network socket + * @brief handle for a network connection */ struct GNUNET_CONNECTION_Handle { @@ -185,7 +159,7 @@ struct GNUNET_CONNECTION_Handle struct sockaddr *addr; /** - * Pointer to the hostname if socket was + * Pointer to the hostname if connection was * created using DNS lookup, otherwise NULL. */ char *hostname; @@ -242,11 +216,6 @@ struct GNUNET_CONNECTION_Handle */ GNUNET_SCHEDULER_TaskIdentifier write_task; - /** - * Destroy task (if already scheduled). - */ - GNUNET_SCHEDULER_TaskIdentifier destroy_task; - /** * Handle to a pending DNS lookup request. */ @@ -262,21 +231,11 @@ struct GNUNET_CONNECTION_Handle */ struct GNUNET_TIME_Absolute receive_timeout; - /** - * Functions to call after connect failed or succeeded. - */ - enum ConnectContinuations ccs; - /** * Maximum number of bytes to read (for receiving). */ size_t max; - /** - * Ignore GNUNET_SCHEDULER_REASON_SHUTDOWN for this socket. - */ - int ignore_shutdown; - /** * Port to connect to. */ @@ -292,73 +251,75 @@ struct GNUNET_CONNECTION_Handle }; + /** * Set the persist option on this connection handle. Indicates * that the underlying socket or fd should never really be closed. * Used for indicating process death. * - * @param sock the connection to set persistent + * @param connection the connection to set persistent */ void -GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *sock) +GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection) { - sock->persist = GNUNET_YES; + connection->persist = GNUNET_YES; } /** - * Disable the "CORK" feature for communication with the given socket, + * Disable the "CORK" feature for communication with the given connection, * forcing the OS to immediately flush the buffer on transmission * instead of potentially buffering multiple messages. Essentially * reduces the OS send buffers to zero. * Used to make sure that the last messages sent through the connection * reach the other side before the process is terminated. * - * @param sock the connection to make flushing and blocking + * @param connection the connection to make flushing and blocking * @return GNUNET_OK on success */ int -GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock) +GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection) { - return GNUNET_NETWORK_socket_disable_corking (sock->sock); + return GNUNET_NETWORK_socket_disable_corking (connection->sock); } + /** - * Create a socket handle by boxing an existing OS socket. The OS + * Create a connection handle by boxing an existing OS socket. The OS * socket should henceforth be no longer used directly. - * GNUNET_socket_destroy will close it. + * GNUNET_connection_destroy will close it. * * @param osSocket existing socket to box - * @return the boxed socket handle + * @return the boxed connection handle */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket) { - struct GNUNET_CONNECTION_Handle *ret; + struct GNUNET_CONNECTION_Handle *connection; - ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); - ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; - ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); - ret->sock = osSocket; - return ret; + connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); + connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; + connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); + connection->sock = osSocket; + return connection; } /** - * Create a socket handle by accepting on a listen socket. This + * Create a connection handle by accepting on a listen socket. This * function may block if the listen socket has no connection ready. * * @param access function to use to check if access is allowed * @param access_cls closure for access * @param lsock listen socket - * @return the socket handle, NULL on error + * @return the connection handle, NULL on error */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, void *access_cls, struct GNUNET_NETWORK_Handle *lsock) { - struct GNUNET_CONNECTION_Handle *ret; + struct GNUNET_CONNECTION_Handle *connection; char addr[128]; socklen_t addrlen; struct GNUNET_NETWORK_Handle *sock; @@ -369,7 +330,6 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, void *uaddr; struct GNUNET_CONNECTION_Credentials *gcp; struct GNUNET_CONNECTION_Credentials gc; - #ifdef SO_PEERCRED struct ucred uc; socklen_t olen; @@ -392,7 +352,7 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, sa = (struct sockaddr *) addr; v6 = (struct sockaddr_in6 *) addr; - if ((sa->sa_family == AF_INET6) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr))) + if ((AF_INET6 == sa->sa_family) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr))) { /* convert to V4 address */ v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); @@ -417,7 +377,7 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, gcp = NULL; gc.uid = 0; gc.gid = 0; - if (sa->sa_family == AF_UNIX) + if (AF_UNIX == sa->sa_family) { #if HAVE_GETPEEREID /* most BSDs */ @@ -453,10 +413,10 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, #endif } - if ((access != NULL) && + if ((NULL != access) && (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen)))) { - if (aret == GNUNET_NO) + if (GNUNET_NO == aret) LOG (GNUNET_ERROR_TYPE_INFO, _("Access denied to `%s'\n"), GNUNET_a2s (uaddr, addrlen)); GNUNET_break (GNUNET_OK == @@ -465,147 +425,151 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, GNUNET_free (uaddr); return NULL; } - ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); - ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; - ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); - ret->addr = uaddr; - ret->addrlen = addrlen; - ret->sock = sock; + connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); + connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; + connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); + connection->addr = uaddr; + connection->addrlen = addrlen; + connection->sock = sock; LOG (GNUNET_ERROR_TYPE_INFO, _("Accepting connection from `%s': %p\n"), - GNUNET_a2s (uaddr, addrlen), ret); - return ret; + GNUNET_a2s (uaddr, addrlen), connection); + return connection; } + /** * Obtain the network address of the other party. * - * @param sock the client to get the address for + * @param connection the client to get the address for * @param addr where to store the address * @param addrlen where to store the length of the address * @return GNUNET_OK on success */ int -GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *sock, +GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection, void **addr, size_t * addrlen) { - if ((sock->addr == NULL) || (sock->addrlen == 0)) + if ((NULL == connection->addr) || (0 == connection->addrlen)) return GNUNET_NO; - *addr = GNUNET_malloc (sock->addrlen); - memcpy (*addr, sock->addr, sock->addrlen); - *addrlen = sock->addrlen; + *addr = GNUNET_malloc (connection->addrlen); + memcpy (*addr, connection->addr, connection->addrlen); + *addrlen = connection->addrlen; return GNUNET_OK; } /** - * This function is called after establishing a connection either has - * succeeded or timed out. Note that it is possible that the attempt - * timed out and that we're immediately retrying. If we are retrying, - * we need to wait again (or timeout); if we succeeded, we need to - * wait for data (or timeout). + * Tell the receiver callback that we had an IO error. * - * @param cls our connection handle - * @param tc task context describing why we are here + * @param connection connection to signal error + * @param errcode error code to send */ static void -receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); +signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, int errcode) +{ + GNUNET_CONNECTION_Receiver receiver; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Receive encounters error (%s), connection closed (%p)\n", + STRERROR (errcode), + connection); + GNUNET_assert (NULL != (receiver = connection->receiver)); + connection->receiver = NULL; + receiver (connection->receiver_cls, NULL, 0, connection->addr, connection->addrlen, errcode); +} /** - * Scheduler let us know that the connect task is finished (or was - * cancelled due to shutdown). Now really clean up. + * Tell the receiver callback that a timeout was reached. * - * @param cls our "struct GNUNET_CONNECTION_Handle *" - * @param tc unused + * @param connection connection to signal for + */ +static void +signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection) +{ + GNUNET_CONNECTION_Receiver receiver; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection signals timeout to receiver (%p)!\n", + connection); + GNUNET_assert (NULL != (receiver = connection->receiver)); + connection->receiver = NULL; + receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0); +} + + +/** + * We failed to transmit data to the service, signal the error. + * + * @param connection handle that had trouble + * @param ecode error code (errno) */ static void -destroy_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection, + int ecode) { - struct GNUNET_CONNECTION_Handle *sock = cls; GNUNET_CONNECTION_TransmitReadyNotify notify; - struct AddressProbe *pos; - sock->destroy_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_assert (sock->dns_active == NULL); - if (0 != (sock->ccs & COCO_TRANSMIT_READY)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy waits for CCS-TR to be done (%p)\n", - sock); - sock->ccs |= COCO_DESTROY_CONTINUATION; - return; - } - if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Destroy waits for write_task to be done (%p)\n", sock); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); - sock->destroy_task = - GNUNET_SCHEDULER_add_after (sock->write_task, &destroy_continuation, - sock); - return; - } - if (0 != (sock->ccs & COCO_RECEIVE_AGAIN)) - { - sock->ccs |= COCO_DESTROY_CONTINUATION; - return; - } - if (sock->sock != NULL) + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Transmission encounterd error (%s), connection closed (%p)\n", + STRERROR (ecode), + connection); + if (NULL != connection->sock) { - LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down socket (%p)\n", sock); - if (sock->persist != GNUNET_YES) - { - if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR)) - && (errno != ENOTCONN) && (errno != ECONNRESET)) - LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown"); - } + GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR); + GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock)); + connection->sock = NULL; + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task); } - if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != connection->read_task) { - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); - sock->destroy_task = - GNUNET_SCHEDULER_add_after (sock->read_task, &destroy_continuation, - sock); + /* send errors trigger read errors... */ + GNUNET_SCHEDULER_cancel (connection->read_task); + connection->read_task = GNUNET_SCHEDULER_NO_TASK; + signal_receive_timeout (connection); return; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroy actually runs (%p)!\n", sock); - while (NULL != (pos = sock->ap_head)) - { - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); - GNUNET_SCHEDULER_cancel (pos->task); - GNUNET_CONTAINER_DLL_remove (sock->ap_head, sock->ap_tail, pos); - GNUNET_free (pos); - } - GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); - GNUNET_assert (sock->ccs == COCO_NONE); - if (NULL != (notify = sock->nth.notify_ready)) - { - sock->nth.notify_ready = NULL; - notify (sock->nth.notify_ready_cls, 0, NULL); - } + if (NULL == connection->nth.notify_ready) + return; /* nobody to tell about it */ + notify = connection->nth.notify_ready; + connection->nth.notify_ready = NULL; + notify (connection->nth.notify_ready_cls, 0, NULL); +} - if (sock->sock != NULL) + +/** + * We've failed for good to establish a connection (timeout or + * no more addresses to try). + * + * @param connection the connection we tried to establish + */ +static void +connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection) +{ + LOG (GNUNET_ERROR_TYPE_INFO, + _("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"), + connection->hostname, connection->port); + GNUNET_break (NULL == connection->ap_head); + GNUNET_break (NULL == connection->ap_tail); + GNUNET_break (GNUNET_NO == connection->dns_active); + GNUNET_break (NULL == connection->sock); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task); + + /* signal errors for jobs that used to wait on the connection */ + if (NULL != connection->receiver) + signal_receive_error (connection, ECONNREFUSED); + if (NULL != connection->nth.notify_ready) { - if (sock->persist != GNUNET_YES) - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); - else - GNUNET_free (sock->sock); /* at least no memory leak (we deliberately - * leak the socket in this special case) ... */ + GNUNET_assert (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); + GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); + connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; + signal_transmit_error (connection, ECONNREFUSED); } - GNUNET_free_non_null (sock->addr); - GNUNET_free_non_null (sock->hostname); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Freeing memory of connection %p.\n", sock); - GNUNET_free (sock->write_buffer); - GNUNET_free (sock); } - /** - * See if we are now connected. If not, wait longer for - * connect to succeed. If connected, we should be able - * to write now as well, unless we timed out. + * We are ready to transmit (or got a timeout). * * @param cls our connection handle * @param tc task context describing why we are here @@ -615,98 +579,52 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** - * We've failed for good to establish a connection. + * This function is called once we either timeout or have data ready + * to read. * - * @param h the connection we tried to establish + * @param cls connection to read from + * @param tc scheduler context */ static void -connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h) -{ - LOG ((0 != - strncmp (h->hostname, "localhost:", - 10)) ? GNUNET_ERROR_TYPE_INFO : GNUNET_ERROR_TYPE_WARNING, - _ - ("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"), - h->hostname, h->port); - /* connect failed / timed out */ - GNUNET_break (h->ap_head == NULL); - GNUNET_break (h->ap_tail == NULL); - GNUNET_break (h->dns_active == GNUNET_NO); - GNUNET_break (h->sock == NULL); - - /* trigger jobs that used to wait on "connect_task" */ - if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "connect_fail_continuation triggers receive_again (%p)\n", h); - h->ccs -= COCO_RECEIVE_AGAIN; - h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); - } - if (0 != (h->ccs & COCO_TRANSMIT_READY)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "connect_fail_continuation cancels timeout_task, triggers transmit_ready (%p)\n", - h); - GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); - GNUNET_SCHEDULER_cancel (h->nth.timeout_task); - h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; - h->ccs -= COCO_TRANSMIT_READY; - GNUNET_assert (h->nth.notify_ready != NULL); - GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); - h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h); - } - if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "connect_fail_continuation runs destroy_continuation (%p)\n", h); - h->ccs -= COCO_DESTROY_CONTINUATION; - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); - h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h); - } -} +receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** * We've succeeded in establishing a connection. * - * @param h the connection we tried to establish + * @param connection the connection we tried to establish */ static void -connect_success_continuation (struct GNUNET_CONNECTION_Handle *h) +connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection) { - LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection to `%s' succeeded! (%p)\n", - GNUNET_a2s (h->addr, h->addrlen), h); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Connection to `%s' succeeded! (%p)\n", + GNUNET_a2s (connection->addr, connection->addrlen), connection); /* trigger jobs that waited for the connection */ - if (0 != (h->ccs & COCO_RECEIVE_AGAIN)) + if (NULL != connection->receiver) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "connect_success_continuation runs receive_again (%p)\n", h); - h->ccs -= COCO_RECEIVE_AGAIN; - h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h); + "Connection succeeded, starting with receiving data (%p)\n", + connection); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->read_task); + connection->read_task = + GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining + (connection->receive_timeout), connection->sock, + &receive_ready, connection); } - if (0 != (h->ccs & COCO_TRANSMIT_READY)) + if (NULL != connection->nth.notify_ready) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "connect_success_continuation runs transmit_ready, cancels timeout_task (%p)\n", - h); - GNUNET_assert (h->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); - GNUNET_SCHEDULER_cancel (h->nth.timeout_task); - h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; - h->ccs -= COCO_TRANSMIT_READY; - GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK); - GNUNET_assert (h->nth.notify_ready != NULL); - h->write_task = + "Connection succeeded, starting with sending data (%p)\n", + connection); + GNUNET_assert (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); + GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); + connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_assert (connection->write_task == GNUNET_SCHEDULER_NO_TASK); + connection->write_task = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining - (h->nth.transmit_timeout), h->sock, - &transmit_ready, h); - } - if (0 != (h->ccs & COCO_DESTROY_CONTINUATION)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "connect_success_continuation runs destroy_continuation (%p)\n", h); - h->ccs -= COCO_DESTROY_CONTINUATION; - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->destroy_task); - h->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, h); + (connection->nth.transmit_timeout), connection->sock, + &transmit_ready, connection); } } @@ -723,48 +641,48 @@ connect_probe_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct AddressProbe *ap = cls; - struct GNUNET_CONNECTION_Handle *h = ap->h; + struct GNUNET_CONNECTION_Handle *connection = ap->connection; struct AddressProbe *pos; int error; socklen_t len; - GNUNET_assert (ap->sock != NULL); - GNUNET_CONTAINER_DLL_remove (h->ap_head, h->ap_tail, ap); + GNUNET_assert (NULL != ap->sock); + GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, ap); len = sizeof (error); errno = 0; error = 0; if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || (GNUNET_OK != GNUNET_NETWORK_socket_getsockopt (ap->sock, SOL_SOCKET, SO_ERROR, &error, - &len)) || (error != 0)) + &len)) || (0 != error)) { GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); GNUNET_free (ap); - if ((NULL == h->ap_head) && (h->dns_active == GNUNET_NO)) - connect_fail_continuation (h); + if ((NULL == connection->ap_head) && (GNUNET_NO == connection->dns_active)) + connect_fail_continuation (connection); return; } - GNUNET_assert (h->sock == NULL); - h->sock = ap->sock; - GNUNET_assert (h->addr == NULL); - h->addr = GNUNET_malloc (ap->addrlen); - memcpy (h->addr, ap->addr, ap->addrlen); - h->addrlen = ap->addrlen; + GNUNET_assert (NULL == connection->sock); + connection->sock = ap->sock; + GNUNET_assert (NULL == connection->addr); + connection->addr = GNUNET_malloc (ap->addrlen); + memcpy (connection->addr, ap->addr, ap->addrlen); + connection->addrlen = ap->addrlen; GNUNET_free (ap); /* cancel all other attempts */ - while (NULL != (pos = h->ap_head)) + while (NULL != (pos = connection->ap_head)) { GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); GNUNET_SCHEDULER_cancel (pos->task); - GNUNET_CONTAINER_DLL_remove (h->ap_head, h->ap_tail, pos); + GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, pos); GNUNET_free (pos); } - connect_success_continuation (h); + connect_success_continuation (connection); } /** - * Try to establish a socket connection given the specified address. + * Try to establish a connection given the specified address. * This function is called by the resolver once we have a DNS reply. * * @param cls our "struct GNUNET_CONNECTION_Handle *" @@ -775,37 +693,37 @@ static void try_connect_using_address (void *cls, const struct sockaddr *addr, socklen_t addrlen) { - struct GNUNET_CONNECTION_Handle *h = cls; + struct GNUNET_CONNECTION_Handle *connection = cls; struct AddressProbe *ap; struct GNUNET_TIME_Relative delay; - if (addr == NULL) + if (NULL == addr) { - h->dns_active = NULL; - if ((NULL == h->ap_head) && (NULL == h->sock)) - connect_fail_continuation (h); + connection->dns_active = NULL; + if ((NULL == connection->ap_head) && (NULL == connection->sock)) + connect_fail_continuation (connection); return; } - if (h->sock != NULL) + if (NULL != connection->sock) return; /* already connected */ - GNUNET_assert (h->addr == NULL); + GNUNET_assert (NULL == connection->addr); /* try to connect */ LOG (GNUNET_ERROR_TYPE_DEBUG, - "Trying to connect using address `%s:%u/%s:%u'\n", h->hostname, h->port, - GNUNET_a2s (addr, addrlen), h->port); + "Trying to connect using address `%s:%u/%s:%u'\n", connection->hostname, connection->port, + GNUNET_a2s (addr, addrlen), connection->port); ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen); ap->addr = (const struct sockaddr *) &ap[1]; memcpy (&ap[1], addr, addrlen); ap->addrlen = addrlen; - ap->h = h; + ap->connection = connection; switch (ap->addr->sa_family) { case AF_INET: - ((struct sockaddr_in *) ap->addr)->sin_port = htons (h->port); + ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port); break; case AF_INET6: - ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (h->port); + ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port); break; default: GNUNET_break (0); @@ -813,39 +731,39 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, return; /* not supported by us */ } ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0); - if (ap->sock == NULL) + if (NULL == ap->sock) { GNUNET_free (ap); return; /* not supported by OS */ } LOG (GNUNET_ERROR_TYPE_INFO, _("Trying to connect to `%s' (%p)\n"), - GNUNET_a2s (ap->addr, ap->addrlen), h); + GNUNET_a2s (ap->addr, ap->addrlen), connection); if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (ap->sock, ap->addr, ap->addrlen)) && - (errno != EINPROGRESS)) + (EINPROGRESS != errno)) { /* maybe refused / unsupported address, try next */ LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); #if 0 LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to connect to `%s' (%p)\n"), - GNUNET_a2s (ap->addr, ap->addrlen), h); + GNUNET_a2s (ap->addr, ap->addrlen), connection); #endif GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); GNUNET_free (ap); return; } - GNUNET_CONTAINER_DLL_insert (h->ap_head, h->ap_tail, ap); + GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap); delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT; - if (h->nth.notify_ready != NULL) + if (NULL != connection->nth.notify_ready) delay = GNUNET_TIME_relative_min (delay, - GNUNET_TIME_absolute_get_remaining (h-> + GNUNET_TIME_absolute_get_remaining (connection-> nth.transmit_timeout)); - if (h->receiver != NULL) + if (NULL != connection->receiver) delay = GNUNET_TIME_relative_min (delay, GNUNET_TIME_absolute_get_remaining - (h->receive_timeout)); + (connection->receive_timeout)); ap->task = GNUNET_SCHEDULER_add_write_net (delay, ap->sock, &connect_probe_continuation, ap); @@ -853,45 +771,45 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, /** - * Create a socket handle by (asynchronously) connecting to a host. + * Create a connection handle by (asynchronously) connecting to a host. * This function returns immediately, even if the connection has not * yet been established. This function only creates TCP connections. * * @param cfg configuration to use * @param hostname name of the host to connect to * @param port port to connect to - * @return the socket handle + * @return the connection handle */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *hostname, uint16_t port) { - struct GNUNET_CONNECTION_Handle *ret; + struct GNUNET_CONNECTION_Handle *connection; GNUNET_assert (0 < strlen (hostname)); /* sanity check */ - ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); - ret->cfg = cfg; - ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; - ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); - ret->port = port; - ret->hostname = GNUNET_strdup (hostname); - ret->dns_active = - GNUNET_RESOLVER_ip_get (ret->hostname, AF_UNSPEC, + connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); + connection->cfg = cfg; + connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; + connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); + connection->port = port; + connection->hostname = GNUNET_strdup (hostname); + connection->dns_active = + GNUNET_RESOLVER_ip_get (connection->hostname, AF_UNSPEC, GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, - &try_connect_using_address, ret); - return ret; + &try_connect_using_address, connection); + return connection; } /** - * Create a socket handle by connecting to a UNIX domain service. + * Create a connection handle by connecting to a UNIX domain service. * This function returns immediately, even if the connection has not * yet been established. This function only creates UNIX connections. * * @param cfg configuration to use * @param unixpath path to connect to - * @return the socket handle, NULL on systems without UNIX support + * @return the connection handle, NULL on systems without UNIX support */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct @@ -899,7 +817,7 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct *cfg, const char *unixpath) { #ifdef AF_UNIX - struct GNUNET_CONNECTION_Handle *ret; + struct GNUNET_CONNECTION_Handle *connection; struct sockaddr_un *un; size_t slen; @@ -918,32 +836,32 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct #if LINUX un->sun_path[0] = '\0'; #endif - ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); - ret->cfg = cfg; - ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; - ret->write_buffer = GNUNET_malloc (ret->write_buffer_size); - ret->port = 0; - ret->hostname = NULL; - ret->addr = (struct sockaddr *) un; - ret->addrlen = slen; - ret->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); - if (NULL == ret->sock) + connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); + connection->cfg = cfg; + connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; + connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); + connection->port = 0; + connection->hostname = NULL; + connection->addr = (struct sockaddr *) un; + connection->addrlen = slen; + connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); + if (NULL == connection->sock) { - GNUNET_free (ret->addr); - GNUNET_free (ret->write_buffer); - GNUNET_free (ret); + GNUNET_free (connection->addr); + GNUNET_free (connection->write_buffer); + GNUNET_free (connection); return NULL; } if (GNUNET_OK != - GNUNET_NETWORK_socket_connect (ret->sock, ret->addr, ret->addrlen)) + GNUNET_NETWORK_socket_connect (connection->sock, connection->addr, connection->addrlen)) { /* Just return; we expect everything to work eventually so don't fail HARD */ - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret->sock)); - ret->sock = NULL; - return ret; + GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock)); + connection->sock = NULL; + return connection; } - connect_success_continuation (ret); - return ret; + connect_success_continuation (connection); + return connection; #else return NULL; #endif @@ -951,14 +869,14 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct /** - * Create a socket handle by (asynchronously) connecting to a host. + * Create a connection handle by (asynchronously) connecting to a host. * This function returns immediately, even if the connection has not * yet been established. This function only creates TCP connections. * * @param af_family address family to use * @param serv_addr server address * @param addrlen length of server address - * @return the socket handle + * @return the connection handle */ struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_sockaddr (int af_family, @@ -966,17 +884,16 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family, socklen_t addrlen) { struct GNUNET_NETWORK_Handle *s; - struct GNUNET_CONNECTION_Handle *ret; - + struct GNUNET_CONNECTION_Handle *connection; s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0); - if (s == NULL) + if (NULL == s) { LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, "socket"); return NULL; } if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && - (errno != EINPROGRESS)) + (EINPROGRESS != errno)) { /* maybe refused / unsupported address, try next */ LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); @@ -985,293 +902,221 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family, GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); return NULL; } - ret = GNUNET_CONNECTION_create_from_existing (s); - ret->addr = GNUNET_malloc (addrlen); - memcpy (ret->addr, serv_addr, addrlen); - ret->addrlen = addrlen; + connection = GNUNET_CONNECTION_create_from_existing (s); + connection->addr = GNUNET_malloc (addrlen); + memcpy (connection->addr, serv_addr, addrlen); + connection->addrlen = addrlen; LOG (GNUNET_ERROR_TYPE_INFO, _("Trying to connect to `%s' (%p)\n"), - GNUNET_a2s (serv_addr, addrlen), ret); - return ret; + GNUNET_a2s (serv_addr, addrlen), connection); + return connection; } /** - * Check if socket is valid (no fatal errors have happened so far). - * Note that a socket that is still trying to connect is considered + * Check if connection is valid (no fatal errors have happened so far). + * Note that a connection that is still trying to connect is considered * valid. * - * @param sock socket to check + * @param connection connection to check * @return GNUNET_YES if valid, GNUNET_NO otherwise */ int -GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *sock) +GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection) { - if ((sock->ap_head != NULL) || (sock->dns_active != NULL)) + if ((NULL != connection->ap_head) || (NULL != connection->dns_active)) return GNUNET_YES; /* still trying to connect */ - return (sock->sock == NULL) ? GNUNET_NO : GNUNET_YES; + return (NULL == connection->sock) ? GNUNET_NO : GNUNET_YES; } /** - * Close the socket and free associated resources. Pending - * transmissions may be completed or dropped depending on the - * arguments. If a receive call is pending and should - * NOT be completed, 'GNUNET_CONNECTION_receive_cancel' - * should be called explicitly first. + * Close the connection and free associated resources. There must + * not be any pending requests for reading or writing to the + * connection at this time. * - * @param sock socket to destroy - * @param finish_pending_write should pending writes be completed or aborted? - * (this applies to transmissions where the data has already been - * read from the application; all other transmissions should be - * aborted using 'GNUNET_CONNECTION_notify_transmit_ready_cancel'). + * @param connection connection to destroy */ void -GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *sock, - int finish_pending_write) +GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection) { - if (GNUNET_NO == finish_pending_write) + struct AddressProbe *pos; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection); + GNUNET_assert (NULL == connection->nth.notify_ready); + GNUNET_assert (NULL == connection->receiver); + if (GNUNET_SCHEDULER_NO_TASK != connection->write_task) { - if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (sock->write_task); - sock->write_task = GNUNET_SCHEDULER_NO_TASK; - sock->write_buffer_off = 0; - } - sock->nth.notify_ready = NULL; + GNUNET_SCHEDULER_cancel (connection->write_task); + connection->write_task = GNUNET_SCHEDULER_NO_TASK; + connection->write_buffer_off = 0; } - if ((sock->write_buffer_off == 0) && (sock->dns_active != NULL)) + if (GNUNET_SCHEDULER_NO_TASK != connection->read_task) { - GNUNET_RESOLVER_request_cancel (sock->dns_active); - sock->dns_active = NULL; + GNUNET_SCHEDULER_cancel (connection->read_task); + connection->read_task = GNUNET_SCHEDULER_NO_TASK; } - - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->destroy_task); - sock->destroy_task = GNUNET_SCHEDULER_add_now (&destroy_continuation, sock); -} - - -/** - * Tell the receiver callback that a timeout was reached. - */ -static void -signal_timeout (struct GNUNET_CONNECTION_Handle *sh) -{ - GNUNET_CONNECTION_Receiver receiver; - - LOG (GNUNET_ERROR_TYPE_DEBUG, "Network signals time out to receiver (%p)!\n", - sh); - GNUNET_assert (NULL != (receiver = sh->receiver)); - sh->receiver = NULL; - receiver (sh->receiver_cls, NULL, 0, NULL, 0, 0); -} - - -/** - * Tell the receiver callback that we had an IO error. - */ -static void -signal_error (struct GNUNET_CONNECTION_Handle *sh, int errcode) -{ - GNUNET_CONNECTION_Receiver receiver; - - GNUNET_assert (NULL != (receiver = sh->receiver)); - sh->receiver = NULL; - receiver (sh->receiver_cls, NULL, 0, sh->addr, sh->addrlen, errcode); + if (GNUNET_SCHEDULER_NO_TASK != connection->nth.timeout_task) + { + GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); + connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + connection->nth.notify_ready = NULL; + if (NULL != connection->dns_active) + { + GNUNET_RESOLVER_request_cancel (connection->dns_active); + connection->dns_active = NULL; + } + while (NULL != (pos = connection->ap_head)) + { + GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); + GNUNET_SCHEDULER_cancel (pos->task); + GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, pos); + GNUNET_free (pos); + } + if ( (NULL != connection->sock) && + (GNUNET_YES != connection->persist) ) + { + if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR)) && + (ENOTCONN != errno) && + (ECONNRESET != errno) ) + LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown"); + } + if (NULL != connection->sock) + { + if (GNUNET_YES != connection->persist) + GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock)); + else + GNUNET_free (connection->sock); /* at least no memory leak (we deliberately + * leak the socket in this special case) ... */ + } + GNUNET_free_non_null (connection->addr); + GNUNET_free_non_null (connection->hostname); + GNUNET_free (connection->write_buffer); + GNUNET_free (connection); } /** * This function is called once we either timeout * or have data ready to read. + * + * @param cls connection to read from + * @param tc scheduler context */ static void receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_CONNECTION_Handle *sh = cls; - struct GNUNET_TIME_Absolute now; - char buffer[sh->max]; + struct GNUNET_CONNECTION_Handle *connection = cls; + char buffer[connection->max]; ssize_t ret; GNUNET_CONNECTION_Receiver receiver; - sh->read_task = GNUNET_SCHEDULER_NO_TASK; - if ((GNUNET_YES == sh->ignore_shutdown) && - (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) + connection->read_task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { /* ignore shutdown request, go again immediately */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Ignoring shutdown signal per configuration\n"); - sh->read_task = + connection->read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining - (sh->receive_timeout), sh->sock, - &receive_ready, sh); + (connection->receive_timeout), connection->sock, + &receive_ready, connection); return; } - now = GNUNET_TIME_absolute_get (); - if ((now.abs_value > sh->receive_timeout.abs_value) || - (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) || - (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { - if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Receive from `%s' encounters error: time out by %llums... (%p)\n", - GNUNET_a2s (sh->addr, sh->addrlen), - GNUNET_TIME_absolute_get_duration (sh->receive_timeout).rel_value, - sh); - signal_timeout (sh); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Receive from `%s' encounters error: timeout (%p)\n", + GNUNET_a2s (connection->addr, connection->addrlen), + GNUNET_TIME_absolute_get_duration (connection->receive_timeout).rel_value, + connection); + signal_receive_timeout (connection); return; } - if (sh->sock == NULL) + if (NULL == connection->sock) { /* connect failed for good */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Receive encounters error, socket closed... (%p)\n", sh); - signal_error (sh, ECONNREFUSED); + signal_receive_error (connection, ECONNREFUSED); return; } - GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, sh->sock)); + GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, connection->sock)); RETRY: - ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max); - if (ret == -1) + ret = GNUNET_NETWORK_socket_recv (connection->sock, buffer, connection->max); + if (-1 == ret) { - if (errno == EINTR) + if (EINTR == errno) goto RETRY; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Error receiving: %s\n", STRERROR (errno)); - signal_error (sh, errno); + signal_receive_error (connection, errno); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "receive_ready read %u/%u bytes from `%s' (%p)!\n", (unsigned int) ret, - sh->max, GNUNET_a2s (sh->addr, sh->addrlen), sh); - GNUNET_assert (NULL != (receiver = sh->receiver)); - sh->receiver = NULL; - receiver (sh->receiver_cls, buffer, ret, sh->addr, sh->addrlen, 0); + connection->max, GNUNET_a2s (connection->addr, connection->addrlen), connection); + GNUNET_assert (NULL != (receiver = connection->receiver)); + connection->receiver = NULL; + receiver (connection->receiver_cls, buffer, ret, connection->addr, connection->addrlen, 0); } /** - * This function is called after establishing a connection either has - * succeeded or timed out. Note that it is possible that the attempt - * timed out and that we're immediately retrying. If we are retrying, - * we need to wait again (or timeout); if we succeeded, we need to - * wait for data (or timeout). - * - * @param cls our connection handle - * @param tc task context describing why we are here - */ -static void -receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_CONNECTION_Handle *sh = cls; - struct GNUNET_TIME_Absolute now; - - sh->read_task = GNUNET_SCHEDULER_NO_TASK; - if (sh->sock == NULL) - { - /* not connected and no longer trying */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Receive encounters error, socket closed (%p)...\n", sh); - signal_error (sh, ECONNREFUSED); - return; - } - now = GNUNET_TIME_absolute_get (); - if ((now.abs_value > sh->receive_timeout.abs_value) || - (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Receive encounters error: time out (%p)...\n", sh); - signal_timeout (sh); - return; - } - GNUNET_assert (sh->sock != NULL); - /* connect succeeded, wait for data! */ - sh->read_task = - GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining - (sh->receive_timeout), sh->sock, - &receive_ready, sh); -} - - -/** - * Receive data from the given socket. Note that this function will + * Receive data from the given connection. Note that this function will * call "receiver" asynchronously using the scheduler. It will * "immediately" return. Note that there MUST only be one active - * receive call per socket at any given point in time (so do not + * receive call per connection at any given point in time (so do not * call receive again until the receiver callback has been invoked). * - * @param sock socket handle + * @param connection connection handle * @param max maximum number of bytes to read - * @param timeout maximum amount of time to wait (use -1 for "forever") + * @param timeout maximum amount of time to wait * @param receiver function to call with received data * @param receiver_cls closure for receiver */ void -GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *sock, size_t max, +GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t max, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_Receiver receiver, void *receiver_cls) { - struct GNUNET_SCHEDULER_TaskContext tc; - - GNUNET_assert ((sock->read_task == GNUNET_SCHEDULER_NO_TASK) && - (0 == (sock->ccs & COCO_RECEIVE_AGAIN)) && - (sock->receiver == NULL)); - sock->receiver = receiver; - sock->receiver_cls = receiver_cls; - sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); - sock->max = max; - if (sock->sock != NULL) + GNUNET_assert ((GNUNET_SCHEDULER_NO_TASK == connection->read_task) && + (NULL == connection->receiver)); + GNUNET_assert (NULL != receiver); + connection->receiver = receiver; + connection->receiver_cls = receiver_cls; + connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); + connection->max = max; + if (NULL != connection->sock) { - memset (&tc, 0, sizeof (tc)); - tc.reason = GNUNET_SCHEDULER_REASON_PREREQ_DONE; - receive_again (sock, &tc); + connection->read_task = + GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining + (connection->receive_timeout), connection->sock, + &receive_ready, connection); return; } - if ((sock->dns_active == NULL) && (sock->ap_head == NULL)) + if ((NULL == connection->dns_active) && (NULL == connection->ap_head)) { + connection->receiver = NULL; receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT); return; } - sock->ccs += COCO_RECEIVE_AGAIN; -} - - -/** - * Configure this connection to ignore shutdown signals. - * - * @param sock socket handle - * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default - */ -void -GNUNET_CONNECTION_ignore_shutdown (struct GNUNET_CONNECTION_Handle *sock, - int do_ignore) -{ - sock->ignore_shutdown = do_ignore; } /** - * Cancel receive job on the given socket. Note that the + * Cancel receive job on the given connection. Note that the * receiver callback must not have been called yet in order * for the cancellation to be valid. * - * @param sock socket handle + * @param connection connection handle * @return closure of the original receiver callback closure */ void * -GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock) +GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection) { - if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_assert (sock == GNUNET_SCHEDULER_cancel (sock->read_task)); - sock->read_task = GNUNET_SCHEDULER_NO_TASK; - } - else + if (GNUNET_SCHEDULER_NO_TASK != connection->read_task) { - GNUNET_assert (0 != (sock->ccs & COCO_RECEIVE_AGAIN)); - sock->ccs -= COCO_RECEIVE_AGAIN; + GNUNET_assert (connection == GNUNET_SCHEDULER_cancel (connection->read_task)); + connection->read_task = GNUNET_SCHEDULER_NO_TASK; } - sock->receiver = NULL; - return sock->receiver_cls; + connection->receiver = NULL; + return connection->receiver_cls; } @@ -1279,41 +1124,42 @@ GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *sock) * Try to call the transmit notify method (check if we do * have enough space available first)! * - * @param sock socket for which we should do this processing + * @param connection connection for which we should do this processing * @return GNUNET_YES if we were able to call notify */ static int -process_notify (struct GNUNET_CONNECTION_Handle *sock) +process_notify (struct GNUNET_CONNECTION_Handle *connection) { size_t used; size_t avail; size_t size; GNUNET_CONNECTION_TransmitReadyNotify notify; - GNUNET_assert (sock->write_task == GNUNET_SCHEDULER_NO_TASK); - if (NULL == (notify = sock->nth.notify_ready)) + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task); + if (NULL == (notify = connection->nth.notify_ready)) return GNUNET_NO; - used = sock->write_buffer_off - sock->write_buffer_pos; - avail = sock->write_buffer_size - used; - size = sock->nth.notify_size; + used = connection->write_buffer_off - connection->write_buffer_pos; + avail = connection->write_buffer_size - used; + size = connection->nth.notify_size; if (size > avail) return GNUNET_NO; - sock->nth.notify_ready = NULL; - if (sock->write_buffer_size - sock->write_buffer_off < size) + connection->nth.notify_ready = NULL; + if (connection->write_buffer_size - connection->write_buffer_off < size) { /* need to compact */ - memmove (sock->write_buffer, &sock->write_buffer[sock->write_buffer_pos], + memmove (connection->write_buffer, &connection->write_buffer[connection->write_buffer_pos], used); - sock->write_buffer_off -= sock->write_buffer_pos; - sock->write_buffer_pos = 0; + connection->write_buffer_off -= connection->write_buffer_pos; + connection->write_buffer_pos = 0; } - avail = sock->write_buffer_size - sock->write_buffer_off; + avail = connection->write_buffer_size - connection->write_buffer_off; GNUNET_assert (avail >= size); size = - notify (sock->nth.notify_ready_cls, avail, - &sock->write_buffer[sock->write_buffer_off]); + notify (connection->nth.notify_ready_cls, avail, + &connection->write_buffer[connection->write_buffer_off]); GNUNET_assert (size <= avail); - sock->write_buffer_off += size; + if (0 != size) + connection->write_buffer_off += size; return GNUNET_YES; } @@ -1332,19 +1178,18 @@ process_notify (struct GNUNET_CONNECTION_Handle *sock) static void transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_CONNECTION_Handle *sock = cls; + struct GNUNET_CONNECTION_Handle *connection = cls; GNUNET_CONNECTION_TransmitReadyNotify notify; - sock->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; + connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmit to `%s:%u/%s' fails, time out reached (%p).\n", - sock->hostname, - sock->port, GNUNET_a2s (sock->addr, sock->addrlen), sock); - GNUNET_assert (0 != (sock->ccs & COCO_TRANSMIT_READY)); - sock->ccs -= COCO_TRANSMIT_READY; /* remove request */ - notify = sock->nth.notify_ready; - sock->nth.notify_ready = NULL; - notify (sock->nth.notify_ready_cls, 0, NULL); + connection->hostname, + connection->port, GNUNET_a2s (connection->addr, connection->addrlen), connection); + notify = connection->nth.notify_ready; + GNUNET_assert (NULL != notify); + connection->nth.notify_ready = NULL; + notify (connection->nth.notify_ready_cls, 0, NULL); } @@ -1360,54 +1205,21 @@ transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void connect_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_CONNECTION_Handle *sock = cls; + struct GNUNET_CONNECTION_Handle *connection = cls; GNUNET_CONNECTION_TransmitReadyNotify notify; LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission request of size %u fails (%s/%u), connection failed (%p).\n", - sock->nth.notify_size, sock->hostname, sock->port, sock); - sock->write_task = GNUNET_SCHEDULER_NO_TASK; - notify = sock->nth.notify_ready; - sock->nth.notify_ready = NULL; - notify (sock->nth.notify_ready_cls, 0, NULL); -} - - -/** - * FIXME - * - * @param sock FIXME - */ -static void -transmit_error (struct GNUNET_CONNECTION_Handle *sock) -{ - GNUNET_CONNECTION_TransmitReadyNotify notify; - - if (NULL != sock->sock) - { - GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR); - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); - sock->sock = NULL; - } - if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (sock->read_task); - sock->read_task = GNUNET_SCHEDULER_NO_TASK; - signal_timeout (sock); - return; - } - if (sock->nth.notify_ready == NULL) - return; /* nobody to tell about it */ - notify = sock->nth.notify_ready; - sock->nth.notify_ready = NULL; - notify (sock->nth.notify_ready_cls, 0, NULL); + connection->nth.notify_size, connection->hostname, connection->port, connection); + connection->write_task = GNUNET_SCHEDULER_NO_TASK; + notify = connection->nth.notify_ready; + connection->nth.notify_ready = NULL; + notify (connection->nth.notify_ready_cls, 0, NULL); } /** - * See if we are now connected. If not, wait longer for - * connect to succeed. If connected, we should be able - * to write now as well, unless we timed out. + * We are ready to transmit (or got a timeout). * * @param cls our connection handle * @param tc task context describing why we are here @@ -1415,27 +1227,27 @@ transmit_error (struct GNUNET_CONNECTION_Handle *sock) static void transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_CONNECTION_Handle *sock = cls; + struct GNUNET_CONNECTION_Handle *connection = cls; GNUNET_CONNECTION_TransmitReadyNotify notify; ssize_t ret; size_t have; - LOG (GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", sock); - GNUNET_assert (sock->write_task != GNUNET_SCHEDULER_NO_TASK); - sock->write_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_assert (sock->nth.timeout_task == GNUNET_SCHEDULER_NO_TASK); + LOG (GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", connection); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != connection->write_task); + connection->write_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->nth.timeout_task); if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { - if ((sock->ignore_shutdown == GNUNET_YES) && (NULL != sock->sock)) + if (NULL != connection->sock) goto SCHEDULE_WRITE; /* ignore shutdown, go again immediately */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmit to `%s' fails, shutdown happened (%p).\n", - GNUNET_a2s (sock->addr, sock->addrlen), sock); - notify = sock->nth.notify_ready; + GNUNET_a2s (connection->addr, connection->addrlen), connection); + notify = connection->nth.notify_ready; if (NULL != notify) { - sock->nth.notify_ready = NULL; - notify (sock->nth.notify_ready_cls, 0, NULL); + connection->nth.notify_ready = NULL; + notify (connection->nth.notify_ready_cls, 0, NULL); } return; } @@ -1443,95 +1255,97 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmit to `%s' fails, time out reached (%p).\n", - GNUNET_a2s (sock->addr, sock->addrlen), sock); - notify = sock->nth.notify_ready; + GNUNET_a2s (connection->addr, connection->addrlen), connection); + notify = connection->nth.notify_ready; GNUNET_assert (NULL != notify); - sock->nth.notify_ready = NULL; - notify (sock->nth.notify_ready_cls, 0, NULL); + connection->nth.notify_ready = NULL; + notify (connection->nth.notify_ready_cls, 0, NULL); return; } - GNUNET_assert (NULL != sock->sock); - if (tc->write_ready == NULL) + GNUNET_assert (NULL != connection->sock); + if (NULL == tc->write_ready) { - /* special circumstances (in particular, - * PREREQ_DONE after connect): not yet ready to write, - * but no "fatal" error either. Hence retry. */ + /* special circumstances (in particular, PREREQ_DONE after + * connect): not yet ready to write, but no "fatal" error either. + * Hence retry. */ goto SCHEDULE_WRITE; } - if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, sock->sock)) + if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, connection->sock)) { - LOG (GNUNET_ERROR_TYPE_INFO, - _ - ("Could not satisfy pending transmission request, socket closed or connect failed (%p).\n"), - sock); - transmit_error (sock); - return; /* connect failed for good, we're finished */ + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task); + /* special circumstances (in particular, shutdown): not yet ready + * to write, but no "fatal" error either. Hence retry. */ + goto SCHEDULE_WRITE; } - GNUNET_assert (sock->write_buffer_off >= sock->write_buffer_pos); - if ((sock->nth.notify_ready != NULL) && - (sock->write_buffer_size < sock->nth.notify_size)) + GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos); + if ((NULL != connection->nth.notify_ready) && + (connection->write_buffer_size < connection->nth.notify_size)) { - sock->write_buffer = - GNUNET_realloc (sock->write_buffer, sock->nth.notify_size); - sock->write_buffer_size = sock->nth.notify_size; + connection->write_buffer = + GNUNET_realloc (connection->write_buffer, connection->nth.notify_size); + connection->write_buffer_size = connection->nth.notify_size; } - process_notify (sock); - have = sock->write_buffer_off - sock->write_buffer_pos; - if (have == 0) + process_notify (connection); + have = connection->write_buffer_off - connection->write_buffer_pos; + if (0 == have) { /* no data ready for writing, terminate write loop */ return; } - GNUNET_assert (have <= sock->write_buffer_size); - GNUNET_assert (have + sock->write_buffer_pos <= sock->write_buffer_size); - GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size); + GNUNET_assert (have <= connection->write_buffer_size); + GNUNET_assert (have + connection->write_buffer_pos <= connection->write_buffer_size); + GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size); RETRY: ret = - GNUNET_NETWORK_socket_send (sock->sock, - &sock->write_buffer[sock->write_buffer_pos], - have); - if (ret == -1) + GNUNET_NETWORK_socket_send (connection->sock, + &connection->write_buffer[connection->write_buffer_pos], + have); + if (-1 == ret) { - if (errno == EINTR) + if (EINTR == errno) goto RETRY; - LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "send"); - transmit_error (sock); + if (GNUNET_SCHEDULER_NO_TASK != connection->write_task) + { + GNUNET_SCHEDULER_cancel (connection->write_task); + connection->write_task = GNUNET_SCHEDULER_NO_TASK; + } + signal_transmit_error (connection, errno); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, - "transmit_ready transmitted %u/%u bytes to `%s' (%p)\n", - (unsigned int) ret, have, GNUNET_a2s (sock->addr, sock->addrlen), sock); - sock->write_buffer_pos += ret; - if (sock->write_buffer_pos == sock->write_buffer_off) + "Connection transmitted %u/%u bytes to `%s' (%p)\n", + (unsigned int) ret, have, GNUNET_a2s (connection->addr, connection->addrlen), connection); + connection->write_buffer_pos += ret; + if (connection->write_buffer_pos == connection->write_buffer_off) { /* transmitted all pending data */ - sock->write_buffer_pos = 0; - sock->write_buffer_off = 0; + connection->write_buffer_pos = 0; + connection->write_buffer_off = 0; } - if ((sock->write_buffer_off == 0) && (NULL == sock->nth.notify_ready)) + if ((0 == connection->write_buffer_off) && (NULL == connection->nth.notify_ready)) return; /* all data sent! */ /* not done writing, schedule more */ SCHEDULE_WRITE: LOG (GNUNET_ERROR_TYPE_DEBUG, - "Re-scheduling transmit_ready (more to do) (%p).\n", sock); - have = sock->write_buffer_off - sock->write_buffer_pos; - GNUNET_assert ((sock->nth.notify_ready != NULL) || (have > 0)); - if (sock->write_task == GNUNET_SCHEDULER_NO_TASK) - sock->write_task = - GNUNET_SCHEDULER_add_write_net ((sock->nth.notify_ready == + "Re-scheduling transmit_ready (more to do) (%p).\n", connection); + have = connection->write_buffer_off - connection->write_buffer_pos; + GNUNET_assert ((NULL != connection->nth.notify_ready) || (have > 0)); + if (GNUNET_SCHEDULER_NO_TASK == connection->write_task) + connection->write_task = + GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready == NULL) ? GNUNET_TIME_UNIT_FOREVER_REL : GNUNET_TIME_absolute_get_remaining - (sock->nth.transmit_timeout), - sock->sock, &transmit_ready, sock); + (connection->nth.transmit_timeout), + connection->sock, &transmit_ready, connection); } /** - * Ask the socket to call us once the specified number of bytes + * Ask the connection to call us once the specified number of bytes * are free in the transmission buffer. May call the notify * method immediately if enough space is available. * - * @param sock socket + * @param connection connection * @param size number of bytes to send * @param timeout after how long should we give up (and call * notify with buf NULL and size 0)? @@ -1541,55 +1355,55 @@ SCHEDULE_WRITE: * NULL if we are already going to notify someone else (busy) */ struct GNUNET_CONNECTION_TransmitHandle * -GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *sock, +GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify notify, void *notify_cls) { - if (sock->nth.notify_ready != NULL) + if (NULL != connection->nth.notify_ready) { GNUNET_assert (0); return NULL; } - GNUNET_assert (notify != NULL); + GNUNET_assert (NULL != notify); GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); - GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size); - GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size); - GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_off); - sock->nth.notify_ready = notify; - sock->nth.notify_ready_cls = notify_cls; - sock->nth.sh = sock; - sock->nth.notify_size = size; - sock->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->nth.timeout_task); - if ((sock->sock == NULL) && (sock->ap_head == NULL) && - (sock->dns_active == NULL)) + GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size); + GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size); + GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off); + connection->nth.notify_ready = notify; + connection->nth.notify_ready_cls = notify_cls; + connection->nth.connection = connection; + connection->nth.notify_size = size; + connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->nth.timeout_task); + if ((NULL == connection->sock) && + (NULL == connection->ap_head) && + (NULL == connection->dns_active)) { - if (sock->write_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (sock->write_task); - sock->write_task = GNUNET_SCHEDULER_add_now (&connect_error, sock); - return &sock->nth; + if (GNUNET_SCHEDULER_NO_TASK != connection->write_task) + GNUNET_SCHEDULER_cancel (connection->write_task); + connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error, connection); + return &connection->nth; } - if (GNUNET_SCHEDULER_NO_TASK != sock->write_task) - return &sock->nth; - if (sock->sock != NULL) + if (GNUNET_SCHEDULER_NO_TASK != connection->write_task) + return &connection->nth; /* previous transmission still in progress */ + if (NULL != connection->sock) { - LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling transmit_ready (%p).\n", sock); - sock->write_task = + /* connected, try to transmit now */ + LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling transmission (%p).\n", connection); + connection->write_task = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining - (sock->nth.transmit_timeout), - sock->sock, &transmit_ready, sock); - } - else - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "CCS-Scheduling transmit_ready, adding timeout task (%p).\n", sock); - sock->ccs |= COCO_TRANSMIT_READY; - sock->nth.timeout_task = - GNUNET_SCHEDULER_add_delayed (timeout, &transmit_timeout, sock); + (connection->nth.transmit_timeout), + connection->sock, &transmit_ready, connection); + return &connection->nth; } - return &sock->nth; + /* not yet connected, wait for connection */ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Need to wait to schedule transmission for connection, adding timeout task (%p).\n", connection); + connection->nth.timeout_task = + GNUNET_SCHEDULER_add_delayed (timeout, &transmit_timeout, connection); + return &connection->nth; } @@ -1603,24 +1417,18 @@ GNUNET_CONNECTION_notify_transmit_ready_cancel (struct GNUNET_CONNECTION_TransmitHandle *th) { - GNUNET_assert (th->notify_ready != NULL); - if (0 != (th->sh->ccs & COCO_TRANSMIT_READY)) + GNUNET_assert (NULL != th->notify_ready); + th->notify_ready = NULL; + if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task) { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "notify_transmit_ready_cancel cancels timeout_task (%p)\n", th); GNUNET_SCHEDULER_cancel (th->timeout_task); th->timeout_task = GNUNET_SCHEDULER_NO_TASK; - th->sh->ccs -= COCO_TRANSMIT_READY; } - else + if (GNUNET_SCHEDULER_NO_TASK != th->connection->write_task) { - if (th->sh->write_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (th->sh->write_task); - th->sh->write_task = GNUNET_SCHEDULER_NO_TASK; - } + GNUNET_SCHEDULER_cancel (th->connection->write_task); + th->connection->write_task = GNUNET_SCHEDULER_NO_TASK; } - th->notify_ready = NULL; } /* end of connection.c */ diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c index 84aab6b..8c226f6 100644 --- a/src/util/container_bloomfilter.c +++ b/src/util/container_bloomfilter.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2003, 2004, 2006, 2008, 2011 Christian Grothoff (and other contributing authors) + (C) 2001, 2002, 2003, 2004, 2006, 2008, 2011, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -350,14 +350,16 @@ iterateBits (const struct GNUNET_CONTAINER_BloomFilter *bf, bitCount = bf->addressesPerElement; tmp[0] = *key; round = 0; + GNUNET_assert (bf->bitArraySize > 0); + GNUNET_assert (bf->bitArraySize * 8LL > bf->bitArraySize); while (bitCount > 0) { while (slot < (sizeof (GNUNET_HashCode) / sizeof (uint32_t))) { if (GNUNET_YES != callback (arg, bf, - (((uint32_t *) & tmp[round & 1])[slot]) & - ((bf->bitArraySize * 8) - 1))) + (((uint32_t *) & tmp[round & 1])[slot]) % + ((bf->bitArraySize * 8LL)))) return; slot++; bitCount--; @@ -442,7 +444,8 @@ testBitCallback (void *cls, const struct GNUNET_CONTAINER_BloomFilter *bf, * * @param filename the name of the file (or the prefix) * @param size the size of the bloom-filter (number of - * bytes of storage space to use) + * bytes of storage space to use); will be rounded up + * to next power of 2 * @param k the number of GNUNET_CRYPTO_hash-functions to apply per * element (number of bits set per element in the set) * @return the bloomfilter @@ -549,8 +552,6 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size, } bf->bitArraySize = size; bf->addressesPerElement = k; - memset (bf->bitArray, 0, bf->bitArraySize); - if (GNUNET_YES != must_read) return bf; /* already done! */ /* Read from the file what bits we can */ @@ -606,33 +607,22 @@ GNUNET_CONTAINER_bloomfilter_init (const char *data, size_t size, unsigned int k) { struct GNUNET_CONTAINER_BloomFilter *bf; - size_t ui; - if ((k == 0) || (size == 0)) - return NULL; - ui = 1; - while (ui < size) - ui *= 2; - if (size != ui) - { - GNUNET_break (0); + if ((0 == k) || (0 == size)) return NULL; - } bf = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_BloomFilter)); bf->filename = NULL; bf->fh = NULL; bf->bitArray = GNUNET_malloc_large (size); - if (bf->bitArray == NULL) + if (NULL == bf->bitArray) { GNUNET_free (bf); return NULL; } bf->bitArraySize = size; bf->addressesPerElement = k; - if (data != NULL) + if (NULL != data) memcpy (bf->bitArray, data, size); - else - memset (bf->bitArray, 0, bf->bitArraySize); return bf; } @@ -848,7 +838,6 @@ GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf, bf->bitArraySize = size; bf->bitArray = GNUNET_malloc (size); - memset (bf->bitArray, 0, bf->bitArraySize); if (bf->filename != NULL) make_empty_file (bf->fh, bf->bitArraySize * 4LL); while (GNUNET_YES == iterator (iterator_cls, &hc)) diff --git a/src/util/container_heap.c b/src/util/container_heap.c index c34e220..b9cab1e 100644 --- a/src/util/container_heap.c +++ b/src/util/container_heap.c @@ -30,7 +30,7 @@ #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) -#define DEBUG 0 +#define EXTRA_CHECKS 0 /** * Node in the heap. @@ -104,7 +104,7 @@ struct GNUNET_CONTAINER_Heap }; -#if DEBUG +#if EXTRA_CHECKS /** * Check if internal invariants hold for the given node. * @@ -401,7 +401,7 @@ GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap) insert_node (heap, heap->root, root->right_child); } GNUNET_free (root); -#if DEBUG +#if EXTRA_CHECKS GNUNET_assert (((heap->size == 0) && (heap->root == NULL)) || (heap->size == heap->root->tree_size + 1)); CHECK (heap->root); @@ -502,7 +502,7 @@ GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_HeapNode *node) if (heap->walk_pos == node) heap->walk_pos = NULL; GNUNET_free (node); -#if DEBUG +#if EXTRA_CHECKS CHECK (heap->root); GNUNET_assert (((heap->size == 0) && (heap->root == NULL)) || (heap->size == heap->root->tree_size + 1)); @@ -523,13 +523,13 @@ GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *heap, struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost) { -#if DEBUG +#if EXTRA_CHECKS GNUNET_assert (((heap->size == 0) && (heap->root == NULL)) || (heap->size == heap->root->tree_size + 1)); CHECK (heap->root); #endif remove_node (node); -#if DEBUG +#if EXTRA_CHECKS CHECK (heap->root); GNUNET_assert (((heap->size == 1) && (heap->root == NULL)) || (heap->size == heap->root->tree_size + 2)); @@ -539,7 +539,7 @@ GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *heap, heap->root = node; else insert_node (heap, heap->root, node); -#if DEBUG +#if EXTRA_CHECKS CHECK (heap->root); GNUNET_assert (((heap->size == 0) && (heap->root == NULL)) || (heap->size == heap->root->tree_size + 1)); diff --git a/src/util/container_slist.c b/src/util/container_slist.c index 7b85dc8..6b58325 100644 --- a/src/util/container_slist.c +++ b/src/util/container_slist.c @@ -250,10 +250,11 @@ GNUNET_CONTAINER_slist_clear (struct GNUNET_CONTAINER_SList *l) /** * Check if a list contains a certain element - * * @param l list * @param buf payload buffer to find * @param len length of the payload (number of bytes in buf) + * + * @return GNUNET_YES if found, GNUNET_NO otherwise */ int GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l, @@ -267,6 +268,32 @@ GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l, return GNUNET_NO; } +typedef int (*Comparator)(const void *, size_t, const void *, size_t); + +/** + * Check if a list contains a certain element + * + * @param l list + * @param buf payload buffer to find + * @param len length of the payload (number of bytes in buf) + * @param compare comparison function, should return 0 if compared elements match + * + * @return NULL if the 'buf' could not be found, pointer to the + * list element, if found + */ +void * +GNUNET_CONTAINER_slist_contains2 (const struct GNUNET_CONTAINER_SList *l, + const void *buf, size_t len, + Comparator compare) +{ + struct GNUNET_CONTAINER_SList_Elem *e; + + for (e = l->head; e != NULL; e = e->next) + if ((e->len == len) && (*compare)(buf, len, e->elem, e->len) == 0) + return e->elem; + return NULL; +} + /** * Count the elements of a list diff --git a/src/util/crypto_aes.c b/src/util/crypto_aes.c index 8b031f3..d5c36d7 100644 --- a/src/util/crypto_aes.c +++ b/src/util/crypto_aes.c @@ -34,6 +34,8 @@ /** * Create a new SessionKey (for AES-256). + * + * @param key session key to initialize */ void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key) @@ -44,6 +46,7 @@ GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key) htonl (GNUNET_CRYPTO_crc32_n (key, GNUNET_CRYPTO_AES_KEY_LENGTH)); } + /** * Check that a new session key is well-formed. * @@ -56,16 +59,55 @@ GNUNET_CRYPTO_aes_check_session_key (const struct GNUNET_CRYPTO_AesSessionKey uint32_t crc; crc = GNUNET_CRYPTO_crc32_n (key, GNUNET_CRYPTO_AES_KEY_LENGTH); - if (ntohl (key->crc32) == crc) - return GNUNET_OK; - GNUNET_break_op (0); - return GNUNET_SYSERR; + if (ntohl (key->crc32) != crc) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Initialize AES cipher. + * + * @param handle handle to initialize + * @param sessionkey session key to use + * @param iv initialization vector to use + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +static int +setup_cipher (gcry_cipher_hd_t *handle, + const struct GNUNET_CRYPTO_AesSessionKey * + sessionkey, + const struct GNUNET_CRYPTO_AesInitializationVector * + iv) +{ + int rc; + + if (GNUNET_OK != + GNUNET_CRYPTO_aes_check_session_key (sessionkey)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_assert (0 == + gcry_cipher_open (handle, GCRY_CIPHER_AES256, + GCRY_CIPHER_MODE_CFB, 0)); + rc = gcry_cipher_setkey (*handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH); + GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); + rc = gcry_cipher_setiv (*handle, iv, + sizeof (struct + GNUNET_CRYPTO_AesInitializationVector)); + GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); + return GNUNET_OK; } /** * Encrypt a block with the public key of another * host that uses the same cyper. + * * @param block the block to encrypt * @param len the size of the block * @param sessionkey the key used to encrypt @@ -82,28 +124,15 @@ GNUNET_CRYPTO_aes_encrypt (const void *block, size_t len, iv, void *result) { gcry_cipher_hd_t handle; - int rc; - if (sessionkey->crc32 != - htonl (GNUNET_CRYPTO_crc32_n (sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH))) - { - GNUNET_break (0); + if (GNUNET_OK != setup_cipher (&handle, sessionkey, iv)) return -1; - } - GNUNET_assert (0 == - gcry_cipher_open (&handle, GCRY_CIPHER_AES256, - GCRY_CIPHER_MODE_CFB, 0)); - rc = gcry_cipher_setkey (handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH); - GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); - rc = gcry_cipher_setiv (handle, iv, - sizeof (struct - GNUNET_CRYPTO_AesInitializationVector)); - GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, len, block, len)); gcry_cipher_close (handle); return len; } + /** * Decrypt a given block with the sessionkey. * @@ -123,30 +152,18 @@ GNUNET_CRYPTO_aes_decrypt (const void *block, size_t size, iv, void *result) { gcry_cipher_hd_t handle; - int rc; - if (sessionkey->crc32 != - htonl (GNUNET_CRYPTO_crc32_n (sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH))) - { - GNUNET_break (0); + if (GNUNET_OK != setup_cipher (&handle, sessionkey, iv)) return -1; - } - GNUNET_assert (0 == - gcry_cipher_open (&handle, GCRY_CIPHER_AES256, - GCRY_CIPHER_MODE_CFB, 0)); - rc = gcry_cipher_setkey (handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH); - GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); - rc = gcry_cipher_setiv (handle, iv, - sizeof (struct - GNUNET_CRYPTO_AesInitializationVector)); - GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size)); gcry_cipher_close (handle); return size; } + /** * @brief Derive an IV + * * @param iv initialization vector * @param skey session key * @param salt salt for the derivation @@ -165,8 +182,10 @@ GNUNET_CRYPTO_aes_derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, va_end (argp); } + /** * @brief Derive an IV + * * @param iv initialization vector * @param skey session key * @param salt salt for the derivation diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c index 63d9654..4d957c0 100644 --- a/src/util/crypto_hash.c +++ b/src/util/crypto_hash.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 Christian Grothoff (and other contributing authors) + (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -34,6 +34,7 @@ #include "gnunet_common.h" #include "gnunet_crypto_lib.h" #include "gnunet_disk_lib.h" +#include "gnunet_strings_lib.h" #include #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) @@ -54,6 +55,21 @@ GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret) } +/** + * Compute short (256-bit) hash of a given block. + * + * @param block the data to GNUNET_CRYPTO_hash, length is given as a second argument + * @param size the length of the data to GNUNET_CRYPTO_hash + * @param ret pointer to where to write the hashcode + */ +void +GNUNET_CRYPTO_short_hash (const void *block, size_t size, + struct GNUNET_CRYPTO_ShortHashCode * ret) +{ + gcry_md_hash_buffer (GCRY_MD_SHA256, ret, block, size); +} + + /** * Context used when hashing a file. */ @@ -204,7 +220,7 @@ GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority, return NULL; } fhc->bsize = blocksize; - if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO)) + if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO, GNUNET_YES)) { GNUNET_free (fhc->filename); GNUNET_free (fhc); @@ -241,25 +257,8 @@ GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc) } - /* ***************** binary-ASCII encoding *************** */ -/** - * Get the numeric value corresponding to a character. - * - * @param a a character - * @return corresponding numeric value - */ -static unsigned int -getValue__ (unsigned char a) -{ - if ((a >= '0') && (a <= '9')) - return a - '0'; - if ((a >= 'A') && (a <= 'V')) - return (a - 'A' + 10); - return -1; -} - /** * Convert GNUNET_CRYPTO_hash to ASCII encoding. The ASCII encoding is rather @@ -276,88 +275,37 @@ void GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block, struct GNUNET_CRYPTO_HashAsciiEncoded *result) { - /** - * 32 characters for encoding (GNUNET_CRYPTO_hash => 32 characters) - */ - static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; - unsigned int wpos; - unsigned int rpos; - unsigned int bits; - unsigned int vbit; - - GNUNET_assert (block != NULL); - GNUNET_assert (result != NULL); - vbit = 0; - wpos = 0; - rpos = 0; - bits = 0; - while ((rpos < sizeof (GNUNET_HashCode)) || (vbit > 0)) - { - if ((rpos < sizeof (GNUNET_HashCode)) && (vbit < 5)) - { - bits = (bits << 8) | ((unsigned char *) block)[rpos++]; /* eat 8 more bits */ - vbit += 8; - } - if (vbit < 5) - { - bits <<= (5 - vbit); /* zero-padding */ - GNUNET_assert (vbit == 2); /* padding by 3: 512+3 mod 5 == 0 */ - vbit = 5; - } - GNUNET_assert (wpos < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1); - result->encoding[wpos++] = encTable__[(bits >> (vbit - 5)) & 31]; - vbit -= 5; - } - GNUNET_assert (wpos == sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1); - GNUNET_assert (vbit == 0); - result->encoding[wpos] = '\0'; + char *np; + + np = GNUNET_STRINGS_data_to_string ((const unsigned char *) block, + sizeof (struct GNUNET_HashCode), + (char*) result, + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1); + GNUNET_assert (NULL != np); + *np = '\0'; } /** - * Convert ASCII encoding back to GNUNET_CRYPTO_hash + * Convert ASCII encoding back to hash code. * * @param enc the encoding * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) - * @param result where to store the GNUNET_CRYPTO_hash code + * @param result where to store the hash code * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding */ int GNUNET_CRYPTO_hash_from_string2 (const char *enc, size_t enclen, GNUNET_HashCode * result) { - unsigned int rpos; - unsigned int wpos; - unsigned int bits; - unsigned int vbit; - int ret; + char upper_enc[enclen]; + char* up_ptr = upper_enc; - if (enclen != sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1) - return GNUNET_SYSERR; + GNUNET_STRINGS_utf8_toupper(enc, &up_ptr); - vbit = 2; /* padding! */ - wpos = sizeof (GNUNET_HashCode); - rpos = sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1; - bits = (ret = getValue__ (enc[--rpos])) >> 3; - if (-1 == ret) - return GNUNET_SYSERR; - while (wpos > 0) - { - GNUNET_assert (rpos > 0); - bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits; - if (-1 == ret) - return GNUNET_SYSERR; - vbit += 5; - if (vbit >= 8) - { - ((unsigned char *) result)[--wpos] = (unsigned char) bits; - bits >>= 8; - vbit -= 8; - } - } - GNUNET_assert (rpos == 0); - GNUNET_assert (vbit == 0); - return GNUNET_OK; + return GNUNET_STRINGS_string_to_data (upper_enc, enclen, + (unsigned char*) result, + sizeof (struct GNUNET_HashCode)); } @@ -644,4 +592,119 @@ GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, } + +/** + * Double short (256-bit) hash to create a long hash. + * + * @param sh short hash to double + * @param dh where to store the (doubled) long hash (not really a hash) + */ +void +GNUNET_CRYPTO_short_hash_double (const struct GNUNET_CRYPTO_ShortHashCode *sh, + struct GNUNET_HashCode *dh) +{ + char *ptr; + + ptr = (char*) dh; + memcpy (ptr, sh, sizeof (struct GNUNET_CRYPTO_ShortHashCode)); + memcpy (&ptr[sizeof (struct GNUNET_CRYPTO_ShortHashCode)], sh, sizeof (struct GNUNET_CRYPTO_ShortHashCode)); +} + + +/** + * Truncate doubled short hash back to a short hash. + * + * @param dh doubled short hash to reduce again + * @param sh where to store the short hash + * @return GNUNET_OK on success, GNUNET_SYSERR if this was not a + * doubled short hash + */ +int +GNUNET_CRYPTO_short_hash_from_truncation (const struct GNUNET_HashCode *dh, + struct GNUNET_CRYPTO_ShortHashCode *sh) +{ + const struct GNUNET_CRYPTO_ShortHashCode *s; + + s = (const struct GNUNET_CRYPTO_ShortHashCode *) dh; + if (0 != memcmp (&s[0], + &s[1], + sizeof (struct GNUNET_CRYPTO_ShortHashCode))) + return GNUNET_SYSERR; + *sh = *s; + return GNUNET_OK; +} + + +/** + * Convert ASCII encoding back to a 'struct GNUNET_CRYPTO_ShortHash' + * + * @param enc the encoding + * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) + * @param result where to store the GNUNET_CRYPTO_hash code + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +int +GNUNET_CRYPTO_short_hash_from_string2 (const char *enc, size_t enclen, + struct GNUNET_CRYPTO_ShortHashCode * result) +{ + + char upper_enc[enclen]; + char* up_ptr = upper_enc; + + GNUNET_STRINGS_utf8_toupper(enc, &up_ptr); + return GNUNET_STRINGS_string_to_data (upper_enc, enclen, + (unsigned char*) result, + sizeof (struct GNUNET_CRYPTO_ShortHashCode)); +} + + +/** + * Convert short hash to ASCII encoding. + * + * @param block the hash code + * @param result where to store the encoding (struct GNUNET_CRYPTO_ShortHashAsciiEncoded can be + * safely cast to char*, a '\\0' termination is set). + */ +void +GNUNET_CRYPTO_short_hash_to_enc (const struct GNUNET_CRYPTO_ShortHashCode * block, + struct GNUNET_CRYPTO_ShortHashAsciiEncoded *result) +{ + char *np; + + np = GNUNET_STRINGS_data_to_string ((const unsigned char *) block, + sizeof (struct GNUNET_CRYPTO_ShortHashCode), + (char*) result, + sizeof (struct GNUNET_CRYPTO_ShortHashAsciiEncoded) - 1); + GNUNET_assert (NULL != np); + *np = '\0'; +} + +/** + * Compare function for ShortHashCodes, producing a total ordering + * of all hashcodes. + * + * @param h1 some hash code + * @param h2 some hash code + * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2. + */ +int +GNUNET_CRYPTO_short_hash_cmp (const struct GNUNET_CRYPTO_ShortHashCode * h1, + const struct GNUNET_CRYPTO_ShortHashCode * h2) +{ + unsigned int *i1; + unsigned int *i2; + int i; + + i1 = (unsigned int *) h1; + i2 = (unsigned int *) h2; + for (i = (sizeof (struct GNUNET_CRYPTO_ShortHashCode) / sizeof (unsigned int)) - 1; i >= 0; i--) + { + if (i1[i] > i2[i]) + return 1; + if (i1[i] < i2[i]) + return -1; + } + return 0; +} + /* end of crypto_hash.c */ diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c index 40bfa67..c2b9677 100644 --- a/src/util/crypto_hkdf.c +++ b/src/util/crypto_hkdf.c @@ -49,6 +49,7 @@ #define DEBUG_HKDF 0 + #if GNUNET_BUILD #include "platform.h" #include "gnunet_crypto_lib.h" diff --git a/src/util/crypto_ksk.c b/src/util/crypto_ksk.c index 0f5a295..274457b 100644 --- a/src/util/crypto_ksk.c +++ b/src/util/crypto_ksk.c @@ -557,202 +557,65 @@ makeKblockKeyInternal (const GNUNET_HashCode * hc) /** - * Decode the internal format into the format used - * by libgcrypt. + * Entry in the KSK cache. */ -static struct GNUNET_CRYPTO_RsaPrivateKey * -ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding) -{ - struct GNUNET_CRYPTO_RsaPrivateKey *ret; - gcry_sexp_t res; - gcry_mpi_t n, e, d, p, q, u; - int rc; - size_t size; - int pos; - - pos = 0; - size = ntohs (encoding->sizen); - rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, - &((const unsigned char *) (&encoding[1]))[pos], size, - &size); - pos += ntohs (encoding->sizen); - if (rc) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - return NULL; - } - size = ntohs (encoding->sizee); - rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG, - &((const unsigned char *) (&encoding[1]))[pos], size, - &size); - pos += ntohs (encoding->sizee); - if (rc) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (n); - return NULL; - } - size = ntohs (encoding->sized); - rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG, - &((const unsigned char *) (&encoding[1]))[pos], size, - &size); - pos += ntohs (encoding->sized); - if (rc) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (n); - gcry_mpi_release (e); - return NULL; - } - /* swap p and q! */ - size = ntohs (encoding->sizep); - if (size > 0) - { - rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG, - &((const unsigned char *) (&encoding[1]))[pos], size, - &size); - pos += ntohs (encoding->sizep); - if (rc) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (n); - gcry_mpi_release (e); - gcry_mpi_release (d); - return NULL; - } - } - else - q = NULL; - size = ntohs (encoding->sizeq); - if (size > 0) - { - rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG, - &((const unsigned char *) (&encoding[1]))[pos], size, - &size); - pos += ntohs (encoding->sizeq); - if (rc) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (n); - gcry_mpi_release (e); - gcry_mpi_release (d); - if (q != NULL) - gcry_mpi_release (q); - return NULL; - } - } - else - p = NULL; - pos += ntohs (encoding->sizedmp1); - pos += ntohs (encoding->sizedmq1); - size = - ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) - - pos; - if (size > 0) - { - rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG, - &((const unsigned char *) (&encoding[1]))[pos], size, - &size); - if (rc) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (n); - gcry_mpi_release (e); - gcry_mpi_release (d); - if (p != NULL) - gcry_mpi_release (p); - if (q != NULL) - gcry_mpi_release (q); - return NULL; - } - } - else - u = NULL; - - if ((p != NULL) && (q != NULL) && (u != NULL)) - { - rc = gcry_sexp_build (&res, &size, /* erroff */ - "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))", - n, e, d, p, q, u); - } - else - { - if ((p != NULL) && (q != NULL)) - { - rc = gcry_sexp_build (&res, &size, /* erroff */ - "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))", - n, e, d, p, q); - } - else - { - rc = gcry_sexp_build (&res, &size, /* erroff */ - "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d); - } - } - gcry_mpi_release (n); - gcry_mpi_release (e); - gcry_mpi_release (d); - if (p != NULL) - gcry_mpi_release (p); - if (q != NULL) - gcry_mpi_release (q); - if (u != NULL) - gcry_mpi_release (u); - - if (rc) - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); -#if EXTRA_CHECKS - if (gcry_pk_testkey (res)) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc); - return NULL; - } -#endif - ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); - ret->sexp = res; - return ret; -} - - struct KBlockKeyCacheLine { + /** + * Hash from which the key was generated. + */ GNUNET_HashCode hc; + + /** + * The encoded key. + */ struct KskRsaPrivateKeyBinaryEncoded *pke; }; + +/** + * Cached KSK keys so that we don't have to recompute them + * all the time. + */ static struct KBlockKeyCacheLine **cache; + +/** + * Size of the 'cache' array. + */ static unsigned int cacheSize; + /** * Deterministically (!) create a hostkey using only the * given HashCode as input to the PRNG. + * + * @param hc hash code to generate the key from + * @return corresponding private key; must not be freed! */ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc) { - struct GNUNET_CRYPTO_RsaPrivateKey *ret; struct KBlockKeyCacheLine *line; unsigned int i; - for (i = 0; i < cacheSize; i++) - { + for (i = 0; i < cacheSize; i++) if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode))) - { - ret = ksk_decode_key (cache[i]->pke); - return ret; - } - } - + return GNUNET_CRYPTO_rsa_decode_key ((const char*) cache[i]->pke, + ntohs (cache[i]->pke->len)); line = GNUNET_malloc (sizeof (struct KBlockKeyCacheLine)); line->hc = *hc; line->pke = makeKblockKeyInternal (hc); GNUNET_array_grow (cache, cacheSize, cacheSize + 1); cache[cacheSize - 1] = line; - return ksk_decode_key (line->pke); + return GNUNET_CRYPTO_rsa_decode_key ((const char*) line->pke, + ntohs (line->pke->len)); } +/** + * Destructor that frees the KSK cache. + */ void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini () { unsigned int i; diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c index 25226a3..35d3c41 100644 --- a/src/util/crypto_random.c +++ b/src/util/crypto_random.c @@ -256,7 +256,7 @@ entropy_generator (void *cls, const char *what, int printchar, int current, if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill"); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); - GNUNET_OS_process_close (genproc); + GNUNET_OS_process_destroy (genproc); genproc = NULL; } return; @@ -274,7 +274,7 @@ entropy_generator (void *cls, const char *what, int printchar, int current, if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill"); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); - GNUNET_OS_process_close (genproc); + GNUNET_OS_process_destroy (genproc); genproc = NULL; } LOG (GNUNET_ERROR_TYPE_INFO, _("Starting `%s' process to generate entropy\n"), @@ -293,7 +293,7 @@ killfind () if (genproc != NULL) { GNUNET_OS_process_kill (genproc, SIGKILL); - GNUNET_OS_process_close (genproc); + GNUNET_OS_process_destroy (genproc); genproc = NULL; } } diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index 418fe83..0106f43 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c @@ -36,6 +36,7 @@ #include "gnunet_common.h" #include "gnunet_crypto_lib.h" #include "gnunet_disk_lib.h" +#include "gnunet_strings_lib.h" #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) @@ -53,32 +54,6 @@ struct GNUNET_CRYPTO_RsaPrivateKey }; -GNUNET_NETWORK_STRUCT_BEGIN - -/** - * GNUnet mandates a certain format for the encoding - * of private RSA key information that is provided - * by the RSA implementations. This format is used - * to serialize a private RSA key (typically when - * writing it to disk). - */ -struct RsaPrivateKeyBinaryEncoded -{ - /** - * Total size of the structure, in bytes, in big-endian! - */ - uint16_t len GNUNET_PACKED; - uint16_t sizen GNUNET_PACKED; /* in big-endian! */ - uint16_t sizee GNUNET_PACKED; /* in big-endian! */ - uint16_t sized GNUNET_PACKED; /* in big-endian! */ - uint16_t sizep GNUNET_PACKED; /* in big-endian! */ - uint16_t sizeq GNUNET_PACKED; /* in big-endian! */ - uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */ - uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */ - /* followed by the actual values */ -}; -GNUNET_NETWORK_STRUCT_END - #define HOSTKEY_LEN 2048 #define EXTRA_CHECKS ALLOW_EXTRA_CHECKS @@ -107,7 +82,9 @@ adjust (unsigned char *buf, size_t size, size_t target) } /** - * This HostKey implementation uses RSA. + * Create a new private key. Caller must free return value. + * + * @return fresh private key */ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_key_create () @@ -132,6 +109,7 @@ GNUNET_CRYPTO_rsa_key_create () /** * Free memory occupied by hostkey + * @param hostkey pointer to the memory to free */ void GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) @@ -237,6 +215,70 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey } +/** + * Convert a public key to a string. + * + * @param pub key to convert + * @return string representing 'pub' + */ +char * +GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub) +{ + char *pubkeybuf; + size_t keylen = (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) * 8; + char *end; + + if (keylen % 5 > 0) + keylen += 5 - keylen % 5; + keylen /= 5; + pubkeybuf = GNUNET_malloc (keylen + 1); + end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + pubkeybuf, + keylen); + if (NULL == end) + { + GNUNET_free (pubkeybuf); + return NULL; + } + *end = '\0'; + return pubkeybuf; +} + + +/** + * Convert a string representing a public key to a public key. + * + * @param enc encoded public key + * @param enclen number of bytes in enc (without 0-terminator) + * @param pub where to store the public key + * @return GNUNET_OK on success + */ +int +GNUNET_CRYPTO_rsa_public_key_from_string (const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub) +{ + size_t keylen = (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) * 8; + + if (keylen % 5 > 0) + keylen += 5 - keylen % 5; + keylen /= 5; + if (enclen != keylen) + return GNUNET_SYSERR; + + if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen, + (unsigned char*) pub, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + return GNUNET_SYSERR; + if ( (ntohs (pub->len) != sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) || + (ntohs (pub->padding) != 0) || + (ntohs (pub->sizen) != GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH) ) + return GNUNET_SYSERR; + return GNUNET_OK; +} + + /** * Internal: publicKey => RSA-Key. * @@ -301,10 +343,10 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * @returns encoding of the private key. * The first 4 bytes give the size of the array, as usual. */ -static struct RsaPrivateKeyBinaryEncoded * -rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) +struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * +GNUNET_CRYPTO_rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) { - struct RsaPrivateKeyBinaryEncoded *retval; + struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *retval; gcry_mpi_t pkv[6]; void *pbu[6]; size_t sizes[6]; @@ -333,7 +375,7 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) if (rc) rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "ned"); GNUNET_assert (0 == rc); - size = sizeof (struct RsaPrivateKeyBinaryEncoded); + size = sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded); for (i = 0; i < 6; i++) { if (pkv[i] != NULL) @@ -383,6 +425,7 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) return retval; } + /** * Decode the private key from the file-format back * to the "normal", internal format. @@ -394,8 +437,8 @@ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) { struct GNUNET_CRYPTO_RsaPrivateKey *ret; - const struct RsaPrivateKeyBinaryEncoded *encoding = - (const struct RsaPrivateKeyBinaryEncoded *) buf; + const struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *encoding = + (const struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *) buf; gcry_sexp_t res; gcry_mpi_t n, e, d, p, q, u; int rc; @@ -483,7 +526,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) pos += ntohs (encoding->sizedmp1); pos += ntohs (encoding->sizedmq1); size = - ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos; + ntohs (encoding->len) - sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded) - pos; if (size > 0) { rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG, @@ -567,7 +610,7 @@ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) { struct GNUNET_CRYPTO_RsaPrivateKey *ret; - struct RsaPrivateKeyBinaryEncoded *enc; + struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc; uint16_t len; struct GNUNET_DISK_FileHandle *fd; unsigned int cnt; @@ -607,7 +650,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) while (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, - sizeof (struct RsaPrivateKeyBinaryEncoded), + sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), GNUNET_YES)) { sleep (1); @@ -623,7 +666,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) _("Creating a new private key. This may take a while.\n")); ret = GNUNET_CRYPTO_rsa_key_create (); GNUNET_assert (ret != NULL); - enc = rsa_encode_key (ret); + enc = GNUNET_CRYPTO_rsa_encode_key (ret); GNUNET_assert (enc != NULL); GNUNET_assert (ntohs (enc->len) == GNUNET_DISK_file_write (fd, enc, ntohs (enc->len))); @@ -632,7 +675,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) GNUNET_DISK_file_sync (fd); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, - sizeof (struct RsaPrivateKeyBinaryEncoded))) + sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); GNUNET_CRYPTO_rsa_key_get_public (ret, &pub); @@ -655,7 +698,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) { if (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, - sizeof (struct RsaPrivateKeyBinaryEncoded), + sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), GNUNET_NO)) { if (0 == ++cnt % 60) @@ -677,21 +720,21 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, - sizeof (struct RsaPrivateKeyBinaryEncoded))) + sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); return NULL; } - if (GNUNET_YES != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES)) + if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) fs = 0; - if (fs < sizeof (struct RsaPrivateKeyBinaryEncoded)) + if (fs < sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)) { /* maybe we got the read lock before the hostkey generating * process had a chance to get the write lock; give it up! */ if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, - sizeof (struct RsaPrivateKeyBinaryEncoded))) + sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); if (0 == ++cnt % 10) { @@ -699,7 +742,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) _ ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"), filename, (unsigned int) fs, - (unsigned int) sizeof (struct RsaPrivateKeyBinaryEncoded)); + (unsigned int) sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)); LOG (GNUNET_ERROR_TYPE_ERROR, _ ("This may be ok if someone is currently generating a hostkey.\n")); @@ -727,7 +770,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) GNUNET_free (enc); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, - sizeof (struct RsaPrivateKeyBinaryEncoded))) + sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); if (ret != NULL) @@ -742,6 +785,35 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) } +/** + * Setup a hostkey file for a peer given the name of the + * configuration file (!). This function is used so that + * at a later point code can be certain that reading a + * hostkey is fast (for example in time-dependent testcases). + * + * @param cfg_name name of the configuration file to use + */ +void +GNUNET_CRYPTO_setup_hostkey (const char *cfg_name) +{ + struct GNUNET_CONFIGURATION_Handle *cfg; + struct GNUNET_CRYPTO_RsaPrivateKey *pk; + char *fn; + + cfg = GNUNET_CONFIGURATION_create (); + (void) GNUNET_CONFIGURATION_load (cfg, cfg_name); + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", &fn)) + { + pk = GNUNET_CRYPTO_rsa_key_create_from_file (fn); + if (NULL != pk) + GNUNET_CRYPTO_rsa_key_free (pk); + GNUNET_free (fn); + } + GNUNET_CONFIGURATION_destroy (cfg); +} + + /** * Encrypt a block with the public key of another host that uses the * same cipher. @@ -793,6 +865,7 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, return GNUNET_OK; } + /** * Decrypt a given block with the hostkey. * diff --git a/src/util/disk.c b/src/util/disk.c index b6b458f..cba0d44 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -40,10 +40,6 @@ #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) -#define DEBUG_NPIPE GNUNET_EXTRA_LOGGING - -#define DEBUG_PIPE GNUNET_EXTRA_LOGGING - /** * Block size for IO for copying files. */ @@ -112,9 +108,22 @@ struct GetFileSizeData * GNUNET_YES if symbolic links should be included. */ int include_sym_links; + + /** + * GNUNET_YES if mode is file-only (return total == -1 for directories). + */ + int single_file_mode; }; +#ifndef MINGW +/** + * Translate GNUnet-internal permission bitmap to UNIX file + * access permission bitmap. + * + * @param perm file permissions, GNUnet style + * @return file permissions, UNIX style + */ static int translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm) { @@ -142,6 +151,7 @@ translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm) return mode; } +#endif /** @@ -166,16 +176,21 @@ getSizeRec (void *cls, const char *fn) #ifdef HAVE_STAT64 if (0 != STAT64 (fn, &buf)) { - LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat64", fn); + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat64", fn); return GNUNET_SYSERR; } #else if (0 != STAT (fn, &buf)) { - LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", fn); + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat", fn); return GNUNET_SYSERR; } #endif + if ((S_ISDIR (buf.st_mode)) && (gfsd->single_file_mode == GNUNET_YES)) + { + errno = EISDIR; + return GNUNET_SYSERR; + } if ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)) gfsd->total += buf.st_size; if ((S_ISDIR (buf.st_mode)) && (0 == ACCESS (fn, X_OK)) && @@ -255,7 +270,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset, } #ifdef MINGW - LARGE_INTEGER li, new_pos; + LARGE_INTEGER li; + LARGE_INTEGER new_pos; BOOL b; static DWORD t[] = {[GNUNET_DISK_SEEK_SET] = FILE_BEGIN, @@ -290,11 +306,13 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset, * of all sizes of files in the directory) * @param includeSymLinks should symbolic links be * included? + * @param singleFileMode GNUNET_YES to only get size of one file + * and return GNUNET_SYSERR for directories. * @return GNUNET_SYSERR on error, GNUNET_OK on success */ int GNUNET_DISK_file_size (const char *filename, uint64_t * size, - int includeSymLinks) + int includeSymLinks, int singleFileMode) { struct GetFileSizeData gfsd; int ret; @@ -302,6 +320,7 @@ GNUNET_DISK_file_size (const char *filename, uint64_t * size, GNUNET_assert (size != NULL); gfsd.total = 0; gfsd.include_sym_links = includeSymLinks; + gfsd.single_file_mode = singleFileMode; ret = getSizeRec (&gfsd, filename); *size = gfsd.total; return ret; @@ -719,27 +738,18 @@ GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle * h, void *result, } else { -#if DEBUG_PIPE - LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to read\n"); -#endif if (!ReadFile (h->h, result, len, &bytesRead, h->oOverlapRead)) { if (GetLastError () != ERROR_IO_PENDING) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error reading from pipe: %u\n", GetLastError ()); -#endif SetErrnoFromWinError (GetLastError ()); return GNUNET_SYSERR; } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n"); -#endif GetOverlappedResult (h->h, h->oOverlapRead, &bytesRead, TRUE); } -#if DEBUG_PIPE - LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes\n", bytesRead); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes from pipe\n", bytesRead); } return bytesRead; #else @@ -781,33 +791,24 @@ GNUNET_DISK_file_read_non_blocking (const struct GNUNET_DISK_FileHandle * h, } else { -#if DEBUG_PIPE - LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe, trying to read\n"); -#endif if (!ReadFile (h->h, result, len, &bytesRead, h->oOverlapRead)) { if (GetLastError () != ERROR_IO_PENDING) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error reading from pipe: %u\n", GetLastError ()); -#endif SetErrnoFromWinError (GetLastError ()); return GNUNET_SYSERR; } else { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "ReadFile() queued a read, cancelling\n"); -#endif CancelIo (h->h); errno = EAGAIN; return GNUNET_SYSERR; } } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes\n", bytesRead); -#endif } return bytesRead; #else @@ -880,31 +881,23 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h, } else { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to write %u bytes\n", n); -#endif if (!WriteFile (h->h, buffer, n, &bytesWritten, h->oOverlapWrite)) { if (GetLastError () != ERROR_IO_PENDING) { SetErrnoFromWinError (GetLastError ()); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n", GetLastError ()); -#endif return GNUNET_SYSERR; } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n"); -#endif if (!GetOverlappedResult (h->h, h->oOverlapWrite, &bytesWritten, TRUE)) { SetErrnoFromWinError (GetLastError ()); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error getting overlapped result while writing to pipe: %u\n", GetLastError ()); -#endif return GNUNET_SYSERR; } } @@ -913,35 +906,27 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h, DWORD ovr; if (!GetOverlappedResult (h->h, h->oOverlapWrite, &ovr, TRUE)) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error getting control overlapped result while writing to pipe: %u\n", GetLastError ()); -#endif } else { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes (ovr says %u), picking the greatest\n", bytesWritten, ovr); -#endif } } if (bytesWritten == 0) { if (n > 0) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes, returning -1 with EAGAIN\n", bytesWritten); -#endif errno = EAGAIN; return GNUNET_SYSERR; } } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytesWritten); -#endif } return bytesWritten; #else @@ -970,37 +955,27 @@ GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle * h, #ifdef MINGW DWORD bytesWritten; /* We do a non-overlapped write, which is as blocking as it gets */ -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Writing %u bytes\n", n); -#endif if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL)) { SetErrnoFromWinError (GetLastError ()); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n", GetLastError ()); -#endif return GNUNET_SYSERR; } if (bytesWritten == 0 && n > 0) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for pipe to clean\n"); -#endif WaitForSingleObject (h->h, INFINITE); if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL)) { SetErrnoFromWinError (GetLastError ()); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n", GetLastError ()); -#endif return GNUNET_SYSERR; } } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytesWritten); -#endif return bytesWritten; #else int flags; @@ -1350,7 +1325,7 @@ GNUNET_DISK_file_copy (const char *src, const char *dst) struct GNUNET_DISK_FileHandle *in; struct GNUNET_DISK_FileHandle *out; - if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES)) + if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES, GNUNET_YES)) return GNUNET_SYSERR; pos = 0; in = GNUNET_DISK_file_open (src, GNUNET_DISK_OPEN_READ, @@ -2008,10 +1983,8 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, snprintf (pipename, sizeof pipename, "\\\\.\\pipe\\gnunet-%d-%ld", getpid (), InterlockedIncrement ((LONG *) & pipe_unique_id)); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateNamedPipe: name = %s, size = %lu\n", pipename, psize); -#endif /* Use CreateNamedPipe instead of CreatePipe, because the latter * returns a write handle that does not permit FILE_READ_ATTRIBUTES * access, on versions of win32 earlier than WinXP SP2. @@ -2028,9 +2001,7 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, if (read_pipe != INVALID_HANDLE_VALUE) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", read_pipe); -#endif break; } @@ -2041,33 +2012,24 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, case ERROR_PIPE_BUSY: /* The pipe is already open with compatible parameters. * Pick a new name and retry. */ -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe busy, retrying\n"); -#endif continue; case ERROR_ACCESS_DENIED: /* The pipe is already open with incompatible parameters. * Pick a new name and retry. */ -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe access denied, retrying\n"); -#endif continue; case ERROR_CALL_NOT_IMPLEMENTED: /* We are on an older Win9x platform without named pipes. * Return an anonymous pipe as the best approximation. */ -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateNamedPipe not implemented, resorting to " "CreatePipe: size = %lu\n", psize); -#endif if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize)) { -#if DEBUG_PIPE - LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", - *read_pipe_ptr); - LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", + LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p, write handle = %p\n", + *read_pipe_ptr, *write_pipe_ptr); -#endif return GNUNET_OK; } err = GetLastError (); @@ -2079,9 +2041,7 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, } /* NOTREACHED */ } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile: name = %s\n", pipename); -#endif /* Open the named pipe for writing. * Be sure to permit FILE_READ_ATTRIBUTES access. */ @@ -2094,15 +2054,11 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, /* Failure. */ DWORD err = GetLastError (); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile failed: %d\n", err); -#endif CloseHandle (read_pipe); return err; } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", write_pipe); -#endif /* Success. */ *read_pipe_ptr = read_pipe; *write_pipe_ptr = write_pipe; diff --git a/src/util/getopt.c b/src/util/getopt.c index 1699498..572e534 100644 --- a/src/util/getopt.c +++ b/src/util/getopt.c @@ -202,9 +202,8 @@ char * getenv (); static char * -my_index (str, chr) - const char *str; - int chr; +my_index (const char *str, + int chr) { while (*str) { @@ -294,8 +293,7 @@ exchange (char **); #endif static void -exchange (argv) - char **argv; +exchange (char **argv) { int bottom = first_nonopt; int middle = last_nonopt; @@ -381,10 +379,9 @@ static const char * _getopt_initialize (int, char *const *, const char *); #endif static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +_getopt_initialize (int argc, + char *const *argv, + const char *optstring) { /* Start processing options with ARGV-element 1 (since ARGV-element 0 * is the program name); the sequence of previously skipped diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c index 8fb3673..a31080f 100644 --- a/src/util/getopt_helpers.c +++ b/src/util/getopt_helpers.c @@ -79,9 +79,12 @@ GNUNET_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext const char *trans; const struct GNUNET_GETOPT_CommandLineOption *opt; - printf ("%s\n%s\n", ctx->binaryOptions, gettext (about)); - printf (_ - ("Arguments mandatory for long options are also mandatory for short options.\n")); + if (NULL != about) + { + printf ("%s\n%s\n", ctx->binaryOptions, gettext (about)); + printf (_ + ("Arguments mandatory for long options are also mandatory for short options.\n")); + } i = 0; opt = ctx->allOptions; while (opt[i].description != NULL) diff --git a/src/util/gnunet-rsa.c b/src/util/gnunet-rsa.c new file mode 100644 index 0000000..f3cd83a --- /dev/null +++ b/src/util/gnunet-rsa.c @@ -0,0 +1,128 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file util/gnunet-rsa.c + * @brief tool to manipulate RSA key files + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" + + +/** + * Flag for printing public key. + */ +static int print_public_key; + +/** + * Flag for printing hash of public key. + */ +static int print_peer_identity; + +/** + * Flag for printing short hash of public key. + */ +static int print_short_identity; + + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_CRYPTO_RsaPrivateKey *pk; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; + struct GNUNET_PeerIdentity pid; + + if (NULL == args[0]) + { + fprintf (stderr, _("No hostkey file specified on command line\n")); + return; + } + pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]); + if (print_public_key) + { + char *s; + + GNUNET_CRYPTO_rsa_key_get_public (pk, &pub); + s = GNUNET_CRYPTO_rsa_public_key_to_string (&pub); + fprintf (stdout, "%s\n", s); + GNUNET_free (s); + } + if (print_peer_identity) + { + struct GNUNET_CRYPTO_HashAsciiEncoded enc; + + GNUNET_CRYPTO_rsa_key_get_public (pk, &pub); + GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); + GNUNET_CRYPTO_hash_to_enc (&pid.hashPubKey, &enc); + fprintf (stdout, "%s\n", enc.encoding); + } + if (print_short_identity) + { + struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc; + struct GNUNET_CRYPTO_ShortHashCode sh; + + GNUNET_CRYPTO_rsa_key_get_public (pk, &pub); + GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &sh); + GNUNET_CRYPTO_short_hash_to_enc (&sh, &enc); + fprintf (stdout, "%s\n", enc.short_encoding); + } + GNUNET_CRYPTO_rsa_key_free (pk); +} + + +/** + * The main function to obtain statistics in GNUnet. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + { 'p', "print-public-key", NULL, + gettext_noop ("print the public key in ASCII format"), + 0, &GNUNET_GETOPT_set_one, &print_public_key }, + { 'P', "print-peer-identity", NULL, + gettext_noop ("print the hash of the public key in ASCII format"), + 0, &GNUNET_GETOPT_set_one, &print_peer_identity }, + { 's', "print-short-identity", NULL, + gettext_noop ("print the short hash of the public key in ASCII format"), + 0, &GNUNET_GETOPT_set_one, &print_short_identity }, + GNUNET_GETOPT_OPTION_END + }; + return (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-rsa [OPTIONS] keyfile", + gettext_noop ("Manipulate GNUnet private RSA key files"), + options, &run, NULL)) ? 0 : 1; +} + +/* end of gnunet-rsa.c */ diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c index f20666a..97eba6d 100644 --- a/src/util/gnunet-service-resolver.c +++ b/src/util/gnunet-service-resolver.c @@ -490,10 +490,8 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_RESOLVER - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Resolver asked to look up `%s'.\n"), + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Resolver asked to look up `%s'.\n", hostname); -#endif get_ip_from_hostname (client, hostname, af); return; } @@ -521,15 +519,13 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_RESOLVER { char buf[INET6_ADDRSTRLEN]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Resolver asked to look up IP address `%s'.\n"), + "Resolver asked to look up IP address `%s'.\n", inet_ntop (af, ip, buf, sizeof (buf))); } -#endif get_ip_as_string (client, af, ip); } diff --git a/src/util/helper.c b/src/util/helper.c index 43ec23a..6a84ff3 100644 --- a/src/util/helper.c +++ b/src/util/helper.c @@ -31,24 +31,29 @@ /** * Entry in the queue of messages we need to transmit to the helper. */ -struct HelperMessageQueueEntry +struct GNUNET_HELPER_SendHandle { /** * This is an entry in a DLL. */ - struct HelperMessageQueueEntry *next; + struct GNUNET_HELPER_SendHandle *next; /** * This is an entry in a DLL. */ - struct HelperMessageQueueEntry *prev; + struct GNUNET_HELPER_SendHandle *prev; /** * Message to transmit (allocated at the end of this struct) */ const struct GNUNET_MessageHeader *msg; - + + /** + * The handle to a helper process. + */ + struct GNUNET_HELPER_Handle *h; + /** * Function to call upon completion. */ @@ -106,12 +111,12 @@ struct GNUNET_HELPER_Handle /** * First message queued for transmission to helper. */ - struct HelperMessageQueueEntry *mq_head; + struct GNUNET_HELPER_SendHandle *sh_head; /** * Last message queued for transmission to helper. */ - struct HelperMessageQueueEntry *mq_tail; + struct GNUNET_HELPER_SendHandle *sh_tail; /** * Binary to run. @@ -148,13 +153,13 @@ struct GNUNET_HELPER_Handle static void stop_helper (struct GNUNET_HELPER_Handle *h) { - struct HelperMessageQueueEntry *qe; + struct GNUNET_HELPER_SendHandle *sh; if (NULL != h->helper_proc) { GNUNET_break (0 == GNUNET_OS_process_kill (h->helper_proc, SIGTERM)); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (h->helper_proc)); - GNUNET_OS_process_close (h->helper_proc); + GNUNET_OS_process_destroy (h->helper_proc); h->helper_proc = NULL; } if (GNUNET_SCHEDULER_NO_TASK != h->restart_task) @@ -184,14 +189,14 @@ stop_helper (struct GNUNET_HELPER_Handle *h) h->helper_out = NULL; h->fh_from_helper = NULL; } - while (NULL != (qe = h->mq_head)) + while (NULL != (sh = h->sh_head)) { - GNUNET_CONTAINER_DLL_remove (h->mq_head, - h->mq_tail, - qe); - if (NULL != qe->cont) - qe->cont (qe->cont_cls, GNUNET_NO); - GNUNET_free (qe); + GNUNET_CONTAINER_DLL_remove (h->sh_head, + h->sh_tail, + sh); + if (NULL != sh->cont) + sh->cont (sh->cont_cls, GNUNET_NO); + GNUNET_free (sh); } /* purge MST buffer */ (void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO); @@ -220,7 +225,7 @@ helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_HELPER_Handle *h = cls; - char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE]; + char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE] GNUNET_ALIGN; ssize_t t; h->read_task = GNUNET_SCHEDULER_NO_TASK; @@ -301,6 +306,9 @@ start_helper (struct GNUNET_HELPER_Handle *h) &restart_task, h); return; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Starting HELPER process `%s'\n"), + h->binary_name); h->fh_from_helper = GNUNET_DISK_pipe_handle (h->helper_out, GNUNET_DISK_PIPE_END_READ); h->fh_to_helper = @@ -380,17 +388,17 @@ GNUNET_HELPER_start (const char *binary_name, void GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h) { - struct HelperMessageQueueEntry *qe; + struct GNUNET_HELPER_SendHandle *sh; /* signal pending writes that we were stopped */ - while (NULL != (qe = h->mq_head)) + while (NULL != (sh = h->sh_head)) { - GNUNET_CONTAINER_DLL_remove (h->mq_head, - h->mq_tail, - qe); - if (NULL != qe->cont) - qe->cont (qe->cont_cls, GNUNET_SYSERR); - GNUNET_free (qe); + GNUNET_CONTAINER_DLL_remove (h->sh_head, + h->sh_tail, + sh); + if (NULL != sh->cont) + sh->cont (sh->cont_cls, GNUNET_SYSERR); + GNUNET_free (sh); } stop_helper (h); GNUNET_SERVER_mst_destroy (h->mst); @@ -409,7 +417,7 @@ helper_write (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_HELPER_Handle *h = cls; - struct HelperMessageQueueEntry *qe; + struct GNUNET_HELPER_SendHandle *sh; const char *buf; ssize_t t; @@ -421,10 +429,10 @@ helper_write (void *cls, h->fh_to_helper, &helper_write, h); return; } - if (NULL == (qe = h->mq_head)) + if (NULL == (sh = h->sh_head)) return; /* how did this happen? */ - buf = (const char*) qe->msg; - t = GNUNET_DISK_file_write (h->fh_to_helper, &buf[qe->wpos], ntohs (qe->msg->size) - qe->wpos); + buf = (const char*) sh->msg; + t = GNUNET_DISK_file_write (h->fh_to_helper, &buf[sh->wpos], ntohs (sh->msg->size) - sh->wpos); if (t <= 0) { /* On write-error, restart the helper */ @@ -439,17 +447,17 @@ helper_write (void *cls, &restart_task, h); return; } - qe->wpos += t; - if (qe->wpos == ntohs (qe->msg->size)) + sh->wpos += t; + if (sh->wpos == ntohs (sh->msg->size)) { - GNUNET_CONTAINER_DLL_remove (h->mq_head, - h->mq_tail, - qe); - if (NULL != qe->cont) - qe->cont (qe->cont_cls, GNUNET_YES); - GNUNET_free (qe); + GNUNET_CONTAINER_DLL_remove (h->sh_head, + h->sh_tail, + sh); + if (NULL != sh->cont) + sh->cont (sh->cont_cls, GNUNET_YES); + GNUNET_free (sh); } - if (NULL != h->mq_head) + if (NULL != h->sh_head) h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, h->fh_to_helper, &helper_write, @@ -466,40 +474,68 @@ helper_write (void *cls, * @param cont continuation to run once the message is out (PREREQ_DONE on succees, CANCEL * if the helper process died, NULL during GNUNET_HELPER_stop). * @param cont_cls closure for 'cont' - * @return GNUNET_YES if the message will be sent - * GNUNET_NO if the message was dropped + * @return NULL if the message was dropped, + * otherwise handle to cancel *cont* (actual transmission may + * not be abortable) */ -int +struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls) { - struct HelperMessageQueueEntry *qe; + struct GNUNET_HELPER_SendHandle *sh; uint16_t mlen; if (NULL == h->fh_to_helper) - return GNUNET_NO; + return NULL; if ( (GNUNET_YES == can_drop) && - (h->mq_head != NULL) ) - return GNUNET_NO; + (NULL != h->sh_head) ) + return NULL; mlen = ntohs (msg->size); - qe = GNUNET_malloc (sizeof (struct HelperMessageQueueEntry) + mlen); - qe->msg = (const struct GNUNET_MessageHeader*) &qe[1]; - memcpy (&qe[1], msg, mlen); - qe->cont = cont; - qe->cont_cls = cont_cls; - GNUNET_CONTAINER_DLL_insert_tail (h->mq_head, - h->mq_tail, - qe); + sh = GNUNET_malloc (sizeof (struct GNUNET_HELPER_SendHandle) + mlen); + sh->msg = (const struct GNUNET_MessageHeader*) &sh[1]; + memcpy (&sh[1], msg, mlen); + sh->h = h; + sh->cont = cont; + sh->cont_cls = cont_cls; + GNUNET_CONTAINER_DLL_insert_tail (h->sh_head, + h->sh_tail, + sh); if (GNUNET_SCHEDULER_NO_TASK == h->write_task) h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, h->fh_to_helper, &helper_write, h); - return GNUNET_YES; + return sh; +} + +/** + * Cancel a 'send' operation. If possible, transmitting the + * message is also aborted, but at least 'cont' won't be + * called. + * + * @param sh operation to cancel + */ +void +GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh) +{ + struct GNUNET_HELPER_Handle *h = sh->h; + + sh->cont = NULL; + sh->cont_cls = NULL; + if (0 == sh->wpos) + { + GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh); + if (NULL == h->sh_head) + { + GNUNET_SCHEDULER_cancel (h->write_task); + h->write_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_free (sh); + } } diff --git a/src/util/load.c b/src/util/load.c index e978a95..146e850 100644 --- a/src/util/load.c +++ b/src/util/load.c @@ -26,7 +26,6 @@ #include "platform.h" #include "gnunet_load_lib.h" -#define DEBUG_LOAD GNUNET_EXTRA_LOGGING #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) diff --git a/src/util/network.c b/src/util/network.c index e530ab7..972f938 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) + (C) 2009, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -192,6 +192,61 @@ socket_set_nodelay (const struct GNUNET_NETWORK_Handle *h) } +/** + * Perform proper canonical initialization for a network handle. + * Set it to non-blocking, make it non-inheritable to child + * processes, disable SIGPIPE, enable "nodelay" (if non-UNIX + * stream socket) and check that it is smaller than FS_SETSIZE. + * + * @param h socket to initialize + * @param af address family of the socket + * @param type socket type + * @return GNUNET_OK on success, GNUNET_SYSERR if initialization + * failed and the handle was destroyed + */ +static int +initialize_network_handle (struct GNUNET_NETWORK_Handle *h, + int af, int type) +{ + h->af = af; + if (h->fd == INVALID_SOCKET) + { +#ifdef MINGW + SetErrnoFromWinsockError (WSAGetLastError ()); +#endif + GNUNET_free (h); + return GNUNET_SYSERR; + } +#ifndef MINGW + if (h->fd >= FD_SETSIZE) + { + GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h)); + errno = EMFILE; + return GNUNET_SYSERR; + } + if (GNUNET_OK != socket_set_inheritable (h)) + LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "socket_set_inheritable"); +#endif + if (GNUNET_SYSERR == socket_set_blocking (h, GNUNET_NO)) + { + GNUNET_break (0); + GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h)); + return GNUNET_SYSERR; + } +#ifdef DARWIN + socket_set_nosigpipe (h); +#endif + if ( (type == SOCK_STREAM) +#ifdef AF_UNIX + && (af != AF_UNIX) +#endif + ) + socket_set_nodelay (h); + return GNUNET_OK; +} + + /** * accept a new connection on a socket * @@ -219,49 +274,10 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc, } #endif ret->fd = accept (desc->fd, address, address_len); - if (address != NULL) - ret->af = address->sa_family; - else - ret->af = desc->af; - if (ret->fd == INVALID_SOCKET) - { -#ifdef MINGW - SetErrnoFromWinsockError (WSAGetLastError ()); -#endif - GNUNET_free (ret); - return NULL; - } -#ifndef MINGW - if (ret->fd >= FD_SETSIZE) - { - GNUNET_break (0 == close (ret->fd)); - GNUNET_free (ret); - errno = EMFILE; - return NULL; - } -#endif - if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO)) - - { - - /* we might want to treat this one as fatal... */ - GNUNET_break (0); - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret)); + if (GNUNET_OK != initialize_network_handle (ret, + (NULL != address) ? address->sa_family : desc->af, + SOCK_STREAM)) return NULL; - } - -#ifndef MINGW - if (GNUNET_OK != socket_set_inheritable (ret)) - LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "socket_set_inheritable"); -#endif -#ifdef DARWIN - socket_set_nosigpipe (ret); -#endif -#ifdef AF_UNIX - if (ret->af != AF_UNIX) -#endif - socket_set_nodelay (ret); return ret; } @@ -492,15 +508,16 @@ GNUNET_NETWORK_socket_recvfrom_amount (const struct GNUNET_NETWORK_Handle * error = ioctl (desc->fd, FIONREAD, &pending); if (error == 0) + return (ssize_t) pending; + return GNUNET_NO; #else u_long pending; error = ioctlsocket (desc->fd, FIONREAD, &pending); if (error != SOCKET_ERROR) + return (ssize_t) pending; + return GNUNET_NO; #endif - return pending; - else - return GNUNET_NO; } @@ -677,49 +694,10 @@ GNUNET_NETWORK_socket_create (int domain, int type, int protocol) struct GNUNET_NETWORK_Handle *ret; ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); - ret->af = domain; ret->fd = socket (domain, type, protocol); - if (INVALID_SOCKET == ret->fd) - { -#ifdef MINGW - SetErrnoFromWinsockError (WSAGetLastError ()); -#endif - GNUNET_free (ret); - return NULL; - } - -#ifndef MINGW - if (ret->fd >= FD_SETSIZE) - { - GNUNET_break (0 == close (ret->fd)); - GNUNET_free (ret); - errno = EMFILE; - return NULL; - } - -#endif - if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO)) - { - /* we might want to treat this one as fatal... */ - GNUNET_break (0); - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret)); + if (GNUNET_OK != + initialize_network_handle (ret, domain, type)) return NULL; - } - -#ifndef MINGW - if (GNUNET_OK != socket_set_inheritable (ret)) - LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "socket_set_inheritable"); -#endif -#ifdef DARWIN - socket_set_nosigpipe (ret); -#endif - if ((type == SOCK_STREAM) -#ifdef AF_UNIX - && (domain != AF_UNIX) -#endif - ) - socket_set_nodelay (ret); return ret; } @@ -887,7 +865,29 @@ GNUNET_NETWORK_get_fd (struct GNUNET_NETWORK_Handle *desc) return desc->fd; } +/** + * Return sockaddr for this network handle + * + * @param desc wrapper to process + * @return sockaddr + */ +struct sockaddr* +GNUNET_NETWORK_get_addr (struct GNUNET_NETWORK_Handle *desc) +{ + return desc->addr; +} +/** + * Return sockaddr length for this network handle + * + * @param desc wrapper to process + * @return socklen_t for sockaddr + */ +socklen_t +GNUNET_NETWORK_get_addrlen (struct GNUNET_NETWORK_Handle *desc) +{ + return desc->addrlen; +} /** * Copy a native fd set * @@ -1047,9 +1047,6 @@ GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1, if (GNUNET_CONTAINER_slist_contains (fds2->handles, h, sizeof (struct GNUNET_DISK_FileHandle))) { -#if DEBUG_NETWORK - LOG (GNUNET_ERROR_TYPE_DEBUG, "Match!\n"); -#endif return GNUNET_YES; } GNUNET_CONTAINER_slist_next (&it); @@ -1105,7 +1102,6 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, const struct GNUNET_TIME_Relative timeout) { int nfds = 0; - #ifdef MINGW int handles = 0; int ex_handles = 0; @@ -1116,7 +1112,9 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, int retcode = 0; DWORD ms_total = 0; - int nsock = 0, nhandles = 0, nSockEvents = 0; + int nsock = 0; + int nhandles = 0; + int nSockEvents = 0; static HANDLE hEventRead = 0; static HANDLE hEventWrite = 0; @@ -1132,12 +1130,18 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, DWORD newretcode = 0; int returnedpos = 0; - struct GNUNET_CONTAINER_SList *handles_read, *handles_write, *handles_except; + struct GNUNET_CONTAINER_SList *handles_read; + struct GNUNET_CONTAINER_SList *handles_write; + struct GNUNET_CONTAINER_SList *handles_except; - fd_set aread, awrite, aexcept; + fd_set aread; + fd_set awrite; + fd_set aexcept; #if DEBUG_NETWORK - fd_set bread, bwrite, bexcept; + fd_set bread; + fd_set bwrite; + fd_set bexcept; #endif /* TODO: Make this growable */ @@ -1421,21 +1425,14 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, } handle_array[nhandles] = NULL; - -#if DEBUG_NETWORK - LOG (GNUNET_ERROR_TYPE_DEBUG, "Number nfds : %d\n", nfds); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Number of handles : %d\n", nhandles); - LOG (GNUNET_ERROR_TYPE_DEBUG, "retcode : %d\n", newretcode); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Will wait : %d\n", ms_total); -#endif - + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Number nfds: %d, handles: %d, return code: %u will wait: %d ms\n", + nfds, nhandles, newretcode, ms_total); if (nhandles) returncode = WaitForMultipleObjects (nhandles, handle_array, FALSE, ms_total); -#if DEBUG_NETWORK LOG (GNUNET_ERROR_TYPE_DEBUG, "WaitForMultipleObjects Returned : %d\n", returncode); -#endif returnedpos = returncode - WAIT_OBJECT_0; LOG (GNUNET_ERROR_TYPE_DEBUG, "return pos is : %d\n", returnedpos); @@ -1455,7 +1452,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, struct timeval tvslice; tvslice.tv_sec = 0; - tvslice.tv_usec = 10; + tvslice.tv_usec = 0; retcode = select (nfds, &aread, &awrite, &aexcept, &tvslice); if (retcode == -1) retcode = 0; @@ -1546,10 +1543,8 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, } } } -#if DEBUG_NETWORK if (!nhandles || (returnedpos >= nhandles)) LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning from _select() with nothing!\n"); -#endif if (rfds) { struct GNUNET_CONTAINER_SList_Iterator t; diff --git a/src/util/os_installation.c b/src/util/os_installation.c index b82813d..e790ce1 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -62,7 +62,7 @@ get_path_from_proc_maps () while (NULL != fgets (line, sizeof (line), f)) { if ((1 == - sscanf (line, "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s", dir)) && + SSCANF (line, "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s", dir)) && (NULL != (lgu = strstr (dir, "libgnunetutil")))) { lgu[0] = '\0'; diff --git a/src/util/os_priority.c b/src/util/os_priority.c index a1f173a..b8b1ba1 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c @@ -31,6 +31,7 @@ #include "gnunet_strings_lib.h" #include "gnunet_crypto_lib.h" #include "disk.h" +#include #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) @@ -299,7 +300,7 @@ npipe_open (const char *fn, } if (-1 == fd) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_INFO, (flags == GNUNET_DISK_OPEN_READ) ? _("Failed to open named pipe `%s' for reading: %s\n") : _("Failed to open named pipe `%s' for writing: %s\n"), @@ -325,29 +326,32 @@ parent_control_handler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_DISK_FileHandle *control_pipe = cls; - int sig; - + char sig; + ssize_t ret; + LOG (GNUNET_ERROR_TYPE_DEBUG, "`%s' invoked because of %d\n", __FUNCTION__, tc->reason); - if (tc->reason & - (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT | - GNUNET_SCHEDULER_REASON_PREREQ_DONE)) + if (0 != (tc->reason & + (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT))) { GNUNET_DISK_file_close (control_pipe); + control_pipe = NULL; return; } - if (GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig)) != - sizeof (sig)) + ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig)); + if (sizeof (sig) != ret) { - LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read"); + if (-1 == ret) + LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read"); GNUNET_DISK_file_close (control_pipe); + control_pipe = NULL; return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Got control code %d from parent\n", sig); GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, control_pipe, &parent_control_handler, control_pipe); - raise (sig); + raise ((int) sig); } @@ -425,27 +429,22 @@ int GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig) { int ret; + char csig; + csig = (char) sig; #if !WINDOWS if ( (NULL == proc->control_pipe) && (NULL != proc->childpipename) ) proc->control_pipe = npipe_open (proc->childpipename, GNUNET_DISK_OPEN_WRITE); #endif - if (NULL == proc->control_pipe) + if (NULL != proc->control_pipe) { -#if WINDOWS - /* no pipe and windows? can't do this */ - errno = EINVAL; - return -1; -#else - return kill (proc->pid, sig); -#endif + ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof (csig)); + if (ret == sizeof (csig)) + return 0; } - ret = GNUNET_DISK_file_write (proc->control_pipe, &sig, sizeof (sig)); - if (ret == sizeof (sig)) - return 0; - /* pipe failed, try other methods */ + /* pipe failed or non-existent, try other methods */ switch (sig) { #if !WINDOWS @@ -469,7 +468,7 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig) errno = EINVAL; return -1; #else - return kill (proc->pid, sig); + return PLIBC_KILL (proc->pid, sig); #endif } } @@ -488,13 +487,16 @@ GNUNET_OS_process_get_pid (struct GNUNET_OS_Process * proc) } +/** + * Cleans up process structure contents (OS-dependent) and deallocates it + * + * @param proc pointer to process structure + */ void -GNUNET_OS_process_close (struct GNUNET_OS_Process *proc) +GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc) { -#if ENABLE_WINDOWS_WORKAROUNDS - if (proc->control_pipe) + if (NULL != proc->control_pipe) GNUNET_DISK_file_close (proc->control_pipe); -#endif // FIXME NILS #ifdef WINDOWS if (proc->handle != NULL) @@ -648,10 +650,15 @@ GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc, static char * CreateCustomEnvTable (char **vars) { - char *win32_env_table, *ptr, **var_ptr, *result, *result_ptr; + char *win32_env_table; + char *ptr; + char **var_ptr; + char *result; + char *result_ptr; size_t tablesize = 0; size_t items_count = 0; - size_t n_found = 0, n_var; + size_t n_found = 0; + size_t n_var; char *index = NULL; size_t c; size_t var_len; @@ -804,8 +811,11 @@ GNUNET_OS_start_process_vap (int pipe_control, ret = fork (); if (-1 == ret) { + int eno = errno; + LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); GNUNET_free_non_null (childpipename); + errno = eno; return NULL; } if (0 != ret) @@ -863,7 +873,10 @@ GNUNET_OS_start_process_vap (int pipe_control, char *libdir; char *ptr; char *non_const_filename; - wchar_t wpath[MAX_PATH + 1], wcmd[32768]; + char win_path[MAX_PATH + 1]; + wchar_t *wpath, *wcmd; + size_t wpath_len, wcmd_len; + long lRet; /* Search in prefix dir (hopefully - the directory from which * the current module was loaded), bindir and libdir, then in PATH @@ -895,7 +908,22 @@ GNUNET_OS_start_process_vap (int pipe_control, else GNUNET_asprintf (&non_const_filename, "%s", filename); + /* It could be in POSIX form, convert it to a DOS path early on */ + if (ERROR_SUCCESS != (lRet = plibc_conv_to_win_path (non_const_filename, win_path))) + { + SetErrnoFromWinError (lRet); + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "plibc_conv_to_win_path", + non_const_filename); + GNUNET_free (non_const_filename); + GNUNET_free (pathbuf); + return NULL; + } + GNUNET_free (non_const_filename); + non_const_filename = GNUNET_strdup (win_path); /* Check that this is the full path. If it isn't, search. */ + /* FIXME: convert it to wchar_t and use SearchPathW? + * Remember: arguments to _start_process() are technically in UTF-8... + */ if (non_const_filename[1] == ':') snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); else if (!SearchPathA @@ -972,6 +1000,8 @@ GNUNET_OS_start_process_vap (int pipe_control, return NULL; } } + else + control_pipe = NULL; if (NULL != childpipename) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n", @@ -985,19 +1015,39 @@ GNUNET_OS_start_process_vap (int pipe_control, our_env[0] = NULL; } env_block = CreateCustomEnvTable (our_env); - GNUNET_free (our_env[0]); - GNUNET_free (our_env[1]); + GNUNET_free_non_null (our_env[0]); + GNUNET_free_non_null (our_env[1]); + + wpath_len = 0; + if (NULL == (wpath = u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", path, errno); + GNUNET_free (env_block); + GNUNET_free (cmd); + return NULL; + } + + wcmd_len = 0; + if (NULL == (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", cmd, errno); + GNUNET_free (env_block); + GNUNET_free (cmd); + free (wpath); + return NULL; + } - if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath) - || ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd) - || !CreateProcessW - (wpath, wcmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, - env_block, NULL, &start, &proc)) + if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, + DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc)) { SetErrnoFromWinError (GetLastError ()); LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path); GNUNET_free (env_block); GNUNET_free (cmd); + free (wpath); + free (wcmd); return NULL; } @@ -1014,7 +1064,8 @@ GNUNET_OS_start_process_vap (int pipe_control, CloseHandle (proc.hThread); GNUNET_free (cmd); - + free (wpath); + free (wcmd); return gnunet_proc; #endif } @@ -1136,9 +1187,12 @@ GNUNET_OS_start_process_v (int pipe_control, ret = fork (); if (-1 == ret) { + int eno = errno; + LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); GNUNET_free_non_null (childpipename); GNUNET_array_grow (lscp, ls, 0); + errno = eno; return NULL; } if (0 != ret) @@ -1220,13 +1274,16 @@ GNUNET_OS_start_process_v (int pipe_control, char *libdir; char *ptr; char *non_const_filename; + char win_path[MAX_PATH + 1]; struct GNUNET_DISK_PipeHandle *lsocks_pipe; const struct GNUNET_DISK_FileHandle *lsocks_write_fd; HANDLE lsocks_read; HANDLE lsocks_write; - wchar_t wpath[MAX_PATH + 1], wcmd[32768]; + wchar_t *wpath, *wcmd; + size_t wpath_len, wcmd_len; int env_off; int fail; + long lRet; /* Search in prefix dir (hopefully - the directory from which * the current module was loaded), bindir and libdir, then in PATH @@ -1263,7 +1320,22 @@ GNUNET_OS_start_process_v (int pipe_control, else GNUNET_asprintf (&non_const_filename, "%s", filename); - /* Check that this is the full path. If it isn't, search. */ + /* It could be in POSIX form, convert it to a DOS path early on */ + if (ERROR_SUCCESS != (lRet = plibc_conv_to_win_path (non_const_filename, win_path))) + { + SetErrnoFromWinError (lRet); + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "plibc_conv_to_win_path", + non_const_filename); + GNUNET_free (non_const_filename); + GNUNET_free (pathbuf); + return NULL; + } + GNUNET_free (non_const_filename); + non_const_filename = GNUNET_strdup (win_path); + /* Check that this is the full path. If it isn't, search. */ + /* FIXME: convert it to wchar_t and use SearchPathW? + * Remember: arguments to _start_process() are technically in UTF-8... + */ if (non_const_filename[1] == ':') snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); else if (!SearchPathA @@ -1345,6 +1417,8 @@ GNUNET_OS_start_process_v (int pipe_control, return NULL; } } + else + control_pipe = NULL; if (lsocks != NULL && lsocks[0] != INVALID_SOCKET) { lsocks_pipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); @@ -1384,11 +1458,30 @@ GNUNET_OS_start_process_v (int pipe_control, env_block = CreateCustomEnvTable (our_env); while (0 > env_off) GNUNET_free_non_null (our_env[--env_off]); - if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath) - || ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd) - || !CreateProcessW - (wpath, wcmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, - env_block, NULL, &start, &proc)) + + wpath_len = 0; + if (NULL == (wpath = u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", path, errno); + GNUNET_free (env_block); + GNUNET_free (cmd); + return NULL; + } + + wcmd_len = 0; + if (NULL == (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len))) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", cmd, errno); + GNUNET_free (env_block); + GNUNET_free (cmd); + free (wpath); + return NULL; + } + + if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, + DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc)) { SetErrnoFromWinError (GetLastError ()); LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); @@ -1398,6 +1491,8 @@ GNUNET_OS_start_process_v (int pipe_control, GNUNET_DISK_pipe_close (lsocks_pipe); GNUNET_free (env_block); GNUNET_free (cmd); + free (wpath); + free (wcmd); return NULL; } @@ -1413,6 +1508,8 @@ GNUNET_OS_start_process_v (int pipe_control, ResumeThread (proc.hThread); CloseHandle (proc.hThread); GNUNET_free (cmd); + free (wpath); + free (wcmd); if (lsocks == NULL || lsocks[0] == INVALID_SOCKET) return gnunet_proc; @@ -1499,7 +1596,9 @@ GNUNET_OS_start_process_v (int pipe_control, /** - * Retrieve the status of a process + * Retrieve the status of a process, waiting on him if dead. + * Nonblocking version. + * * @param proc process ID * @param type status type * @param code return code/signal number @@ -1716,7 +1815,7 @@ GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd) } (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (cmd->eip)); - GNUNET_OS_process_close (cmd->eip); + GNUNET_OS_process_destroy (cmd->eip); GNUNET_DISK_pipe_close (cmd->opipe); GNUNET_free (cmd); } diff --git a/src/util/program.c b/src/util/program.c index 6a0e5a5..9e1a83d 100644 --- a/src/util/program.c +++ b/src/util/program.c @@ -72,6 +72,11 @@ struct CommandContext }; +int +GNUNET_SPEEDUP_start_ (const struct GNUNET_CONFIGURATION_Handle *cfg); + +int +GNUNET_SPEEDUP_stop_ (void); /** * Initial task called by the scheduler for each @@ -81,6 +86,7 @@ static void program_main (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct CommandContext *cc = cls; + GNUNET_SPEEDUP_start_(cc->cfg); GNUNET_RESOLVER_connect (cc->cfg); cc->task (cc->task_cls, cc->args, cc->cfgfile, cc->cfg); @@ -95,10 +101,10 @@ program_main (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param a2 second command line option */ static int -cmd_sorter (__const void *a1, __const void *a2) +cmd_sorter (const void *a1, const void *a2) { - __const struct GNUNET_GETOPT_CommandLineOption *c1 = a1; - __const struct GNUNET_GETOPT_CommandLineOption *c2 = a2; + const struct GNUNET_GETOPT_CommandLineOption *c1 = a1; + const struct GNUNET_GETOPT_CommandLineOption *c2 = a2; if (toupper ((unsigned char) c1->shortName) > toupper ((unsigned char) c2->shortName)) @@ -125,13 +131,16 @@ cmd_sorter (__const void *a1, __const void *a2) * @param options command line options * @param task main function to run * @param task_cls closure for task + * @param run_without_scheduler GNUNET_NO start the scheduler, GNUNET_YES do not + * start the scheduler just run the main task * @return GNUNET_SYSERR on error, GNUNET_OK on success */ int -GNUNET_PROGRAM_run (int argc, char *const *argv, const char *binaryName, +GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, - GNUNET_PROGRAM_Main task, void *task_cls) + GNUNET_PROGRAM_Main task, void *task_cls, + int run_without_scheduler) { struct CommandContext cc; char *path; @@ -247,9 +256,17 @@ GNUNET_PROGRAM_run (int argc, char *const *argv, const char *binaryName, } /* run */ cc.args = &argv[ret]; - GNUNET_SCHEDULER_run (&program_main, &cc); - + if (GNUNET_NO == run_without_scheduler) + { + GNUNET_SCHEDULER_run (&program_main, &cc); + } + else + { + GNUNET_RESOLVER_connect (cc.cfg); + cc.task (cc.task_cls, cc.args, cc.cfgfile, cc.cfg); + } /* clean up */ + GNUNET_SPEEDUP_stop_ (); GNUNET_CONFIGURATION_destroy (cfg); GNUNET_free_non_null (cc.cfgfile); GNUNET_free_non_null (loglev); @@ -257,5 +274,28 @@ GNUNET_PROGRAM_run (int argc, char *const *argv, const char *binaryName, return GNUNET_OK; } +/** + * Run a standard GNUnet command startup sequence (initialize loggers + * and configuration, parse options). + * + * @param argc number of command line arguments + * @param argv command line arguments + * @param binaryName our expected name + * @param binaryHelp help text for the program + * @param options command line options + * @param task main function to run + * @param task_cls closure for task + * @return GNUNET_SYSERR on error, GNUNET_OK on success + */ +int +GNUNET_PROGRAM_run (int argc, char *const *argv, const char *binaryName, + const char *binaryHelp, + const struct GNUNET_GETOPT_CommandLineOption *options, + GNUNET_PROGRAM_Main task, void *task_cls) +{ + return GNUNET_PROGRAM_run2 (argc, argv, binaryName, binaryHelp, options, task, task_cls, GNUNET_NO); +} + + /* end of program.c */ diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c index 782a405..0165738 100644 --- a/src/util/pseudonym.c +++ b/src/util/pseudonym.c @@ -96,7 +96,7 @@ internal_notify (const GNUNET_HashCode * id, pos = head; while (pos != NULL) { - pos->callback (pos->closure, id, md, rating); + pos->callback (pos->closure, id, NULL, NULL, md, rating); pos = pos->next; } } @@ -104,6 +104,9 @@ internal_notify (const GNUNET_HashCode * id, /** * Register callback to be invoked whenever we discover * a new pseudonym. + * Will immediately call provided iterator callback for all + * already discovered pseudonyms. + * * @param cfg configuration to use * @param iterator iterator over pseudonym * @param closure point to a closure @@ -185,7 +188,7 @@ get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param nsid hash code of a pseudonym * @param meta meta data to be written into a file * @param ranking ranking of a pseudonym - * @param ns_name name of a pseudonym + * @param ns_name non-unique name of a pseudonym */ static void write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg, @@ -219,9 +222,9 @@ write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg, } GNUNET_free (fn); /* create entry for pseudonym name in names */ - /* FIXME: 90% of what this call does is not needed - * here => refactor code to only create the entry! */ - GNUNET_free_non_null (GNUNET_PSEUDONYM_id_to_name (cfg, nsid)); + if (ns_name != NULL) + GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, nsid, ns_name, + NULL)); } @@ -286,63 +289,38 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, } - /** - * Return the unique, human readable name for the given namespace. + * Return unique variant of the namespace name. + * Use it after GNUNET_PSEUDONYM_get_info() to make sure + * that name is unique. * * @param cfg configuration * @param nsid cryptographic ID of the namespace - * @return NULL on failure (should never happen) + * @param name name to uniquify + * @param suffix if not NULL, filled with the suffix value + * @return NULL on failure (should never happen), name on success. + * Free the name with GNUNET_free(). */ char * -GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg, - const GNUNET_HashCode * nsid) +GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, const char *name, unsigned int *suffix) { - struct GNUNET_CONTAINER_MetaData *meta; - char *name; GNUNET_HashCode nh; - char *fn; uint64_t len; + char *fn; struct GNUNET_DISK_FileHandle *fh; unsigned int i; unsigned int idx; char *ret; struct stat sbuf; - int32_t temp = 0; - int32_t *rank = &temp; - meta = NULL; - name = NULL; - if (GNUNET_OK == read_info (cfg, nsid, &meta, rank, &name)) - { - if ((meta != NULL) && (name == NULL)) - name = - GNUNET_CONTAINER_meta_data_get_first_by_types (meta, - EXTRACTOR_METATYPE_TITLE, - EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, - EXTRACTOR_METATYPE_FILENAME, - EXTRACTOR_METATYPE_DESCRIPTION, - EXTRACTOR_METATYPE_SUBJECT, - EXTRACTOR_METATYPE_PUBLISHER, - EXTRACTOR_METATYPE_AUTHOR_NAME, - EXTRACTOR_METATYPE_COMMENT, - EXTRACTOR_METATYPE_SUMMARY, - -1); - if (meta != NULL) - { - GNUNET_CONTAINER_meta_data_destroy (meta); - meta = NULL; - } - } - if (name == NULL) - name = GNUNET_strdup (_("no-name")); GNUNET_CRYPTO_hash (name, strlen (name), &nh); fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); GNUNET_assert (fn != NULL); len = 0; if (0 == STAT (fn, &sbuf)) - GNUNET_DISK_file_size (fn, &len, GNUNET_YES); + GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES)); fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_READWRITE, @@ -372,22 +350,107 @@ GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_DISK_file_close (fh); ret = GNUNET_malloc (strlen (name) + 32); GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx); - GNUNET_free (name); + if (suffix != NULL) + *suffix = idx; GNUNET_free (fn); return ret; } +/** + * Get namespace name, metadata and rank + * This is a wrapper around internal read_info() call, and ensures that + * returned data is not invalid (not NULL). + * + * @param cfg configuration + * @param nsid cryptographic ID of the namespace + * @param ret_meta a location to store metadata pointer. NULL, if metadata + * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy(). + * @param ret_rank a location to store rank. NULL, if rank not needed. + * @param ret_name a location to store human-readable name. Name is not unique. + * NULL, if name is not needed. Free with GNUNET_free(). + * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with + * a duplicate of a "no-name" placeholder + * @return GNUNET_OK on success. GNUENT_SYSERR if the data was + * unobtainable (in that case ret_* are filled with placeholders - + * empty metadata container, rank -1 and a "no-name" name). + */ +int +GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta, + int32_t *ret_rank, char **ret_name, int *name_is_a_dup) +{ + struct GNUNET_CONTAINER_MetaData *meta; + char *name; + int32_t rank = -1; + + meta = NULL; + name = NULL; + if (GNUNET_OK == read_info (cfg, nsid, &meta, &rank, &name)) + { + if ((meta != NULL) && (name == NULL)) + name = + GNUNET_CONTAINER_meta_data_get_first_by_types (meta, + EXTRACTOR_METATYPE_TITLE, + EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, + EXTRACTOR_METATYPE_FILENAME, + EXTRACTOR_METATYPE_DESCRIPTION, + EXTRACTOR_METATYPE_SUBJECT, + EXTRACTOR_METATYPE_PUBLISHER, + EXTRACTOR_METATYPE_AUTHOR_NAME, + EXTRACTOR_METATYPE_COMMENT, + EXTRACTOR_METATYPE_SUMMARY, + -1); + if (ret_name != NULL) + { + if (name == NULL) + { + name = GNUNET_strdup (_("no-name")); + if (name_is_a_dup != NULL) + *name_is_a_dup = GNUNET_YES; + } + else if (name_is_a_dup != NULL) + *name_is_a_dup = GNUNET_NO; + *ret_name = name; + } + else if (name != NULL) + GNUNET_free (name); + + if (ret_meta != NULL) + { + if (meta == NULL) + meta = GNUNET_CONTAINER_meta_data_create (); + *ret_meta = meta; + } + else if (meta != NULL) + GNUNET_CONTAINER_meta_data_destroy (meta); + + if (ret_rank != NULL) + *ret_rank = rank; + + return GNUNET_OK; + } + if (ret_name != NULL) + *ret_name = GNUNET_strdup (_("no-name")); + if (ret_meta != NULL) + *ret_meta = GNUNET_CONTAINER_meta_data_create (); + if (ret_rank != NULL) + *ret_rank = -1; + if (name_is_a_dup != NULL) + *name_is_a_dup = GNUNET_YES; + return GNUNET_SYSERR; +} + /** * Get the namespace ID belonging to the given namespace name. * * @param cfg configuration to use - * @param ns_uname human-readable name for the namespace + * @param ns_uname unique (!) human-readable name for the namespace * @param nsid set to namespace ID based on 'ns_uname' - * @return GNUNET_OK on success + * @return GNUNET_OK on success, GNUNET_SYSERR on failure */ int GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *ns_uname, GNUNET_HashCode * nsid) + const char *ns_uname, GNUNET_HashCode * nsid) { size_t slen; uint64_t len; @@ -399,19 +462,20 @@ GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, idx = -1; slen = strlen (ns_uname); - while ((slen > 0) && (1 != sscanf (&ns_uname[slen - 1], "-%u", &idx))) + while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx))) slen--; if (slen == 0) return GNUNET_SYSERR; name = GNUNET_strdup (ns_uname); name[slen - 1] = '\0'; + GNUNET_CRYPTO_hash (name, strlen (name), &nh); GNUNET_free (name); fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); GNUNET_assert (fn != NULL); if ((GNUNET_OK != GNUNET_DISK_file_test (fn) || - (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES))) || + (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) || ((idx + 1) * sizeof (GNUNET_HashCode) > len)) { GNUNET_free (fn); @@ -472,10 +536,11 @@ list_pseudonym_helper (void *cls, const char *fullname) struct ListPseudonymClosure *c = cls; int ret; GNUNET_HashCode id; - int rating; + int32_t rating; struct GNUNET_CONTAINER_MetaData *meta; const char *fn; char *str; + char *name_unique; if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) return GNUNET_OK; @@ -487,11 +552,22 @@ list_pseudonym_helper (void *cls, const char *fullname) if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id)) return GNUNET_OK; /* invalid name */ str = NULL; - if (GNUNET_OK != read_info (c->cfg, &id, &meta, &rating, &str)) - return GNUNET_OK; /* ignore entry */ - GNUNET_free_non_null (str); + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (c->cfg, &id, &meta, &rating, + &str, NULL)) + { + /* ignore entry. FIXME: Why? Lack of data about a pseudonym is not a reason + * to ignore it... So yeah, it will have placeholders instead of name, + * empty metadata container and a default rank == -1, so what? We know + * its nsid - that's all we really need. Right? */ + GNUNET_free (str); + GNUNET_CONTAINER_meta_data_destroy (meta); + return GNUNET_OK; + } + name_unique = GNUNET_PSEUDONYM_name_uniquify (c->cfg, &id, str, NULL); if (c->iterator != NULL) - ret = c->iterator (c->closure, &id, meta, rating); + ret = c->iterator (c->closure, &id, str, name_unique, meta, rating); + GNUNET_free_non_null (str); + GNUNET_free_non_null (name_unique); GNUNET_CONTAINER_meta_data_destroy (meta); return ret; } @@ -558,6 +634,31 @@ GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, } +/** + * Set the pseudonym metadata, rank and name. + * + * @param cfg overall configuration + * @param nsid id of the pseudonym + * @param name name to set. Must be the non-unique version of it. + * May be NULL, in which case it erases pseudonym's name! + * @param md metadata to set + * May be NULL, in which case it erases pseudonym's metadata! + * @param rank rank to assign + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int +GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, const char *name, + const struct GNUNET_CONTAINER_MetaData *md, int rank) +{ + GNUNET_assert (cfg != NULL); + GNUNET_assert (nsid != NULL); + + write_pseudonym_info (cfg, nsid, md, rank, name); + return GNUNET_OK; +} + + /** * Add a pseudonym to the set of known pseudonyms. * For all pseudonym advertisements that we discover diff --git a/src/util/resolver.conf.in b/src/util/resolver.conf.in index 671ea0e..7abe1c9 100644 --- a/src/util/resolver.conf.in +++ b/src/util/resolver.conf.in @@ -1,6 +1,6 @@ [resolver] AUTOSTART = YES -@UNIXONLY@ PORT = 2089 +@JAVAPORT@PORT = 2089 HOSTNAME = localhost HOME = $SERVICEHOME CONFIG = $DEFAULTCONFIG diff --git a/src/util/resolver.h b/src/util/resolver.h index 2c0de99..b77c199 100644 --- a/src/util/resolver.h +++ b/src/util/resolver.h @@ -27,8 +27,6 @@ #include "gnunet_common.h" -#define DEBUG_RESOLVER GNUNET_EXTRA_LOGGING - GNUNET_NETWORK_STRUCT_BEGIN /** diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index 9d5ae6c..87b76f1 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c @@ -250,10 +250,8 @@ GNUNET_RESOLVER_disconnect () GNUNET_assert (NULL == req_tail); if (NULL != client) { -#if DEBUG_RESOLVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from DNS service\n"); -#endif - GNUNET_CLIENT_disconnect (client, GNUNET_NO); + GNUNET_CLIENT_disconnect (client); client = NULL; } if (r_task != GNUNET_SCHEDULER_NO_TASK) @@ -339,9 +337,7 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) struct GNUNET_RESOLVER_RequestHandle *rh = cls; uint16_t size; -#if DEBUG_RESOLVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving response from DNS service\n"); -#endif if (msg == NULL) { char buf[INET6_ADDRSTRLEN]; @@ -374,7 +370,7 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) } GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); GNUNET_free (rh); - GNUNET_CLIENT_disconnect (client, GNUNET_NO); + GNUNET_CLIENT_disconnect (client); client = NULL; reconnect (); return; @@ -382,7 +378,7 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type)) { GNUNET_break (0); - GNUNET_CLIENT_disconnect (client, GNUNET_NO); + GNUNET_CLIENT_disconnect (client); client = NULL; reconnect (); return; @@ -417,15 +413,13 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) rh->name_callback (rh->cls, NULL); GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); GNUNET_free (rh); - GNUNET_CLIENT_disconnect (client, GNUNET_NO); + GNUNET_CLIENT_disconnect (client); client = NULL; reconnect (); return; } -#if DEBUG_RESOLVER - LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s' for IP `%s'.\n"), + LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolver returns `%s' for IP `%s'.\n", hostname, GNUNET_a2s ((const void *) &rh[1], rh->data_len)); -#endif if (rh->was_transmitted != GNUNET_SYSERR) rh->name_callback (rh->cls, hostname); rh->received_response = GNUNET_YES; @@ -473,7 +467,7 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) rh->addr_callback (rh->cls, NULL, 0); GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); GNUNET_free (rh); - GNUNET_CLIENT_disconnect (client, GNUNET_NO); + GNUNET_CLIENT_disconnect (client); client = NULL; reconnect (); return; @@ -606,7 +600,7 @@ static void process_requests () { struct GNUNET_RESOLVER_GetMessage *msg; - char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; + char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; struct GNUNET_RESOLVER_RequestHandle *rh; if (NULL == client) @@ -633,17 +627,15 @@ process_requests () msg->direction = htonl (rh->direction); msg->af = htonl (rh->af); memcpy (&msg[1], &rh[1], rh->data_len); -#if DEBUG_RESOLVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting DNS resolution request to DNS service\n"); -#endif if (GNUNET_OK != GNUNET_CLIENT_transmit_and_get_response (client, &msg->header, GNUNET_TIME_absolute_get_remaining (rh->timeout), GNUNET_YES, &handle_response, rh)) { - GNUNET_CLIENT_disconnect (client, GNUNET_NO); + GNUNET_CLIENT_disconnect (client); client = NULL; reconnect (); return; @@ -666,9 +658,7 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) return; /* no work pending */ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; -#if DEBUG_RESOLVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to DNS service\n"); -#endif client = GNUNET_CLIENT_connect ("resolver", resolver_cfg); if (NULL == client) { @@ -712,11 +702,9 @@ reconnect () break; } } -#if DEBUG_RESOLVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Will try to connect to DNS service in %llu ms\n", (unsigned long long) backoff.rel_value); -#endif GNUNET_assert (NULL != resolver_cfg); r_task = GNUNET_SCHEDULER_add_delayed (backoff, &reconnect_task, NULL); backoff = GNUNET_TIME_relative_multiply (backoff, 2); @@ -803,9 +791,7 @@ numeric_reverse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) char *result; result = no_resolve (rh->af, &rh[1], rh->data_len); -#if DEBUG_RESOLVER - LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s'.\n"), result); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolver returns `%s'.\n", result); if (result != NULL) { rh->name_callback (rh->cls, result); @@ -897,9 +883,7 @@ GNUNET_RESOLVER_local_fqdn_get () "gethostname"); return NULL; } -#if DEBUG_RESOLVER - LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our FQDN `%s'\n"), hostname); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolving our FQDN `%s'\n", hostname); host = gethostbyname (hostname); if (NULL == host) { @@ -934,9 +918,7 @@ GNUNET_RESOLVER_hostname_resolve (int af, "gethostname"); return NULL; } -#if DEBUG_RESOLVER - LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our hostname `%s'\n"), hostname); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolving our hostname `%s'\n", hostname); return GNUNET_RESOLVER_ip_get (hostname, af, timeout, callback, cls); } diff --git a/src/util/scheduler.c b/src/util/scheduler.c index c54672f..45cc020 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c @@ -114,11 +114,6 @@ struct Task */ GNUNET_SCHEDULER_TaskIdentifier id; - /** - * Identifier of a prerequisite task. - */ - GNUNET_SCHEDULER_TaskIdentifier prereq_id; - /** * Absolute timeout value for the task, or * GNUNET_TIME_UNIT_FOREVER_ABS for "no timeout". @@ -215,13 +210,6 @@ static struct Task *ready[GNUNET_SCHEDULER_PRIORITY_COUNT]; */ static GNUNET_SCHEDULER_TaskIdentifier last_id; -/** - * Highest number so that all tasks with smaller identifiers - * have already completed. Also the lowest number of a task - * still waiting to be executed. - */ -static GNUNET_SCHEDULER_TaskIdentifier lowest_pending_id; - /** * Number of tasks on the ready list. */ @@ -292,60 +280,6 @@ check_priority (enum GNUNET_SCHEDULER_Priority p) } -/** - * Is a task with this identifier still pending? Also updates - * "lowest_pending_id" as a side-effect (for faster checks in the - * future), but only if the return value is "GNUNET_NO" (and - * the "lowest_pending_id" check failed). - * - * @param id which task are we checking for - * @return GNUNET_YES if so, GNUNET_NO if not - */ -static int -is_pending (GNUNET_SCHEDULER_TaskIdentifier id) -{ - struct Task *pos; - enum GNUNET_SCHEDULER_Priority p; - GNUNET_SCHEDULER_TaskIdentifier min; - - if (id < lowest_pending_id) - return GNUNET_NO; - min = -1; /* maximum value */ - pos = pending; - while (pos != NULL) - { - if (pos->id == id) - return GNUNET_YES; - if (pos->id < min) - min = pos->id; - pos = pos->next; - } - pos = pending_timeout; - while (pos != NULL) - { - if (pos->id == id) - return GNUNET_YES; - if (pos->id < min) - min = pos->id; - pos = pos->next; - } - for (p = 0; p < GNUNET_SCHEDULER_PRIORITY_COUNT; p++) - { - pos = ready[p]; - while (pos != NULL) - { - if (pos->id == id) - return GNUNET_YES; - if (pos->id < min) - min = pos->id; - pos = pos->next; - } - } - lowest_pending_id = min; - return GNUNET_NO; -} - - /** * Update all sets and timeout for select. * @@ -374,12 +308,6 @@ update_sets (struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws, pos = pending; while (pos != NULL) { - if ((pos->prereq_id != GNUNET_SCHEDULER_NO_TASK) && - (GNUNET_YES == is_pending (pos->prereq_id))) - { - pos = pos->next; - continue; - } if (pos->timeout.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value) { to = GNUNET_TIME_absolute_get_difference (now, pos->timeout); @@ -459,15 +387,7 @@ is_ready (struct Task *task, struct GNUNET_TIME_Absolute now, reason |= GNUNET_SCHEDULER_REASON_WRITE_READY; if (reason == 0) return GNUNET_NO; /* not ready */ - if (task->prereq_id != GNUNET_SCHEDULER_NO_TASK) - { - if (GNUNET_YES == is_pending (task->prereq_id)) - { - task->reason = reason; - return GNUNET_NO; /* prereq waiting */ - } - reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE; - } + reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE; task->reason = reason; return GNUNET_YES; } @@ -1106,31 +1026,6 @@ GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_Task task, void *task_cls, } -/** - * Schedule a new task to be run after the specified prerequisite task - * has completed. It will be run with the DEFAULT priority. - * - * @param prerequisite_task run this task after the task with the given - * task identifier completes (and any of our other - * conditions, such as delay, read or write-readiness - * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency - * on completion of other tasks (this will cause the task to run as - * soon as possible). - * @param task main function of the task - * @param task_cls closure of task - * @return unique task identifier for the job - * only valid until "task" is started! - */ -GNUNET_SCHEDULER_TaskIdentifier -GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_TaskIdentifier prerequisite_task, - GNUNET_SCHEDULER_Task task, void *task_cls) -{ - return GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - prerequisite_task, GNUNET_TIME_UNIT_ZERO, - NULL, NULL, task, task_cls); -} - - /** * Schedule a new task to be run with a specified priority. * @@ -1144,7 +1039,7 @@ GNUNET_SCHEDULER_TaskIdentifier GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_Task task, void *task_cls) { - return GNUNET_SCHEDULER_add_select (prio, GNUNET_SCHEDULER_NO_TASK, + return GNUNET_SCHEDULER_add_select (prio, GNUNET_TIME_UNIT_ZERO, NULL, NULL, task, task_cls); } @@ -1299,7 +1194,6 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_UNIT_ZERO, NULL, NULL, task, task_cls); GNUNET_assert (pending->id == ret); @@ -1399,7 +1293,6 @@ add_without_sets (struct GNUNET_TIME_Relative delay, #if PROFILE_DELAYS t->start_time = GNUNET_TIME_absolute_get (); #endif - t->prereq_id = GNUNET_SCHEDULER_NO_TASK; t->timeout = GNUNET_TIME_relative_to_absolute (delay); t->priority = check_priority ((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority); t->lifeness = current_lifeness; @@ -1440,6 +1333,35 @@ GNUNET_SCHEDULER_TaskIdentifier GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_Task task, void *task_cls) +{ + return GNUNET_SCHEDULER_add_read_net_with_priority (delay, + GNUNET_SCHEDULER_PRIORITY_DEFAULT, + rfd, task, task_cls); +} + + +/** + * Schedule a new task to be run with a specified priority and to be + * run after the specified delay or when the specified file descriptor + * is ready for reading. The delay can be used as a timeout on the + * socket being ready. The task will be scheduled for execution once + * either the delay has expired or the socket operation is ready. It + * will be run with the DEFAULT priority. + * + * @param delay when should this operation time out? Use + * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown" + * @param priority priority to use for the task + * @param rfd read file-descriptor + * @param task main function of the task + * @param task_cls closure of task + * @return unique task identifier for the job + * only valid until "task" is started! + */ +GNUNET_SCHEDULER_TaskIdentifier +GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay, + enum GNUNET_SCHEDULER_Priority priority, + struct GNUNET_NETWORK_Handle *rfd, + GNUNET_SCHEDULER_Task task, void *task_cls) { #if MINGW struct GNUNET_NETWORK_FDSet *rs; @@ -1449,20 +1371,21 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay, rs = GNUNET_NETWORK_fdset_create (); GNUNET_NETWORK_fdset_set (rs, rfd); ret = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, delay, rs, NULL, + GNUNET_SCHEDULER_add_select (priority, + delay, rs, NULL, task, task_cls); GNUNET_NETWORK_fdset_destroy (rs); return ret; #else return add_without_sets (delay, - GNUNET_SCHEDULER_PRIORITY_DEFAULT, + priority, GNUNET_NETWORK_get_fd (rfd), -1, task, task_cls); #endif } + /** * Schedule a new task to be run with a specified delay or when the * specified file descriptor is ready for writing. The delay can be @@ -1493,7 +1416,7 @@ GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay, GNUNET_NETWORK_fdset_set (ws, wfd); ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, delay, NULL, ws, + delay, NULL, ws, task, task_cls); GNUNET_NETWORK_fdset_destroy (ws); return ret; @@ -1536,7 +1459,7 @@ GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay, GNUNET_NETWORK_fdset_handle_set (rs, rfd); ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, delay, rs, NULL, + delay, rs, NULL, task, task_cls); GNUNET_NETWORK_fdset_destroy (rs); return ret; @@ -1581,7 +1504,7 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, GNUNET_NETWORK_fdset_handle_set (ws, wfd); ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, delay, NULL, ws, + delay, NULL, ws, task, task_cls); GNUNET_NETWORK_fdset_destroy (ws); return ret; @@ -1617,11 +1540,6 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, * * * @param prio how important is this task? - * @param prerequisite_task run this task after the task with the given - * task identifier completes (and any of our other - * conditions, such as delay, read or write-readiness - * are satisfied). Use GNUNET_SCHEDULER_NO_TASK to not have any dependency - * on completion of other tasks. * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever", * which means that the task will only be run after we receive SIGTERM * @param rs set of file descriptors we want to read (can be NULL) @@ -1633,7 +1551,6 @@ GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, */ GNUNET_SCHEDULER_TaskIdentifier GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, - GNUNET_SCHEDULER_TaskIdentifier prerequisite_task, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, @@ -1671,7 +1588,6 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, #if PROFILE_DELAYS t->start_time = GNUNET_TIME_absolute_get (); #endif - t->prereq_id = prerequisite_task; t->timeout = GNUNET_TIME_relative_to_absolute (delay); t->priority = check_priority ((prio == diff --git a/src/util/server.c b/src/util/server.c index 24804d2..409e89f 100644 --- a/src/util/server.c +++ b/src/util/server.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) + (C) 2009, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -26,11 +26,7 @@ #include "platform.h" #include "gnunet_common.h" -#include "gnunet_connection_lib.h" -#include "gnunet_scheduler_lib.h" -#include "gnunet_server_lib.h" -#include "gnunet_time_lib.h" -#include "gnunet_disk_lib.h" +#include "gnunet_util_lib.h" #include "gnunet_protocols.h" #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) @@ -39,7 +35,6 @@ #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) -#define DEBUG_SERVER GNUNET_EXTRA_LOGGING /** * List of arrays of message handlers. @@ -64,10 +59,15 @@ struct HandlerList struct NotifyList { /** - * This is a linked list. + * This is a doubly linked list. */ struct NotifyList *next; + /** + * This is a doubly linked list. + */ + struct NotifyList *prev; + /** * Function to call. */ @@ -91,14 +91,24 @@ struct GNUNET_SERVER_Handle struct HandlerList *handlers; /** - * List of our current clients. + * Head of list of our current clients. */ - struct GNUNET_SERVER_Client *clients; + struct GNUNET_SERVER_Client *clients_head; /** - * Linked list of functions to call on disconnects by clients. + * Head of list of our current clients. */ - struct NotifyList *disconnect_notify_list; + struct GNUNET_SERVER_Client *clients_tail; + + /** + * Head of linked list of functions to call on disconnects by clients. + */ + struct NotifyList *disconnect_notify_list_head; + + /** + * Tail of linked list of functions to call on disconnects by clients. + */ + struct NotifyList *disconnect_notify_list_tail; /** * Function to call for access control. @@ -127,6 +137,26 @@ struct GNUNET_SERVER_Handle */ GNUNET_SCHEDULER_TaskIdentifier listen_task; + /** + * Alternative function to create a MST instance. + */ + GNUNET_SERVER_MstCreateCallback mst_create; + + /** + * Alternative function to destroy a MST instance. + */ + GNUNET_SERVER_MstDestroyCallback mst_destroy; + + /** + * Alternative function to give data to a MST instance. + */ + GNUNET_SERVER_MstReceiveCallback mst_receive; + + /** + * Closure for 'mst_'-callbacks. + */ + void *mst_cls; + /** * Do we ignore messages of types that we do not understand or do we * require that a handler is found (and if not kill the connection)? @@ -134,16 +164,36 @@ struct GNUNET_SERVER_Handle int require_found; /** - * Should all of the clients of this server continue to process - * connections as usual even if we get a shutdown request? (the - * listen socket always ignores shutdown). + * Set to GNUNET_YES once we are in 'soft' shutdown where we wait for + * all non-monitor clients to disconnect before we call + * GNUNET_SERVER_destroy. See 'test_monitor_clients'. Set to + * GNUNET_SYSERR once the final destroy task has been scheduled + * (we cannot run it in the same task). */ - int clients_ignore_shutdown; + int in_soft_shutdown; +}; + + +/** + * Handle server returns for aborting transmission to a client. + */ +struct GNUNET_SERVER_TransmitHandle +{ + /** + * Function to call to get the message. + */ + GNUNET_CONNECTION_TransmitReadyNotify callback; + + /** + * Closure for 'callback' + */ + void *callback_cls; + + /** + * Active connection transmission handle. + */ + struct GNUNET_CONNECTION_TransmitHandle *cth; - GNUNET_SERVER_MstCreateCallback mst_create; - GNUNET_SERVER_MstDestroyCallback mst_destroy; - GNUNET_SERVER_MstReceiveCallback mst_receive; - void *mst_cls; }; @@ -154,10 +204,15 @@ struct GNUNET_SERVER_Client { /** - * This is a linked list. + * This is a doubly linked list. */ struct GNUNET_SERVER_Client *next; + /** + * This is a doubly linked list. + */ + struct GNUNET_SERVER_Client *prev; + /** * Processing of incoming data. */ @@ -195,14 +250,10 @@ struct GNUNET_SERVER_Client struct GNUNET_TIME_Absolute last_activity; /** - * + * Transmission handle we return for this client from + * GNUNET_SERVER_notify_transmit_ready. */ - GNUNET_CONNECTION_TransmitReadyNotify callback; - - /** - * callback - */ - void *callback_cls; + struct GNUNET_SERVER_TransmitHandle th; /** * After how long should an idle connection time @@ -235,8 +286,7 @@ struct GNUNET_SERVER_Client int in_process_client_buffer; /** - * We're about to close down this client due to some serious - * error. + * We're about to close down this client. */ int shutdown_now; @@ -258,6 +308,13 @@ struct GNUNET_SERVER_Client */ int persist; + /** + * Is this client a 'monitor' client that should not be counted + * when deciding on destroying the server during soft shutdown? + * (see also GNUNET_SERVICE_start) + */ + int is_monitor; + /** * Type of last message processed (for warn_no_receive_done). */ @@ -273,28 +330,66 @@ struct GNUNET_SERVER_Client * @param tc reason why we are running right now */ static void -process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + + +/** + * Add a listen task with the scheduler for this server. + * + * @param server handle to our server for which we are adding the listen + * socket + */ +static void +schedule_listen_task (struct GNUNET_SERVER_Handle *server) { - struct GNUNET_SERVER_Handle *server = cls; - struct GNUNET_CONNECTION_Handle *sock; - struct GNUNET_SERVER_Client *client; struct GNUNET_NETWORK_FDSet *r; unsigned int i; - server->listen_task = GNUNET_SCHEDULER_NO_TASK; + if (NULL == server->listen_sockets[0]) + return; /* nothing to do, no listen sockets! */ + if (NULL == server->listen_sockets[1]) + { + /* simplified method: no fd set needed; this is then much simpler and + much more efficient */ + server->listen_task = + GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_SCHEDULER_PRIORITY_HIGH, + server->listen_sockets[0], + &process_listen_socket, server); + return; + } r = GNUNET_NETWORK_fdset_create (); i = 0; while (NULL != server->listen_sockets[i]) GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]); + server->listen_task = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, + GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, + &process_listen_socket, server); + GNUNET_NETWORK_fdset_destroy (r); +} + + +/** + * Scheduler says our listen socket is ready. Process it! + * + * @param cls handle to our server for which we are processing the listen + * socket + * @param tc reason why we are running right now + */ +static void +process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_SERVER_Handle *server = cls; + struct GNUNET_CONNECTION_Handle *sock; + struct GNUNET_SERVER_Client *client; + unsigned int i; + + server->listen_task = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { /* ignore shutdown, someone else will take care of it! */ - server->listen_task = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, - GNUNET_SCHEDULER_NO_TASK, - GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, - &process_listen_socket, server); - GNUNET_NETWORK_fdset_destroy (r); + schedule_listen_task (server); return; } i = 0; @@ -306,14 +401,10 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONNECTION_create_from_accept (server->access, server->access_cls, server->listen_sockets[i]); - if (sock != NULL) + if (NULL != sock) { -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server accepted incoming connection.\n"); -#endif client = GNUNET_SERVER_connect_socket (server, sock); - GNUNET_CONNECTION_ignore_shutdown (sock, - server->clients_ignore_shutdown); /* decrement reference count, we don't keep "client" alive */ GNUNET_SERVER_client_drop (client); } @@ -321,12 +412,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) i++; } /* listen for more! */ - server->listen_task = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, - GNUNET_SCHEDULER_NO_TASK, - GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, - &process_listen_socket, server); - GNUNET_NETWORK_fdset_destroy (r); + schedule_listen_task (server); } @@ -340,7 +426,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static struct GNUNET_NETWORK_Handle * open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen) { - const static int on = 1; + static int on = 1; struct GNUNET_NETWORK_Handle *sock; uint16_t port; int eno; @@ -368,14 +454,14 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen) errno = 0; return NULL; } - if (port != 0) + if (0 != port) { if (GNUNET_NETWORK_socket_setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "setsockopt"); #ifdef IPV6_V6ONLY - if ((serverAddr->sa_family == AF_INET6) && + if ((AF_INET6 == serverAddr->sa_family) && (GNUNET_NETWORK_socket_setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK)) LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, @@ -383,30 +469,30 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen) #endif } /* bind the socket */ - if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK) + if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen)) { eno = errno; - if (errno != EADDRINUSE) + if (EADDRINUSE != errno) { /* we don't log 'EADDRINUSE' here since an IPv4 bind may * fail if we already took the port on IPv6; if both IPv4 and * IPv6 binds fail, then our caller will log using the * errno preserved in 'eno' */ LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); - if (port != 0) + if (0 != port) LOG (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed for port %d (%s).\n"), "bind", port, - (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); + (AF_INET == serverAddr->sa_family) ? "IPv4" : "IPv6"); eno = 0; } else { - if (port != 0) + if (0 != port) LOG (GNUNET_ERROR_TYPE_WARNING, _("`%s' failed for port %d (%s): address already in use\n"), "bind", port, - (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); - else if (serverAddr->sa_family == AF_UNIX) + (AF_INET == serverAddr->sa_family) ? "IPv4" : "IPv6"); + else if (AF_UNIX == serverAddr->sa_family) LOG (GNUNET_ERROR_TYPE_WARNING, _("`%s' failed for `%s': address already in use\n"), "bind", ((const struct sockaddr_un *) serverAddr)->sun_path); @@ -423,11 +509,9 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen) errno = 0; return NULL; } -#if DEBUG_SERVER - if (port != 0) + if (0 != port) LOG (GNUNET_ERROR_TYPE_DEBUG, "Server starts to listen on port %u.\n", port); -#endif return sock; } @@ -451,30 +535,17 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, struct GNUNET_TIME_Relative idle_timeout, int require_found) { - struct GNUNET_SERVER_Handle *ret; - struct GNUNET_NETWORK_FDSet *r; - int i; - - ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle)); - ret->idle_timeout = idle_timeout; - ret->listen_sockets = lsocks; - ret->access = access; - ret->access_cls = access_cls; - ret->require_found = require_found; - if (lsocks != NULL) - { - r = GNUNET_NETWORK_fdset_create (); - i = 0; - while (NULL != ret->listen_sockets[i]) - GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]); - ret->listen_task = - GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, - GNUNET_SCHEDULER_NO_TASK, - GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, - &process_listen_socket, ret); - GNUNET_NETWORK_fdset_destroy (r); - } - return ret; + struct GNUNET_SERVER_Handle *server; + + server = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle)); + server->idle_timeout = idle_timeout; + server->listen_sockets = lsocks; + server->access = access; + server->access_cls = access_cls; + server->require_found = require_found; + if (NULL != lsocks) + schedule_listen_task (server); + return server; } @@ -501,25 +572,41 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls, struct GNUNET_NETWORK_Handle **lsocks; unsigned int i; unsigned int j; + unsigned int k; + int seen; i = 0; - while (serverAddr[i] != NULL) + while (NULL != serverAddr[i]) i++; if (i > 0) { lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1)); i = 0; j = 0; - while (serverAddr[i] != NULL) + while (NULL != serverAddr[i]) { + seen = 0; + for (k=0;kis_monitor = GNUNET_YES; +} + + +/** + * Helper function for 'test_monitor_clients' to trigger + * 'GNUNET_SERVER_destroy' after the stack has unwound. + * + * @param cls the 'struct GNUNET_SERVER_Handle' to destroy + * @param tc unused + */ +static void +do_destroy (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_SERVER_Handle *server = cls; + GNUNET_SERVER_destroy (server); +} + + +/** + * Check if only 'monitor' clients are left. If so, destroy the + * server completely. + * + * @param server server to test for full shutdown + */ +static void +test_monitor_clients (struct GNUNET_SERVER_Handle *server) +{ + struct GNUNET_SERVER_Client *client; + + if (GNUNET_YES != server->in_soft_shutdown) + return; + for (client = server->clients_head; NULL != client; client = client->next) + if (GNUNET_NO == client->is_monitor) + return; /* not done yet */ + server->in_soft_shutdown = GNUNET_SYSERR; + GNUNET_SCHEDULER_add_continuation (&do_destroy, server, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); +} + + +/** + * Stop the listen socket and get ready to shutdown the server + * once only 'monitor' clients are left. + * + * @param server server to stop listening on + */ +void +GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server) +{ + unsigned int i; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "Server in soft shutdown\n"); + if (GNUNET_SCHEDULER_NO_TASK != server->listen_task) + { + GNUNET_SCHEDULER_cancel (server->listen_task); + server->listen_task = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != server->listen_sockets) + { + i = 0; + while (NULL != server->listen_sockets[i]) + GNUNET_break (GNUNET_OK == + GNUNET_NETWORK_socket_close (server->listen_sockets[i++])); + GNUNET_free (server->listen_sockets); + server->listen_sockets = NULL; + } + if (GNUNET_NO == server->in_soft_shutdown) + server->in_soft_shutdown = GNUNET_YES; + test_monitor_clients (server); +} + + /** * Free resources held by this server. * - * @param s server to destroy + * @param server server to destroy */ void -GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) +GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server) { struct HandlerList *hpos; struct NotifyList *npos; unsigned int i; -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n"); -#endif - if (GNUNET_SCHEDULER_NO_TASK != s->listen_task) + if (GNUNET_SCHEDULER_NO_TASK != server->listen_task) { - GNUNET_SCHEDULER_cancel (s->listen_task); - s->listen_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_SCHEDULER_cancel (server->listen_task); + server->listen_task = GNUNET_SCHEDULER_NO_TASK; } - if (s->listen_sockets != NULL) + if (NULL != server->listen_sockets) { i = 0; - while (s->listen_sockets[i] != NULL) + while (NULL != server->listen_sockets[i]) GNUNET_break (GNUNET_OK == - GNUNET_NETWORK_socket_close (s->listen_sockets[i++])); - GNUNET_free (s->listen_sockets); - s->listen_sockets = NULL; + GNUNET_NETWORK_socket_close (server->listen_sockets[i++])); + GNUNET_free (server->listen_sockets); + server->listen_sockets = NULL; } - while (s->clients != NULL) - GNUNET_SERVER_client_disconnect (s->clients); - while (NULL != (hpos = s->handlers)) + while (NULL != server->clients_head) + GNUNET_SERVER_client_disconnect (server->clients_head); + while (NULL != (hpos = server->handlers)) { - s->handlers = hpos->next; + server->handlers = hpos->next; GNUNET_free (hpos); } - while (NULL != (npos = s->disconnect_notify_list)) + while (NULL != (npos = server->disconnect_notify_list_head)) { npos->callback (npos->callback_cls, NULL); - s->disconnect_notify_list = npos->next; + GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head, + server->disconnect_notify_list_tail, + npos); GNUNET_free (npos); } - GNUNET_free (s); + GNUNET_free (server); } @@ -606,6 +782,16 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, } +/** + * Change functions used by the server to tokenize the message stream. + * (very rarely used). + * + * @param server server to modify + * @param create new tokenizer initialization function + * @param destroy new tokenizer destruction function + * @param receive new tokenizer receive function + * @param cls closure for 'create', 'receive', 'destroy' + */ void GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server, GNUNET_SERVER_MstCreateCallback create, @@ -631,6 +817,7 @@ warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_SERVER_Client *client = cls; + GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */ client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &warn_no_receive_done, client); @@ -691,15 +878,11 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, type = ntohs (message->type); size = ntohs (message->size); -#if DEBUG_SERVER - LOG (GNUNET_ERROR_TYPE_DEBUG, "Server schedules transmission of %u-byte message of type %u to client.\n", size, type); -#endif - pos = server->handlers; found = GNUNET_NO; - while (pos != NULL) + for (pos = server->handlers; NULL != pos; pos = pos->next) { i = 0; while (pos->handlers[i].callback != NULL) @@ -707,7 +890,7 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, mh = &pos->handlers[i]; if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL)) { - if ((mh->expected_size != 0) && (mh->expected_size != size)) + if ((0 != mh->expected_size) && (mh->expected_size != size)) { #if GNUNET8_NETWORK_IS_DEAD LOG (GNUNET_ERROR_TYPE_WARNING, @@ -717,11 +900,13 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, #endif return GNUNET_SYSERR; } - if (sender != NULL) + if (NULL != sender) { - if (0 == sender->suspended) + if ( (0 == sender->suspended) && + (GNUNET_SCHEDULER_NO_TASK == sender->warn_task) ) { - sender->warn_start = GNUNET_TIME_absolute_get (); + GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */ + sender->warn_start = GNUNET_TIME_absolute_get (); sender->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &warn_no_receive_done, sender); @@ -734,13 +919,12 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, } i++; } - pos = pos->next; } - if (found == GNUNET_NO) + if (GNUNET_NO == found) { LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Received message of unknown type %d\n", type); - if (server->require_found == GNUNET_YES) + if (GNUNET_YES == server->require_found) return GNUNET_SYSERR; } return GNUNET_OK; @@ -778,28 +962,24 @@ process_incoming (void *cls, const void *buf, size_t available, static void process_mst (struct GNUNET_SERVER_Client *client, int ret) { - while ((ret != GNUNET_SYSERR) && (client->server != NULL) && + while ((GNUNET_SYSERR != ret) && (NULL != client->server) && (GNUNET_YES != client->shutdown_now) && (0 == client->suspended)) { - if (ret == GNUNET_OK) + if (GNUNET_OK == ret) { - client->receive_pending = GNUNET_YES; -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server re-enters receive loop, timeout: %llu.\n", client->idle_timeout.rel_value); -#endif + client->receive_pending = GNUNET_YES; GNUNET_CONNECTION_receive (client->connection, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, client->idle_timeout, &process_incoming, client); break; } -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server processes additional messages instantly.\n"); -#endif - if (client->server->mst_receive != NULL) + if (NULL != client->server->mst_receive) ret = client->server->mst_receive (client->server->mst_cls, client->mst, client, NULL, 0, GNUNET_NO, GNUNET_YES); @@ -808,23 +988,17 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret) GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, GNUNET_YES); } -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n", ret, client->server, client->shutdown_now, client->suspended); -#endif - - if (ret == GNUNET_NO) + if (GNUNET_NO == ret) { -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server has more data pending but is suspended.\n"); -#endif client->receive_pending = GNUNET_SYSERR; /* data pending */ } - if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now)) + if ((GNUNET_SYSERR == ret) || (GNUNET_YES == client->shutdown_now)) GNUNET_SERVER_client_disconnect (client); - GNUNET_SERVER_client_drop (client); } @@ -848,22 +1022,20 @@ process_incoming (void *cls, const void *buf, size_t available, struct GNUNET_TIME_Absolute now; int ret; - GNUNET_assert (client->receive_pending == GNUNET_YES); + GNUNET_assert (GNUNET_YES == client->receive_pending); client->receive_pending = GNUNET_NO; now = GNUNET_TIME_absolute_get (); end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout); - if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) && - (client->shutdown_now != GNUNET_YES) && (server != NULL) && + if ((NULL == buf) && (0 == available) && (NULL == addr) && (0 == errCode) && + (GNUNET_YES != client->shutdown_now) && (NULL != server) && (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) && (end.abs_value > now.abs_value)) { /* wait longer, timeout changed (i.e. due to us sending) */ -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Receive time out, but no disconnect due to sending (%p)\n", GNUNET_a2s (addr, addrlen)); -#endif client->receive_pending = GNUNET_YES; GNUNET_CONNECTION_receive (client->connection, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, @@ -871,31 +1043,37 @@ process_incoming (void *cls, const void *buf, size_t available, &process_incoming, client); return; } - if ((buf == NULL) || (available == 0) || (errCode != 0) || (server == NULL) || - (client->shutdown_now == GNUNET_YES) || + if ((NULL == buf) || (0 == available) || (0 != errCode) || (NULL == server) || + (GNUNET_YES == client->shutdown_now) || (GNUNET_YES != GNUNET_CONNECTION_check (client->connection))) { /* other side closed connection, error connecting, etc. */ GNUNET_SERVER_client_disconnect (client); return; } -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n", (unsigned int) available, GNUNET_a2s (addr, addrlen)); -#endif GNUNET_SERVER_client_keep (client); client->last_activity = now; - if (server->mst_receive != NULL) + if (NULL != server->mst_receive) ret = client->server->mst_receive (client->server->mst_cls, client->mst, client, buf, available, GNUNET_NO, GNUNET_YES); - else + else if (NULL != client->mst) + { ret = GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, GNUNET_YES); + } + else + { + GNUNET_break (0); + return; + } process_mst (client, ret); + GNUNET_SERVER_client_drop (client); } @@ -910,33 +1088,24 @@ static void restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_SERVER_Client *client = cls; - struct GNUNET_SERVER_Handle *server = client->server; + GNUNET_assert (GNUNET_YES != client->shutdown_now); client->restart_task = GNUNET_SCHEDULER_NO_TASK; - if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) && - (GNUNET_NO == server->clients_ignore_shutdown)) - { - GNUNET_SERVER_client_disconnect (client); - return; - } - if (client->receive_pending == GNUNET_NO) + if (GNUNET_NO == client->receive_pending) { -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n"); -#endif client->receive_pending = GNUNET_YES; GNUNET_CONNECTION_receive (client->connection, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, client->idle_timeout, &process_incoming, client); return; } -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Server continues processing messages still in the buffer.\n"); -#endif GNUNET_SERVER_client_keep (client); client->receive_pending = GNUNET_NO; process_mst (client, GNUNET_NO); + GNUNET_SERVER_client_drop (client); } @@ -947,8 +1116,10 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param cls closure (struct GNUNET_SERVER_Handle) * @param client identification of the client (struct GNUNET_SERVER_Client*) * @param message the actual message + * + * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing */ -static void +static int client_message_tokenizer_callback (void *cls, void *client, const struct GNUNET_MessageHeader *message) { @@ -956,17 +1127,18 @@ client_message_tokenizer_callback (void *cls, void *client, struct GNUNET_SERVER_Client *sender = client; int ret; -#if DEBUG_SERVER - LOG (GNUNET_ERROR_TYPE_DEBUG, "Tokenizer gives server message of type %u from client\n", ntohs (message->type)); -#endif sender->in_process_client_buffer = GNUNET_YES; ret = GNUNET_SERVER_inject (server, sender, message); sender->in_process_client_buffer = GNUNET_NO; - if (GNUNET_OK != ret) + if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) ) + { GNUNET_SERVER_client_disconnect (sender); + return GNUNET_SYSERR; + } + return GNUNET_OK; } @@ -990,25 +1162,21 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client)); client->connection = connection; - client->mst = - GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server); client->reference_count = 1; client->server = server; client->last_activity = GNUNET_TIME_absolute_get (); - client->next = server->clients; client->idle_timeout = server->idle_timeout; - server->clients = client; - client->receive_pending = GNUNET_YES; - client->callback = NULL; - client->callback_cls = NULL; - - if (server->mst_create != NULL) + GNUNET_CONTAINER_DLL_insert (server->clients_head, + server->clients_tail, + client); + if (NULL != server->mst_create) client->mst = server->mst_create (server->mst_cls, client); else client->mst = GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server); - + GNUNET_assert (NULL != client->mst); + client->receive_pending = GNUNET_YES; GNUNET_CONNECTION_receive (client->connection, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, client->idle_timeout, &process_incoming, client); @@ -1032,14 +1200,6 @@ GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client, } -void -GNUNET_SERVER_client_set_finish_pending_write (struct GNUNET_SERVER_Client *client, - int finish) -{ - client->finish_pending_write = finish; -} - - /** * Notify the server that the given client handle should * be kept (keeps the connection up if possible, increments @@ -1067,7 +1227,7 @@ GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client) { GNUNET_assert (client->reference_count > 0); client->reference_count--; - if ((client->shutdown_now == GNUNET_YES) && (client->reference_count == 0)) + if ((GNUNET_YES == client->shutdown_now) && (0 == client->reference_count)) GNUNET_SERVER_client_disconnect (client); } @@ -1108,8 +1268,9 @@ GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, n = GNUNET_malloc (sizeof (struct NotifyList)); n->callback = callback; n->callback_cls = callback_cls; - n->next = server->disconnect_notify_list; - server->disconnect_notify_list = n; + GNUNET_CONTAINER_DLL_insert (server->disconnect_notify_list_head, + server->disconnect_notify_list_tail, + n); } @@ -1126,30 +1287,41 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, callback, void *callback_cls) { struct NotifyList *pos; - struct NotifyList *prev; - prev = NULL; - pos = server->disconnect_notify_list; - while (pos != NULL) - { + for (pos = server->disconnect_notify_list_head; NULL != pos; pos = pos->next) if ((pos->callback == callback) && (pos->callback_cls == callback_cls)) break; - prev = pos; - pos = pos->next; - } - if (pos == NULL) + if (NULL == pos) { GNUNET_break (0); return; } - if (prev == NULL) - server->disconnect_notify_list = pos->next; - else - prev->next = pos->next; + GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head, + server->disconnect_notify_list_tail, + pos); GNUNET_free (pos); } +/** + * Destroy the connection that is passed in via 'cls'. Used + * as calling 'GNUNET_CONNECTION_destroy' from within a function + * that was itself called from within 'process_notify' of + * 'connection.c' is not allowed (see #2329). + * + * @param cls connection to destroy + * @param tc scheduler context (unused) + */ +static void +destroy_connection (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_CONNECTION_Handle *connection = cls; + + GNUNET_CONNECTION_destroy (connection); +} + + /** * Ask the server to disconnect from the given client. * This is the same as returning GNUNET_SYSERR from a message @@ -1161,22 +1333,17 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, void GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) { - struct GNUNET_SERVER_Client *prev; - struct GNUNET_SERVER_Client *pos; - struct GNUNET_SERVER_Handle *server; + struct GNUNET_SERVER_Handle *server = client->server; struct NotifyList *n; - unsigned int rc; -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Client is being disconnected from the server.\n"); -#endif - if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != client->restart_task) { GNUNET_SCHEDULER_cancel (client->restart_task); client->restart_task = GNUNET_SCHEDULER_NO_TASK; } - if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) { GNUNET_SCHEDULER_cancel (client->warn_task); client->warn_task = GNUNET_SCHEDULER_NO_TASK; @@ -1186,68 +1353,58 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) GNUNET_CONNECTION_receive_cancel (client->connection); client->receive_pending = GNUNET_NO; } - - rc = client->reference_count; - if (client->shutdown_now != GNUNET_YES) + client->shutdown_now = GNUNET_YES; + client->reference_count++; /* make sure nobody else clean up client... */ + if ( (NULL != client->mst) && + (NULL != server) ) { - server = client->server; - client->shutdown_now = GNUNET_YES; - prev = NULL; - pos = server->clients; - while ((pos != NULL) && (pos != client)) - { - prev = pos; - pos = pos->next; - } - GNUNET_assert (pos != NULL); - if (prev == NULL) - server->clients = pos->next; + GNUNET_CONTAINER_DLL_remove (server->clients_head, + server->clients_tail, + client); + if (NULL != server->mst_destroy) + server->mst_destroy (server->mst_cls, client->mst); else - prev->next = pos->next; - if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (client->restart_task); - client->restart_task = GNUNET_SCHEDULER_NO_TASK; - } - if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (client->warn_task); - client->warn_task = GNUNET_SCHEDULER_NO_TASK; - } - n = server->disconnect_notify_list; - while (n != NULL) - { + GNUNET_SERVER_mst_destroy (client->mst); + client->mst = NULL; + for (n = server->disconnect_notify_list_head; NULL != n; n = n->next) n->callback (n->callback_cls, client); - n = n->next; - } } - if (rc > 0) + client->reference_count--; + if (client->reference_count > 0) { -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "RC still positive, not destroying everything.\n"); -#endif + client->server = NULL; return; } - if (client->in_process_client_buffer == GNUNET_YES) + if (GNUNET_YES == client->in_process_client_buffer) { -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "Still processing inputs, not destroying everything.\n"); -#endif return; } - - if (client->persist == GNUNET_YES) + if (GNUNET_YES == client->persist) GNUNET_CONNECTION_persist_ (client->connection); - GNUNET_CONNECTION_destroy (client->connection, client->finish_pending_write); - - if (client->server->mst_destroy != NULL) - client->server->mst_destroy (client->server->mst_cls, client->mst); - else - GNUNET_SERVER_mst_destroy (client->mst); - + if (NULL != client->th.cth) + GNUNET_SERVER_notify_transmit_ready_cancel (&client->th); + (void) GNUNET_SCHEDULER_add_now (&destroy_connection, + client->connection); + /* need to cancel again, as it might have been re-added + in the meantime (i.e. during callbacks) */ + if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) + { + GNUNET_SCHEDULER_cancel (client->warn_task); + client->warn_task = GNUNET_SCHEDULER_NO_TASK; + } + if (GNUNET_YES == client->receive_pending) + { + GNUNET_CONNECTION_receive_cancel (client->connection); + client->receive_pending = GNUNET_NO; + } GNUNET_free (client); + /* we might be in soft-shutdown, test if we're done */ + if (NULL != server) + test_monitor_clients (server); } @@ -1279,12 +1436,13 @@ static size_t transmit_ready_callback_wrapper (void *cls, size_t size, void *buf) { struct GNUNET_SERVER_Client *client = cls; - size_t ret; + GNUNET_CONNECTION_TransmitReadyNotify callback; - ret = client->callback (client->callback_cls, size, buf); - if (ret > 0) - client->last_activity = GNUNET_TIME_absolute_get (); - return ret; + client->th.cth = NULL; + callback = client->th.callback; + client->th.callback = NULL; + client->last_activity = GNUNET_TIME_absolute_get (); + return callback (client->th.callback_cls, size, buf); } @@ -1300,22 +1458,39 @@ transmit_ready_callback_wrapper (void *cls, size_t size, void *buf) * @param callback_cls closure for callback * @return non-NULL if the notify callback was queued; can be used * to cancel the request using - * GNUNET_CONNECTION_notify_transmit_ready_cancel. + * GNUNET_SERVER_notify_transmit_ready_cancel. * NULL if we are already going to notify someone else (busy) */ -struct GNUNET_CONNECTION_TransmitHandle * +struct GNUNET_SERVER_TransmitHandle * GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify callback, void *callback_cls) { - client->callback_cls = callback_cls; - client->callback = callback; - return GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, - timeout, - &transmit_ready_callback_wrapper, - client); + if (NULL != client->th.callback) + return NULL; + client->th.callback_cls = callback_cls; + client->th.callback = callback; + client->th.cth = GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, + timeout, + &transmit_ready_callback_wrapper, + client); + return &client->th; +} + + +/** + * Abort transmission request. + * + * @param th request to abort + */ +void +GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th) +{ + GNUNET_CONNECTION_notify_transmit_ready_cancel (th->cth); + th->cth = NULL; + th->callback = NULL; } @@ -1347,25 +1522,24 @@ GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client) void GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success) { - if (client == NULL) + if (NULL == client) return; GNUNET_assert (client->suspended > 0); client->suspended--; - if (success != GNUNET_OK) + if (GNUNET_OK != success) { -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_SERVER_receive_done called with failure indication\n"); -#endif - GNUNET_SERVER_client_disconnect (client); + if ( (client->reference_count > 0) || (client->suspended > 0) ) + client->shutdown_now = GNUNET_YES; + else + GNUNET_SERVER_client_disconnect (client); return; } if (client->suspended > 0) { -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_SERVER_receive_done called, but more clients pending\n"); -#endif return; } if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) @@ -1373,43 +1547,22 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success) GNUNET_SCHEDULER_cancel (client->warn_task); client->warn_task = GNUNET_SCHEDULER_NO_TASK; } - if (client->in_process_client_buffer == GNUNET_YES) + if (GNUNET_YES == client->in_process_client_buffer) { -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_SERVER_receive_done called while still in processing loop\n"); -#endif return; } - if ((client->server == NULL) || (GNUNET_YES == client->shutdown_now)) + if ((NULL == client->server) || (GNUNET_YES == client->shutdown_now)) { GNUNET_SERVER_client_disconnect (client); return; } -#if DEBUG_SERVER LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_SERVER_receive_done causes restart in reading from the socket\n"); -#endif GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task); client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, client); } -/** - * Configure this server's connections to continue handling client - * requests as usual even after we get a shutdown signal. The change - * only applies to clients that connect to the server from the outside - * using TCP after this call. Clients managed previously or those - * added using GNUNET_SERVER_connect_socket and - * GNUNET_SERVER_connect_callback are not affected by this option. - * - * @param h server handle - * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default - */ -void -GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, int do_ignore) -{ - h->clients_ignore_shutdown = do_ignore; -} - /* end of server.c */ diff --git a/src/util/server_mst.c b/src/util/server_mst.c index 6161770..9dd04f0 100644 --- a/src/util/server_mst.c +++ b/src/util/server_mst.c @@ -31,7 +31,6 @@ #include "gnunet_server_lib.h" #include "gnunet_time_lib.h" -#define DEBUG_SERVER_MST GNUNET_EXTRA_LOGGING #if HAVE_UNALIGNED_64_ACCESS #define ALIGN_FACTOR 4 @@ -134,11 +133,9 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst, GNUNET_assert (mst->off <= mst->pos); GNUNET_assert (mst->pos <= mst->curr_buf); -#if DEBUG_SERVER_MST LOG (GNUNET_ERROR_TYPE_DEBUG, "Server-mst receives %u bytes with %u bytes already in private buffer\n", (unsigned int) size, (unsigned int) (mst->pos - mst->off)); -#endif ret = GNUNET_OK; ibuf = (char *) mst->hdr; while (mst->pos > 0) @@ -224,7 +221,8 @@ do_align: if (one_shot == GNUNET_YES) one_shot = GNUNET_SYSERR; mst->off += want; - mst->cb (mst->cb_cls, client_identity, hdr); + if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr)) + return GNUNET_SYSERR; if (mst->off == mst->pos) { /* reset to beginning of buffer, it's free right now! */ @@ -235,11 +233,9 @@ do_align: GNUNET_assert (0 == mst->pos); while (size > 0) { -#if DEBUG_SERVER_MST LOG (GNUNET_ERROR_TYPE_DEBUG, "Server-mst has %u bytes left in inbound buffer\n", (unsigned int) size); -#endif if (size < sizeof (struct GNUNET_MessageHeader)) break; offset = (unsigned long) buf; @@ -266,7 +262,8 @@ do_align: } if (one_shot == GNUNET_YES) one_shot = GNUNET_SYSERR; - mst->cb (mst->cb_cls, client_identity, hdr); + if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr)) + return GNUNET_SYSERR; buf += want; size -= want; } @@ -295,11 +292,9 @@ copy: mst->off = 0; mst->pos = 0; } -#if DEBUG_SERVER_MST LOG (GNUNET_ERROR_TYPE_DEBUG, "Server-mst leaves %u bytes in private buffer\n", (unsigned int) (mst->pos - mst->off)); -#endif return ret; } diff --git a/src/util/server_nc.c b/src/util/server_nc.c index 08ffd4b..6e0181e 100644 --- a/src/util/server_nc.c +++ b/src/util/server_nc.c @@ -36,8 +36,6 @@ #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) -#define DEBUG_SERVER_NC GNUNET_EXTRA_LOGGING - /** * Entry in list of messages pending to be transmitted. */ @@ -75,10 +73,15 @@ struct ClientList { /** - * This is a linked list. + * This is a doubly linked list. */ struct ClientList *next; + /** + * This is a doubly linked list. + */ + struct ClientList *prev; + /** * Overall context this client belongs to. */ @@ -92,7 +95,7 @@ struct ClientList /** * Handle for pending transmission request to the client (or NULL). */ - struct GNUNET_CONNECTION_TransmitHandle *th; + struct GNUNET_SERVER_TransmitHandle *th; /** * Head of linked list of requests queued for transmission. @@ -129,9 +132,14 @@ struct GNUNET_SERVER_NotificationContext struct GNUNET_SERVER_Handle *server; /** - * List of clients receiving notifications. + * Head of list of clients receiving notifications. */ - struct ClientList *clients; + struct ClientList *clients_head; + + /** + * Tail of list of clients receiving notifications. + */ + struct ClientList *clients_tail; /** * Maximum number of optional messages to queue per client. @@ -152,45 +160,37 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) { struct GNUNET_SERVER_NotificationContext *nc = cls; struct ClientList *pos; - struct ClientList *prev; struct PendingMessageList *pml; - if (client == NULL) + if (NULL == client) { nc->server = NULL; return; } - prev = NULL; - pos = nc->clients; - while (NULL != pos) - { + for (pos = nc->clients_head; NULL != pos; pos = pos->next) if (pos->client == client) break; - prev = pos; - pos = pos->next; - } - if (pos == NULL) + if (NULL == pos) return; -#if DEBUG_SERVER_NC LOG (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, cleaning up %u messages in NC queue\n", pos->num_pending); -#endif - if (prev == NULL) - nc->clients = pos->next; - else - prev->next = pos->next; + GNUNET_CONTAINER_DLL_remove (nc->clients_head, + nc->clients_tail, + pos); while (NULL != (pml = pos->pending_head)) { GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, pml); GNUNET_free (pml); + pos->num_pending--; } - if (pos->th != NULL) + if (NULL != pos->th) { - GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->th); + GNUNET_SERVER_notify_transmit_ready_cancel (pos->th); pos->th = NULL; } GNUNET_SERVER_client_drop (client); + GNUNET_assert (0 == pos->num_pending); GNUNET_free (pos); } @@ -231,18 +231,27 @@ GNUNET_SERVER_notification_context_destroy (struct struct ClientList *pos; struct PendingMessageList *pml; - while (NULL != (pos = nc->clients)) + while (NULL != (pos = nc->clients_head)) { - nc->clients = pos->next; + GNUNET_CONTAINER_DLL_remove (nc->clients_head, + nc->clients_tail, + pos); + if (NULL != pos->th) + { + GNUNET_SERVER_notify_transmit_ready_cancel(pos->th); + pos->th = NULL; + } GNUNET_SERVER_client_drop (pos->client); while (NULL != (pml = pos->pending_head)) { GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, pml); GNUNET_free (pml); + pos->num_pending--; } + GNUNET_assert (0 == pos->num_pending); GNUNET_free (pos); } - if (nc->server != NULL) + if (NULL != nc->server) GNUNET_SERVER_disconnect_notify_cancel (nc->server, &handle_client_disconnect, nc); GNUNET_free (nc); @@ -262,15 +271,16 @@ GNUNET_SERVER_notification_context_add (struct GNUNET_SERVER_NotificationContext { struct ClientList *cl; - for (cl = nc->clients; NULL != cl; cl = cl->next) + for (cl = nc->clients_head; NULL != cl; cl = cl->next) if (cl->client == client) return; /* already present */ cl = GNUNET_malloc (sizeof (struct ClientList)); - cl->next = nc->clients; + GNUNET_CONTAINER_DLL_insert (nc->clients_head, + nc->clients_tail, + cl); cl->nc = nc; cl->client = client; GNUNET_SERVER_client_keep (client); - nc->clients = cl; } @@ -294,13 +304,11 @@ transmit_message (void *cls, size_t size, void *buf) size_t ret; cl->th = NULL; - if (buf == NULL) + if (NULL == buf) { /* 'cl' should be freed via disconnect notification shortly */ -#if DEBUG_SERVER_NC LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to transmit message from NC queue to client\n"); -#endif return 0; } ret = 0; @@ -310,31 +318,29 @@ transmit_message (void *cls, size_t size, void *buf) if (size < msize) break; GNUNET_CONTAINER_DLL_remove (cl->pending_head, cl->pending_tail, pml); -#if DEBUG_SERVER_NC LOG (GNUNET_ERROR_TYPE_DEBUG, "Copying message of type %u and size %u from pending queue to transmission buffer\n", ntohs (pml->msg->type), msize); -#endif memcpy (&cbuf[ret], pml->msg, msize); ret += msize; size -= msize; GNUNET_free (pml); cl->num_pending--; } - if (pml != NULL) + if (NULL != pml) { -#if DEBUG_SERVER_NC LOG (GNUNET_ERROR_TYPE_DEBUG, "Have %u messages left in NC queue, will try transmission again\n", cl->num_pending); -#endif cl->th = GNUNET_SERVER_notify_transmit_ready (cl->client, ntohs (pml->msg->size), GNUNET_TIME_UNIT_FOREVER_REL, &transmit_message, cl); } else - GNUNET_assert (cl->num_pending == 0); + { + GNUNET_assert (0 == cl->num_pending); + } return ret; } @@ -372,11 +378,9 @@ do_unicast (struct GNUNET_SERVER_NotificationContext *nc, pml = GNUNET_malloc (sizeof (struct PendingMessageList) + size); pml->msg = (const struct GNUNET_MessageHeader *) &pml[1]; pml->can_drop = can_drop; -#if DEBUG_SERVER_NC LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding message of type %u and size %u to pending queue (which has %u entries)\n", ntohs (msg->type), ntohs (msg->size), (unsigned int) nc->queue_length); -#endif memcpy (&pml[1], msg, size); /* append */ GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail, @@ -410,14 +414,10 @@ GNUNET_SERVER_notification_context_unicast (struct { struct ClientList *pos; - pos = nc->clients; - while (NULL != pos) - { + for (pos = nc->clients_head; NULL != pos; pos = pos->next) if (pos->client == client) break; - pos = pos->next; - } - GNUNET_assert (pos != NULL); + GNUNET_assert (NULL != pos); do_unicast (nc, pos, msg, can_drop); } @@ -438,12 +438,8 @@ GNUNET_SERVER_notification_context_broadcast (struct { struct ClientList *pos; - pos = nc->clients; - while (NULL != pos) - { + for (pos = nc->clients_head; NULL != pos; pos = pos->next) do_unicast (nc, pos, msg, can_drop); - pos = pos->next; - } } diff --git a/src/util/server_tc.c b/src/util/server_tc.c index ce40db1..f803af4 100644 --- a/src/util/server_tc.c +++ b/src/util/server_tc.c @@ -82,7 +82,7 @@ transmit_response (void *cls, size_t size, void *buf) struct GNUNET_SERVER_TransmitContext *tc = cls; size_t msize; - if (buf == NULL) + if (NULL == buf) { GNUNET_SERVER_transmit_context_destroy (tc, GNUNET_SYSERR); return 0; @@ -95,7 +95,6 @@ transmit_response (void *cls, size_t size, void *buf) tc->off += msize; if (tc->total == tc->off) { - GNUNET_SERVER_receive_done (tc->client, GNUNET_OK); GNUNET_SERVER_client_drop (tc->client); GNUNET_free_non_null (tc->buf); @@ -131,7 +130,7 @@ GNUNET_SERVER_transmit_context_create (struct GNUNET_SERVER_Client *client) { struct GNUNET_SERVER_TransmitContext *tc; - GNUNET_assert (client != NULL); + GNUNET_assert (NULL != client); tc = GNUNET_malloc (sizeof (struct GNUNET_SERVER_TransmitContext)); GNUNET_SERVER_client_keep (client); tc->client = client; diff --git a/src/util/service.c b/src/util/service.c index 243e7da..6a6fb6c 100644 --- a/src/util/service.c +++ b/src/util/service.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) + (C) 2009, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -42,7 +42,6 @@ #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) -#define DEBUG_SERVICE GNUNET_EXTRA_LOGGING /* ******************* access control ******************** */ @@ -51,7 +50,14 @@ */ struct IPv4NetworkSet { + /** + * IPv4 address. + */ struct in_addr network; + + /** + * IPv4 netmask. + */ struct in_addr netmask; }; @@ -60,11 +66,25 @@ struct IPv4NetworkSet */ struct IPv6NetworkSet { + /** + * IPv6 address. + */ struct in6_addr network; + + /** + * IPv6 netmask. + */ struct in6_addr netmask; }; +int +GNUNET_SPEEDUP_start_ (const struct GNUNET_CONFIGURATION_Handle *cfg); + +int +GNUNET_SPEEDUP_stop_ (void); + + /** * Parse a network specification. The argument specifies * a list of networks. The format is @@ -72,7 +92,7 @@ struct IPv6NetworkSet * with a semicolon). The network must be given in dotted-decimal * notation. The netmask can be given in CIDR notation (/16) or * in dotted-decimal (/255.255.0.0). - *

+ * * @param routeList a string specifying the forbidden networks * @return the converted list, NULL if the synatx is flawed */ @@ -89,27 +109,25 @@ parse_ipv4_specification (const char *routeList) int slash; struct IPv4NetworkSet *result; - if (routeList == NULL) + if (NULL == routeList) return NULL; len = strlen (routeList); - if (len == 0) + if (0 == len) return NULL; count = 0; for (i = 0; i < len; i++) if (routeList[i] == ';') count++; result = GNUNET_malloc (sizeof (struct IPv4NetworkSet) * (count + 1)); - /* add termination */ - memset (result, 0, sizeof (struct IPv4NetworkSet) * (count + 1)); i = 0; pos = 0; while (i < count) { cnt = - sscanf (&routeList[pos], "%u.%u.%u.%u/%u.%u.%u.%u;", &temps[0], + SSCANF (&routeList[pos], "%u.%u.%u.%u/%u.%u.%u.%u;", &temps[0], &temps[1], &temps[2], &temps[3], &temps[4], &temps[5], &temps[6], &temps[7]); - if (cnt == 8) + if (8 == cnt) { for (j = 0; j < 8; j++) if (temps[j] > 0xFF) @@ -133,9 +151,9 @@ parse_ipv4_specification (const char *routeList) } /* try second notation */ cnt = - sscanf (&routeList[pos], "%u.%u.%u.%u/%u;", &temps[0], &temps[1], + SSCANF (&routeList[pos], "%u.%u.%u.%u/%u;", &temps[0], &temps[1], &temps[2], &temps[3], &slash); - if (cnt == 5) + if (5 == cnt) { for (j = 0; j < 4; j++) if (temps[j] > 0xFF) @@ -158,7 +176,7 @@ parse_ipv4_specification (const char *routeList) slash--; } result[i].netmask.s_addr = htonl (result[i].netmask.s_addr); - while (routeList[pos] != ';') + while (';' != routeList[pos]) pos++; pos++; i++; @@ -176,9 +194,9 @@ parse_ipv4_specification (const char *routeList) /* try third notation */ slash = 32; cnt = - sscanf (&routeList[pos], "%u.%u.%u.%u;", &temps[0], &temps[1], + SSCANF (&routeList[pos], "%u.%u.%u.%u;", &temps[0], &temps[1], &temps[2], &temps[3]); - if (cnt == 4) + if (4 == cnt) { for (j = 0; j < 4; j++) if (temps[j] > 0xFF) @@ -227,7 +245,7 @@ parse_ipv4_specification (const char *routeList) * with a semicolon). The network must be given in colon-hex * notation. The netmask must be given in CIDR notation (/16) or * can be omitted to specify a single host. - *

+ * * @param routeListX a string specifying the forbidden networks * @return the converted list, NULL if the synatx is flawed */ @@ -247,17 +265,17 @@ parse_ipv6_specification (const char *routeListX) unsigned int off; int save; - if (routeListX == NULL) + if (NULL == routeListX) return NULL; len = strlen (routeListX); - if (len == 0) + if (0 == len) return NULL; routeList = GNUNET_strdup (routeListX); count = 0; for (i = 0; i < len; i++) - if (routeList[i] == ';') + if (';' == routeList[i]) count++; - if (routeList[len - 1] != ';') + if (';' != routeList[len - 1]) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid network notation (does not end with ';': `%s')\n"), @@ -267,13 +285,12 @@ parse_ipv6_specification (const char *routeListX) } result = GNUNET_malloc (sizeof (struct IPv6NetworkSet) * (count + 1)); - memset (result, 0, sizeof (struct IPv6NetworkSet) * (count + 1)); i = 0; pos = 0; while (i < count) { start = pos; - while (routeList[pos] != ';') + while (';' != routeList[pos]) pos++; slash = pos; while ((slash >= start) && (routeList[slash] != '/')) @@ -292,7 +309,7 @@ parse_ipv6_specification (const char *routeListX) save = errno; if ((1 != SSCANF (&routeList[slash + 1], "%u", &bits)) || (bits >= 128)) { - if (ret == 0) + if (0 == ret) LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong format `%s' for netmask\n"), &routeList[slash + 1]); else @@ -322,7 +339,7 @@ parse_ipv6_specification (const char *routeListX) ret = inet_pton (AF_INET6, &routeList[start], &result[i].network); if (ret <= 0) { - if (ret == 0) + if (0 == ret) LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong format `%s' for network\n"), &routeList[slash + 1]); else @@ -349,12 +366,11 @@ parse_ipv6_specification (const char *routeListX) static int check_ipv4_listed (const struct IPv4NetworkSet *list, const struct in_addr *add) { - int i; + unsigned int i; - i = 0; - if (list == NULL) + if (NULL == list) return GNUNET_NO; - + i = 0; while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0)) { if ((add->s_addr & list[i].netmask.s_addr) == @@ -365,6 +381,7 @@ check_ipv4_listed (const struct IPv4NetworkSet *list, const struct in_addr *add) return GNUNET_NO; } + /** * Check if the given IP address is in the list of IP addresses. * @@ -379,13 +396,12 @@ check_ipv6_listed (const struct IPv6NetworkSet *list, const struct in6_addr *ip) unsigned int j; struct in6_addr zero; - if (list == NULL) + if (NULL == list) return GNUNET_NO; - memset (&zero, 0, sizeof (struct in6_addr)); i = 0; NEXT: - while (memcmp (&zero, &list[i].network, sizeof (struct in6_addr)) != 0) + while (0 != memcmp (&zero, &list[i].network, sizeof (struct in6_addr))) { for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++) if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) != @@ -427,7 +443,7 @@ struct GNUNET_SERVICE_Context /** * Name of our service. */ - const char *serviceName; + const char *service_name; /** * Main service-specific task to run. @@ -477,6 +493,11 @@ struct GNUNET_SERVICE_Context */ struct GNUNET_NETWORK_Handle **lsocks; + /** + * Task ID of the shutdown task. + */ + GNUNET_SCHEDULER_TaskIdentifier shutdown_task; + /** * Idle timeout for server. */ @@ -526,6 +547,14 @@ struct GNUNET_SERVICE_Context /* ****************** message handlers ****************** */ +/** + * Send a 'TEST' message back to the client. + * + * @param cls the 'struct GNUNET_SERVER_Client' to send TEST to + * @param size number of bytes available in 'buf' + * @param buf where to copy the message + * @return number of bytes written to 'buf' + */ static size_t write_test (void *cls, size_t size, void *buf) { @@ -544,6 +573,7 @@ write_test (void *cls, size_t size, void *buf) return sizeof (struct GNUNET_MessageHeader); } + /** * Handler for TEST message. * @@ -577,7 +607,6 @@ static const struct GNUNET_SERVER_MessageHandler defhandlers[] = { }; - /* ****************** service core routines ************** */ @@ -605,31 +634,32 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc, case AF_INET: GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); i4 = (const struct sockaddr_in *) addr; - ret = ((sctx->v4_allowed == NULL) || + ret = ((NULL == sctx->v4_allowed) || (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) && - ((sctx->v4_denied == NULL) || + ((NULL == sctx->v4_denied) || (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr))); break; case AF_INET6: GNUNET_assert (addrlen == sizeof (struct sockaddr_in6)); i6 = (const struct sockaddr_in6 *) addr; - ret = ((sctx->v6_allowed == NULL) || + ret = ((NULL == sctx->v6_allowed) || (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) && - ((sctx->v6_denied == NULL) || + ((NULL == sctx->v6_denied) || (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr))); break; #ifndef WINDOWS case AF_UNIX: ret = GNUNET_OK; /* always OK for now */ - if (sctx->match_uid == GNUNET_YES) + if (GNUNET_YES == sctx->match_uid) { /* UID match required */ - ret = (uc != NULL) && (uc->uid == geteuid ()); + ret = (NULL != uc) && (uc->uid == geteuid ()); } - else if (sctx->match_gid == GNUNET_YES) + else if ( (GNUNET_YES == sctx->match_gid) && + ( (NULL == uc) || (uc->uid != geteuid ()) ) ) { - /* group match required */ - if (uc == NULL) + /* group match required and UID does not match */ + if (NULL == uc) { /* no credentials, group match not possible */ ret = GNUNET_NO; @@ -666,7 +696,7 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc, } if (GNUNET_NO == ret) LOG (GNUNET_ERROR_TYPE_WARNING, _("Access denied to UID %d / GID %d\n"), - (uc == NULL) ? -1 : uc->uid, (uc == NULL) ? -1 : uc->gid); + (NULL == uc) ? -1 : uc->uid, (NULL == uc) ? -1 : uc->gid); break; #endif default: @@ -674,12 +704,12 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc, addr->sa_family); return GNUNET_SYSERR; } - if (ret != GNUNET_OK) + if (GNUNET_OK != ret) { LOG (GNUNET_ERROR_TYPE_WARNING, - _("Access from `%s' denied to service `%s'\n"), GNUNET_a2s (addr, - addrlen), - sctx->serviceName); + _("Access from `%s' denied to service `%s'\n"), + GNUNET_a2s (addr, addrlen), + sctx->service_name); } return ret; } @@ -688,15 +718,17 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc, /** * Get the name of the file where we will * write the PID of the service. + * + * @param sctx service context + * @return name of the file for the process ID */ static char * get_pid_file_name (struct GNUNET_SERVICE_Context *sctx) { - char *pif; if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->serviceName, + GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name, "PIDFILE", &pif)) return NULL; return pif; @@ -705,6 +737,12 @@ get_pid_file_name (struct GNUNET_SERVICE_Context *sctx) /** * Parse an IPv4 access control list. + * + * @param ret location where to write the ACL (set) + * @param sctx service context to use to get the configuration + * @param option name of the ACL option to parse + * @return GNUNET_SYSERR on parse error, GNUNET_OK on success (including + * no ACL configured) */ static int process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx, @@ -712,17 +750,20 @@ process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx, { char *opt; - if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option)) + if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option)) + { + *ret = NULL; return GNUNET_OK; + } GNUNET_break (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sctx->cfg, - sctx->serviceName, + sctx->service_name, option, &opt)); if (NULL == (*ret = parse_ipv4_specification (opt))) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), - opt, sctx->serviceName, option); + opt, sctx->service_name, option); GNUNET_free (opt); return GNUNET_SYSERR; } @@ -732,7 +773,13 @@ process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx, /** - * Parse an IPv4 access control list. + * Parse an IPv6 access control list. + * + * @param ret location where to write the ACL (set) + * @param sctx service context to use to get the configuration + * @param option name of the ACL option to parse + * @return GNUNET_SYSERR on parse error, GNUNET_OK on success (including + * no ACL configured) */ static int process_acl6 (struct IPv6NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx, @@ -740,17 +787,20 @@ process_acl6 (struct IPv6NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx, { char *opt; - if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option)) + if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option)) + { + *ret = NULL; return GNUNET_OK; + } GNUNET_break (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sctx->cfg, - sctx->serviceName, + sctx->service_name, option, &opt)); if (NULL == (*ret = parse_ipv6_specification (opt))) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), - opt, sctx->serviceName, option); + opt, sctx->service_name, option); GNUNET_free (opt); return GNUNET_SYSERR; } @@ -758,6 +808,7 @@ process_acl6 (struct IPv6NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx, return GNUNET_OK; } + /** * Add the given UNIX domain path as an address to the * list (as the first entry). @@ -802,7 +853,7 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens, * Get the list of addresses that a server for the given service * should bind to. * - * @param serviceName name of the service + * @param service_name name of the service * @param cfg configuration (which specifies the addresses) * @param addrs set (call by reference) to an array of pointers to the * addresses the server should bind to and listen on; the @@ -819,7 +870,7 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens, * set to NULL). */ int -GNUNET_SERVICE_get_server_addresses (const char *serviceName, +GNUNET_SERVICE_get_server_addresses (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, struct sockaddr ***addrs, socklen_t ** addr_lens) @@ -842,11 +893,11 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, *addrs = NULL; *addr_lens = NULL; desc = NULL; - if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "DISABLEV6")) + if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6")) { if (GNUNET_SYSERR == (disablev6 = - GNUNET_CONFIGURATION_get_value_yesno (cfg, serviceName, "DISABLEV6"))) + GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6"))) return GNUNET_SYSERR; } else @@ -858,8 +909,8 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); if (NULL == desc) { - if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || - (errno == EACCES)) + if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || + (EACCES == errno)) { LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); return GNUNET_SYSERR; @@ -867,7 +918,7 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, LOG (GNUNET_ERROR_TYPE_INFO, _ ("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), - serviceName, STRERROR (errno)); + service_name, STRERROR (errno)); disablev6 = GNUNET_YES; } else @@ -878,24 +929,24 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, } port = 0; - if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT")) + if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) { GNUNET_break (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (cfg, serviceName, + GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port)); if (port > 65535) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Require valid port number for service `%s' in configuration!\n"), - serviceName); + service_name); return GNUNET_SYSERR; } } - if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO")) + if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) { GNUNET_break (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, + GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "BINDTO", &hostname)); } else @@ -904,9 +955,9 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, unixpath = NULL; #ifdef AF_UNIX if ((GNUNET_YES == - GNUNET_CONFIGURATION_have_value (cfg, serviceName, "UNIXPATH")) && + GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, "UNIXPATH", + GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) { @@ -926,8 +977,8 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); if (NULL == desc) { - if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || - (errno == EACCES)) + if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || + (EACCES == errno)) { LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); GNUNET_free_non_null (hostname); @@ -937,7 +988,7 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, LOG (GNUNET_ERROR_TYPE_INFO, _ ("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), - serviceName, STRERROR (errno)); + service_name, STRERROR (errno)); GNUNET_free (unixpath); unixpath = NULL; } @@ -949,16 +1000,16 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, } #endif - if ((port == 0) && (unixpath == NULL)) + if ((0 == port) && (NULL == unixpath)) { LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), - serviceName); + service_name); GNUNET_free_non_null (hostname); return GNUNET_SYSERR; } - if (port == 0) + if (0 == port) { saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *)); saddrlens = GNUNET_malloc (2 * sizeof (socklen_t)); @@ -970,16 +1021,15 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, return 1; } - if (hostname != NULL) + if (NULL != hostname) { -#if DEBUG_SERVICE LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolving `%s' since that is where `%s' will bind to.\n", hostname, - serviceName); -#endif + service_name); memset (&hints, 0, sizeof (struct addrinfo)); if (disablev6) hints.ai_family = AF_INET; + hints.ai_protocol = IPPROTO_TCP; if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || (res == NULL)) { @@ -1022,19 +1072,17 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, while (NULL != (pos = next)) { next = pos->ai_next; - if ((disablev6) && (pos->ai_family == AF_INET6)) + if ((disablev6) && (AF_INET6 == pos->ai_family)) continue; - if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0)) + if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) continue; /* not TCP */ - if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0)) + if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) continue; /* huh? */ -#if DEBUG_SERVICE LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n", - serviceName, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); -#endif - if (pos->ai_family == AF_INET) + service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); + if (AF_INET == pos->ai_family) { - GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in)); + GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen); saddrlens[i] = pos->ai_addrlen; saddrs[i] = GNUNET_malloc (saddrlens[i]); memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); @@ -1042,8 +1090,8 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, } else { - GNUNET_assert (pos->ai_family == AF_INET6); - GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6)); + GNUNET_assert (AF_INET6 == pos->ai_family); + GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen); saddrlens[i] = pos->ai_addrlen; saddrs[i] = GNUNET_malloc (saddrlens[i]); memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); @@ -1120,6 +1168,9 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, #ifdef MINGW /** + * Read listen sockets from the parent process (ARM). + * + * @param sctx service context to initialize * @return GNUNET_YES if ok, GNUNET_NO if not ok (must bind yourself), * and GNUNET_SYSERR on error. */ @@ -1128,22 +1179,20 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) { const char *env_buf; int fail; - uint64_t count, i; + uint64_t count; + uint64_t i; HANDLE lsocks_pipe; env_buf = getenv ("GNUNET_OS_READ_LSOCKS"); - if ((env_buf == NULL) || (strlen (env_buf) <= 0)) - { + if ((NULL == env_buf) || (strlen (env_buf) <= 0)) return GNUNET_NO; - } /* Using W32 API directly here, because this pipe will * never be used outside of this function, and it's just too much of a bother * to create a GNUnet API that boxes a HANDLE (the way it is done with socks) */ lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10); - if (lsocks_pipe == 0 || lsocks_pipe == INVALID_HANDLE_VALUE) + if ( (0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe)) return GNUNET_NO; - fail = 1; do { @@ -1152,7 +1201,7 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) DWORD rd; ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL); - if (ret == 0 || rd != sizeof (count) || count == 0) + if ((0 == ret) || (sizeof (count) != rd) || (0 == count)) break; sctx->lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1)); @@ -1163,15 +1212,16 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) WSAPROTOCOL_INFOA pi; uint64_t size; SOCKET s; + ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL); - if (ret == 0 || rd != sizeof (size) || size != sizeof (pi)) + if ( (0 == ret) || (sizeof (size) != rd) || (sizeof (pi) != size) ) break; ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL); - if (ret == 0 || rd != sizeof (pi)) + if ( (0 == ret) || (sizeof (pi) != rd)) break; s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED); sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s); - if (sctx->lsocks[i] == NULL) + if (NULL == sctx->lsocks[i]) break; else if (i == count - 1) fail2 = 0; @@ -1189,13 +1239,12 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not access a pre-bound socket, will try to bind myself\n")); - for (i = 0; i < count && sctx->lsocks[i] != NULL; i++) + for (i = 0; (i < count) && (NULL != sctx->lsocks[i]); i++) GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i])); GNUNET_free_non_null (sctx->lsocks); sctx->lsocks = NULL; return GNUNET_NO; } - return GNUNET_YES; } #endif @@ -1216,6 +1265,7 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) * - REJECT_FROM (disallow allow connections from specified IPv4 subnets) * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets) * + * @param sctx service context to initialize * @return GNUNET_OK if configuration succeeded */ static int @@ -1232,15 +1282,15 @@ setup_service (struct GNUNET_SERVICE_Context *sctx) int flags; #endif - if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, "TIMEOUT")) + if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, "TIMEOUT")) { if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->serviceName, + GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->service_name, "TIMEOUT", &idleout)) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Specified value for `%s' of service `%s' is invalid\n"), - "TIMEOUT", sctx->serviceName); + "TIMEOUT", sctx->service_name); return GNUNET_SYSERR; } sctx->timeout = idleout; @@ -1249,16 +1299,16 @@ setup_service (struct GNUNET_SERVICE_Context *sctx) sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL; if (GNUNET_CONFIGURATION_have_value - (sctx->cfg, sctx->serviceName, "TOLERANT")) + (sctx->cfg, sctx->service_name, "TOLERANT")) { if (GNUNET_SYSERR == (tolerant = - GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName, + GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name, "TOLERANT"))) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Specified value for `%s' of service `%s' is invalid\n"), - "TOLERANT", sctx->serviceName); + "TOLERANT", sctx->service_name); return GNUNET_SYSERR; } } @@ -1268,9 +1318,9 @@ setup_service (struct GNUNET_SERVICE_Context *sctx) #ifndef MINGW errno = 0; if ((NULL != (lpid = getenv ("LISTEN_PID"))) && - (1 == sscanf (lpid, "%u", &pid)) && (getpid () == (pid_t) pid) && + (1 == SSCANF (lpid, "%u", &pid)) && (getpid () == (pid_t) pid) && (NULL != (nfds = getenv ("LISTEN_FDS"))) && - (1 == sscanf (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) && + (1 == SSCANF (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) { sctx->lsocks = @@ -1305,17 +1355,17 @@ setup_service (struct GNUNET_SERVICE_Context *sctx) } #endif - if ((sctx->lsocks == NULL) && + if ((NULL == sctx->lsocks) && (GNUNET_SYSERR == - GNUNET_SERVICE_get_server_addresses (sctx->serviceName, sctx->cfg, + GNUNET_SERVICE_get_server_addresses (sctx->service_name, sctx->cfg, &sctx->addrs, &sctx->addrlens))) return GNUNET_SYSERR; sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES; sctx->match_uid = - GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName, + GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name, "UNIX_MATCH_UID"); sctx->match_gid = - GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName, + GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name, "UNIX_MATCH_GID"); process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM"); process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM"); @@ -1329,15 +1379,17 @@ setup_service (struct GNUNET_SERVICE_Context *sctx) /** * Get the name of the user that'll be used * to provide the service. + * + * @param sctx service context + * @return value of the 'USERNAME' option */ static char * get_user_name (struct GNUNET_SERVICE_Context *sctx) { - char *un; if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->serviceName, + GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name, "USERNAME", &un)) return NULL; return un; @@ -1345,6 +1397,10 @@ get_user_name (struct GNUNET_SERVICE_Context *sctx) /** * Write PID file. + * + * @param sctx service context + * @param pid PID to write (should be equal to 'getpid()' + * @return GNUNET_OK on success (including no work to be done) */ static int write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) @@ -1368,7 +1424,7 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) /* we get to create a directory -- and claim it * as ours! */ GNUNET_DISK_directory_create (rdir); - if ((user != NULL) && (0 < strlen (user))) + if ((NULL != user) && (0 < strlen (user))) GNUNET_DISK_file_change_owner (rdir, user); } if (0 != ACCESS (rdir, W_OK | X_OK)) @@ -1381,7 +1437,7 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) } GNUNET_free (rdir); pidfd = FOPEN (pif, "w"); - if (pidfd == NULL) + if (NULL == pidfd) { LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "fopen", pif); GNUNET_free (pif); @@ -1391,7 +1447,7 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) if (0 > FPRINTF (pidfd, "%u", pid)) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif); GNUNET_break (0 == FCLOSE (pidfd)); - if ((user != NULL) && (0 < strlen (user))) + if ((NULL != user) && (0 < strlen (user))) GNUNET_DISK_file_change_owner (pif, user); GNUNET_free_non_null (user); GNUNET_free (pif); @@ -1400,22 +1456,30 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) /** - * Task run during shutdown. + * Task run during shutdown. Stops the server/service. * - * @param cls unused + * @param cls the 'struct GNUNET_SERVICE_Context' * @param tc unused */ static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_SERVER_Handle *server = cls; + struct GNUNET_SERVICE_Context *service = cls; + struct GNUNET_SERVER_Handle *server = service->server; - GNUNET_SERVER_destroy (server); + service->shutdown_task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (service->options & GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN)) + GNUNET_SERVER_stop_listening (server); + else + GNUNET_SERVER_destroy (server); } /** * Initial task for the service. + * + * @param cls service context + * @param tc unused */ static void service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) @@ -1424,7 +1488,7 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) unsigned int i; GNUNET_RESOLVER_connect (sctx->cfg); - if (sctx->lsocks != NULL) + if (NULL != sctx->lsocks) sctx->server = GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks, sctx->timeout, sctx->require_found); @@ -1432,15 +1496,15 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sctx->server = GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens, sctx->timeout, sctx->require_found); - if (sctx->server == NULL) + if (NULL == sctx->server) { - if (sctx->addrs != NULL) + if (NULL != sctx->addrs) { i = 0; - while (sctx->addrs[i] != NULL) + while (NULL != sctx->addrs[i]) { LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to start `%s' at `%s'\n"), - sctx->serviceName, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i])); + sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i])); i++; } } @@ -1451,29 +1515,29 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { /* install a task that will kill the server * process if the scheduler ever gets a shutdown signal */ - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, - sctx->server); + sctx->shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, + sctx); } sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers)); memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers)); i = 0; - while ((sctx->my_handlers[i].callback != NULL)) + while (NULL != sctx->my_handlers[i].callback) sctx->my_handlers[i++].callback_cls = sctx; GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers); - if (sctx->ready_confirm_fd != -1) + if (-1 != sctx->ready_confirm_fd) { GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1)); GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd)); sctx->ready_confirm_fd = -1; write_pid_file (sctx, getpid ()); } - if (sctx->addrs != NULL) + if (NULL != sctx->addrs) { i = 0; - while (sctx->addrs[i] != NULL) + while (NULL != sctx->addrs[i]) { LOG (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"), - sctx->serviceName, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i])); + sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i])); i++; } } @@ -1483,6 +1547,9 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) /** * Detach from terminal. + * + * @param sctx service context + * @return GNUNET_OK on success, GNUNET_SYSERR on error */ static int detach_terminal (struct GNUNET_SERVICE_Context *sctx) @@ -1503,7 +1570,7 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx) LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); return GNUNET_SYSERR; } - if (pid != 0) + if (0 != pid) { /* Parent */ char c; @@ -1547,7 +1614,7 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx) (void) CLOSE (nullfd); /* Detach from controlling terminal */ pid = setsid (); - if (pid == -1) + if (-1 == pid) LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid"); sctx->ready_confirm_fd = filedes[1]; #else @@ -1561,6 +1628,9 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx) /** * Set user ID. + * + * @param sctx service context + * @return GNUNET_OK on success, GNUNET_SYSERR on error */ static int set_user_id (struct GNUNET_SERVICE_Context *sctx) @@ -1574,7 +1644,7 @@ set_user_id (struct GNUNET_SERVICE_Context *sctx) errno = 0; pws = getpwnam (user); - if (pws == NULL) + if (NULL == pws) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot obtain information about user `%s': %s\n"), user, @@ -1605,13 +1675,15 @@ set_user_id (struct GNUNET_SERVICE_Context *sctx) /** * Delete the PID file that was created by our parent. + * + * @param sctx service context */ static void pid_file_delete (struct GNUNET_SERVICE_Context *sctx) { char *pif = get_pid_file_name (sctx); - if (pif == NULL) + if (NULL == pif) return; /* no PID file */ if (0 != UNLINK (pif)) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif); @@ -1625,16 +1697,16 @@ pid_file_delete (struct GNUNET_SERVICE_Context *sctx) * * @param argc number of command line arguments * @param argv command line arguments - * @param serviceName our service name - * @param opt service options + * @param service_name our service name + * @param options service options * @param task main task of the service * @param task_cls closure for task * @return GNUNET_SYSERR on error, GNUNET_OK * if we shutdown nicely */ int -GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName, - enum GNUNET_SERVICE_Options opt, GNUNET_SERVICE_Main task, +GNUNET_SERVICE_run (int argc, char *const *argv, const char *service_name, + enum GNUNET_SERVICE_Options options, GNUNET_SERVICE_Main task, void *task_cls) { #define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0) @@ -1656,7 +1728,7 @@ GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName, {'d', "daemonize", NULL, gettext_noop ("do daemonize (detach from terminal)"), 0, GNUNET_GETOPT_set_one, &do_daemonize}, - GNUNET_GETOPT_OPTION_HELP (serviceName), + GNUNET_GETOPT_OPTION_HELP (NULL), GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev), GNUNET_GETOPT_OPTION_LOGFILE (&logfile), GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION), @@ -1668,32 +1740,30 @@ GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName, loglev = NULL; cfg_fn = GNUNET_strdup (GNUNET_DEFAULT_USER_CONFIG_FILE); memset (&sctx, 0, sizeof (sctx)); - sctx.options = opt; + sctx.options = options; sctx.ready_confirm_fd = -1; sctx.ret = GNUNET_OK; sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL; sctx.task = task; sctx.task_cls = task_cls; - sctx.serviceName = serviceName; + sctx.service_name = service_name; sctx.cfg = cfg = GNUNET_CONFIGURATION_create (); /* setup subsystems */ if (GNUNET_SYSERR == - GNUNET_GETOPT_run (serviceName, service_options, argc, argv)) + GNUNET_GETOPT_run (service_name, service_options, argc, argv)) goto shutdown; - if (GNUNET_OK != GNUNET_log_setup (serviceName, loglev, logfile)) + if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile)) HANDLE_ERROR; if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfg_fn)) goto shutdown; if (GNUNET_OK != setup_service (&sctx)) goto shutdown; - if ((do_daemonize == 1) && (GNUNET_OK != detach_terminal (&sctx))) + if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx))) HANDLE_ERROR; if (GNUNET_OK != set_user_id (&sctx)) goto shutdown; -#if DEBUG_SERVICE LOG (GNUNET_ERROR_TYPE_DEBUG, - "Service `%s' runs with configuration from `%s'\n", serviceName, cfg_fn); -#endif + "Service `%s' runs with configuration from `%s'\n", service_name, cfg_fn); if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING", "SKEW_OFFSET", &skew_offset)) && @@ -1703,31 +1773,30 @@ GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName, { clock_offset = skew_offset - skew_variance; GNUNET_TIME_set_offset (clock_offset); -#if DEBUG_SERVICE LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); -#endif } /* actually run service */ err = 0; GNUNET_SCHEDULER_run (&service_task, &sctx); - + GNUNET_SPEEDUP_start_ (cfg); /* shutdown */ - if ((do_daemonize == 1) && (sctx.server != NULL)) + if ((1 == do_daemonize) && (NULL != sctx.server)) pid_file_delete (&sctx); GNUNET_free_non_null (sctx.my_handlers); shutdown: - if (sctx.ready_confirm_fd != -1) + if (-1 != sctx.ready_confirm_fd) { if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1)) LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd)); } + GNUNET_SPEEDUP_stop_ (); GNUNET_CONFIGURATION_destroy (cfg); i = 0; - if (sctx.addrs != NULL) - while (sctx.addrs[i] != NULL) + if (NULL != sctx.addrs) + while (NULL != sctx.addrs[i]) GNUNET_free (sctx.addrs[i++]); GNUNET_free_non_null (sctx.addrs); GNUNET_free_non_null (sctx.addrlens); @@ -1747,13 +1816,15 @@ shutdown: * Run a service startup sequence within an existing * initialized system. * - * @param serviceName our service name + * @param service_name our service name * @param cfg configuration to use + * @param options service options * @return NULL on error, service handle */ struct GNUNET_SERVICE_Context * -GNUNET_SERVICE_start (const char *serviceName, - const struct GNUNET_CONFIGURATION_Handle *cfg) +GNUNET_SERVICE_start (const char *service_name, + const struct GNUNET_CONFIGURATION_Handle *cfg, + enum GNUNET_SERVICE_Options options) { int i; struct GNUNET_SERVICE_Context *sctx; @@ -1762,8 +1833,9 @@ GNUNET_SERVICE_start (const char *serviceName, sctx->ready_confirm_fd = -1; /* no daemonizing */ sctx->ret = GNUNET_OK; sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL; - sctx->serviceName = serviceName; + sctx->service_name = service_name; sctx->cfg = cfg; + sctx->options = options; /* setup subsystems */ if (GNUNET_OK != setup_service (sctx)) @@ -1771,7 +1843,7 @@ GNUNET_SERVICE_start (const char *serviceName, GNUNET_SERVICE_stop (sctx); return NULL; } - if (sctx->lsocks != NULL) + if (NULL != sctx->lsocks) sctx->server = GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks, sctx->timeout, sctx->require_found); @@ -1794,6 +1866,7 @@ GNUNET_SERVICE_start (const char *serviceName, return sctx; } + /** * Obtain the server used by a service. Note that the server must NOT * be destroyed by the caller. @@ -1818,13 +1891,18 @@ GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx) { unsigned int i; + if (GNUNET_SCHEDULER_NO_TASK != sctx->shutdown_task) + { + GNUNET_SCHEDULER_cancel (sctx->shutdown_task); + sctx->shutdown_task = GNUNET_SCHEDULER_NO_TASK; + } if (NULL != sctx->server) GNUNET_SERVER_destroy (sctx->server); GNUNET_free_non_null (sctx->my_handlers); - if (sctx->addrs != NULL) + if (NULL != sctx->addrs) { i = 0; - while (sctx->addrs[i] != NULL) + while (NULL != sctx->addrs[i]) GNUNET_free (sctx->addrs[i++]); GNUNET_free (sctx->addrs); } diff --git a/src/util/speedup.c b/src/util/speedup.c new file mode 100644 index 0000000..0a005c0 --- /dev/null +++ b/src/util/speedup.c @@ -0,0 +1,92 @@ +/* + This file is part of GNUnet. + (C) 2001, 2002, 2006, 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file util/speedup.c + * @author Matthias Wachs + * @brief functions to speedup peer execution by manipulation system time + */ +#include "platform.h" +#include "gnunet_time_lib.h" +#include "gnunet_scheduler_lib.h" + +#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) + + +static struct GNUNET_TIME_Relative interval; + +static struct GNUNET_TIME_Relative delta; + +static GNUNET_SCHEDULER_TaskIdentifier speedup_task; + + +static void +do_speedup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + static long long current_offset; + + speedup_task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) + return; + current_offset += delta.rel_value; + GNUNET_TIME_set_offset (current_offset); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Speeding up execution time by %llu ms\n", delta.rel_value); + speedup_task = GNUNET_SCHEDULER_add_delayed (interval, &do_speedup, NULL); +} + + +int +GNUNET_SPEEDUP_start_ (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "SPEEDUP_INTERVAL", &interval)) + return GNUNET_SYSERR; + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "SPEEDUP_DELTA", &delta)) + return GNUNET_SYSERR; + + if ((0 == interval.rel_value) || (0 == delta.rel_value)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Speed up disabled\n"); + return GNUNET_OK; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Speed up execution time %llu ms every %llu ms\n", + delta.rel_value, interval.rel_value); + speedup_task = GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO, &do_speedup, NULL); + return GNUNET_OK; +} + + +void +GNUNET_SPEEDUP_stop_ ( ) +{ + if (GNUNET_SCHEDULER_NO_TASK != speedup_task) + { + GNUNET_SCHEDULER_cancel (speedup_task); + speedup_task = GNUNET_SCHEDULER_NO_TASK; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Stopped execution speed up\n"); +} + + + +/* end of speedup.c */ diff --git a/src/util/strings.c b/src/util/strings.c index 8000a93..11134f1 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -31,6 +31,7 @@ #endif #include "gnunet_common.h" #include "gnunet_strings_lib.h" +#include #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) @@ -170,51 +171,38 @@ GNUNET_STRINGS_byte_size_fancy (unsigned long long size) /** - * Convert a given fancy human-readable size to bytes. + * Unit conversion table entry for 'convert_with_table'. + */ +struct ConversionTable +{ + /** + * Name of the unit (or NULL for end of table). + */ + const char *name; + + /** + * Factor to apply for this unit. + */ + unsigned long long value; +}; + + +/** + * Convert a string of the form "4 X 5 Y" into a numeric value + * by interpreting "X" and "Y" as units and then multiplying + * the numbers with the values associated with the respective + * unit from the conversion table. * - * @param fancy_size human readable string (i.e. 1 MB) - * @param size set to the size in bytes + * @param input input string to parse + * @param table table with the conversion of unit names to numbers + * @param output where to store the result * @return GNUNET_OK on success, GNUNET_SYSERR on error */ -int -GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, - unsigned long long *size) +static int +convert_with_table (const char *input, + const struct ConversionTable *table, + unsigned long long *output) { - struct - { - const char *name; - unsigned long long value; - } table[] = - { - { - "B", 1}, - { - "KiB", 1024}, - { - "kB", 1000}, - { - "MiB", 1024 * 1024}, - { - "MB", 1000 * 1000}, - { - "GiB", 1024 * 1024 * 1024}, - { - "GB", 1000 * 1000 * 1000}, - { - "TiB", 1024LL * 1024LL * 1024LL * 1024LL}, - { - "TB", 1000LL * 1000LL * 1000LL * 1024LL}, - { - "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL}, - { - "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL}, - { - "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL}, - { - "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL}, - { - NULL, 0} - }; unsigned long long ret; char *in; const char *tok; @@ -223,7 +211,7 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, ret = 0; last = 0; - in = GNUNET_strdup (fancy_size); + in = GNUNET_strdup (input); for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " ")) { i = 0; @@ -235,7 +223,7 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, { ret += last; last = 0; - if (1 != sscanf (tok, "%llu", &last)) + if (1 != SSCANF (tok, "%llu", &last)) { GNUNET_free (in); return GNUNET_SYSERR; /* expected number */ @@ -243,88 +231,80 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, } } ret += last; - *size = ret; + *output = ret; GNUNET_free (in); return GNUNET_OK; } +/** + * Convert a given fancy human-readable size to bytes. + * + * @param fancy_size human readable string (i.e. 1 MB) + * @param size set to the size in bytes + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, + unsigned long long *size) +{ + static const struct ConversionTable table[] = + { + { "B", 1}, + { "KiB", 1024}, + { "kB", 1000}, + { "MiB", 1024 * 1024}, + { "MB", 1000 * 1000}, + { "GiB", 1024 * 1024 * 1024}, + { "GB", 1000 * 1000 * 1000}, + { "TiB", 1024LL * 1024LL * 1024LL * 1024LL}, + { "TB", 1000LL * 1000LL * 1000LL * 1024LL}, + { "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL}, + { "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL}, + { "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL}, + { "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL}, + { NULL, 0} + }; + + return convert_with_table (fancy_size, + table, + size); +} + + /** * Convert a given fancy human-readable time to our internal * representation. * - * @param fancy_size human readable string (i.e. 1 minute) + * @param fancy_time human readable string (i.e. 1 minute) * @param rtime set to the relative time * @return GNUNET_OK on success, GNUNET_SYSERR on error */ int -GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_size, +GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, struct GNUNET_TIME_Relative *rtime) { - struct - { - const char *name; - unsigned long long value; - } table[] = + static const struct ConversionTable table[] = { - { - "ms", 1}, - { - "s", 1000}, - { - "\"", 1000}, - { - "min", 60 * 1000}, - { - "minutes", 60 * 1000}, - { - "'", 60 * 1000}, - { - "h", 60 * 60 * 1000}, - { - "d", 24 * 60 * 60 * 1000}, - { - "a", 31557600 /* year */ }, - { - NULL, 0} + { "ms", 1}, + { "s", 1000}, + { "\"", 1000}, + { "min", 60 * 1000}, + { "minutes", 60 * 1000}, + { "'", 60 * 1000}, + { "h", 60 * 60 * 1000}, + { "d", 24 * 60 * 60 * 1000}, + { "a", 31536000000LL /* year */ }, + { NULL, 0} }; - unsigned long long ret; - char *in; - const char *tok; - unsigned long long last; - unsigned int i; + int ret; + unsigned long long val; - if ((0 == strcasecmp (fancy_size, "infinity")) || - (0 == strcasecmp (fancy_size, "forever"))) - { - *rtime = GNUNET_TIME_UNIT_FOREVER_REL; - return GNUNET_OK; - } - ret = 0; - last = 0; - in = GNUNET_strdup (fancy_size); - for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " ")) - { - i = 0; - while ((table[i].name != NULL) && (0 != strcasecmp (table[i].name, tok))) - i++; - if (table[i].name != NULL) - last *= table[i].value; - else - { - ret += last; - last = 0; - if (1 != sscanf (tok, "%llu", &last)) - { - GNUNET_free (in); - return GNUNET_SYSERR; /* expected number */ - } - } - } - ret += last; - rtime->rel_value = (uint64_t) ret; - GNUNET_free (in); - return GNUNET_OK; + ret = convert_with_table (fancy_time, + table, + &val); + rtime->rel_value = (uint64_t) val; + return ret; } /** @@ -422,6 +402,45 @@ GNUNET_STRINGS_from_utf8 (const char *input, size_t len, const char *charset) return GNUNET_STRINGS_conv (input, len, "UTF-8", charset); } +/** + * Convert the utf-8 input string to lowercase + * Output needs to be allocated appropriately + * + * @param input input string + * @param output output buffer + */ +void +GNUNET_STRINGS_utf8_tolower(const char* input, char** output) +{ + uint8_t *tmp_in; + size_t len; + + tmp_in = u8_tolower ((uint8_t*)input, strlen ((char *) input), + NULL, UNINORM_NFD, NULL, &len); + memcpy(*output, tmp_in, len); + (*output)[len] = '\0'; + free(tmp_in); +} + +/** + * Convert the utf-8 input string to uppercase + * Output needs to be allocated appropriately + * + * @param input input string + * @param output output buffer + */ +void +GNUNET_STRINGS_utf8_toupper(const char* input, char** output) +{ + uint8_t *tmp_in; + size_t len; + + tmp_in = u8_toupper ((uint8_t*)input, strlen ((char *) input), + NULL, UNINORM_NFD, NULL, &len); + memcpy(*output, tmp_in, len); + (*output)[len] = '\0'; + free(tmp_in); +} /** @@ -630,4 +649,468 @@ GNUNET_STRINGS_get_short_name (const char *filename) return short_fn; } + +/** + * Get the numeric value corresponding to a character. + * + * @param a a character + * @return corresponding numeric value + */ +static unsigned int +getValue__ (unsigned char a) +{ + if ((a >= '0') && (a <= '9')) + return a - '0'; + if ((a >= 'A') && (a <= 'V')) + return (a - 'A' + 10); + return -1; +} + + +/** + * Convert binary data to ASCII encoding. The ASCII encoding is rather + * GNUnet specific. It was chosen such that it only uses characters + * in [0-9A-V], can be produced without complex arithmetics and uses a + * small number of characters. + * Does not append 0-terminator, but returns a pointer to the place where + * it should be placed, if needed. + * + * @param data data to encode + * @param size size of data (in bytes) + * @param out buffer to fill + * @param out_size size of the buffer. Must be large enough to hold + * ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5 bytes + * @return pointer to the next byte in 'out' or NULL on error. + */ +char * +GNUNET_STRINGS_data_to_string (const unsigned char *data, size_t size, char *out, size_t out_size) +{ + /** + * 32 characters for encoding + */ + static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; + unsigned int wpos; + unsigned int rpos; + unsigned int bits; + unsigned int vbit; + + GNUNET_assert (data != NULL); + GNUNET_assert (out != NULL); + if (out_size < (((size*8) + ((size*8) % 5)) % 5)) + { + GNUNET_break (0); + return NULL; + } + vbit = 0; + wpos = 0; + rpos = 0; + bits = 0; + while ((rpos < size) || (vbit > 0)) + { + if ((rpos < size) && (vbit < 5)) + { + bits = (bits << 8) | data[rpos++]; /* eat 8 more bits */ + vbit += 8; + } + if (vbit < 5) + { + bits <<= (5 - vbit); /* zero-padding */ + GNUNET_assert (vbit == ((size * 8) % 5)); + vbit = 5; + } + if (wpos >= out_size) + { + GNUNET_break (0); + return NULL; + } + out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31]; + vbit -= 5; + } + if (wpos != out_size) + { + GNUNET_break (0); + return NULL; + } + GNUNET_assert (vbit == 0); + return &out[wpos]; +} + + +/** + * Convert ASCII encoding back to data + * out_size must match exactly the size of the data before it was encoded. + * + * @param enc the encoding + * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) + * @param out location where to store the decoded data + * @param out_size sizeof the output buffer + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +int +GNUNET_STRINGS_string_to_data (const char *enc, size_t enclen, + unsigned char *out, size_t out_size) +{ + unsigned int rpos; + unsigned int wpos; + unsigned int bits; + unsigned int vbit; + int ret; + int shift; + int encoded_len = out_size * 8; + if (encoded_len % 5 > 0) + { + vbit = encoded_len % 5; /* padding! */ + shift = 5 - vbit; + } + else + { + vbit = 0; + shift = 0; + } + if ((encoded_len + shift) / 5 != enclen) + return GNUNET_SYSERR; + + wpos = out_size; + rpos = enclen; + bits = (ret = getValue__ (enc[--rpos])) >> (5 - encoded_len % 5); + if (-1 == ret) + return GNUNET_SYSERR; + while (wpos > 0) + { + GNUNET_assert (rpos > 0); + bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits; + if (-1 == ret) + return GNUNET_SYSERR; + vbit += 5; + if (vbit >= 8) + { + out[--wpos] = (unsigned char) bits; + bits >>= 8; + vbit -= 8; + } + } + GNUNET_assert (rpos == 0); + GNUNET_assert (vbit == 0); + return GNUNET_OK; +} + + +/** + * Parse a path that might be an URI. + * + * @param path path to parse. Must be NULL-terminated. + * @param scheme_part a pointer to 'char *' where a pointer to a string that + * represents the URI scheme will be stored. Can be NULL. The string is + * allocated by the function, and should be freed by GNUNET_free() when + * it is no longer needed. + * @param path_part a pointer to 'const char *' where a pointer to the path + * part of the URI will be stored. Can be NULL. Points to the same block + * of memory as 'path', and thus must not be freed. Might point to '\0', + * if path part is zero-length. + * @return GNUNET_YES if it's an URI, GNUNET_NO otherwise. If 'path' is not + * an URI, '* scheme_part' and '*path_part' will remain unchanged + * (if they weren't NULL). + */ +int +GNUNET_STRINGS_parse_uri (const char *path, char **scheme_part, + const char **path_part) +{ + size_t len; + int i, end; + int pp_state = 0; + const char *post_scheme_part = NULL; + len = strlen (path); + for (end = 0, i = 0; !end && i < len; i++) + { + switch (pp_state) + { + case 0: + if (path[i] == ':' && i > 0) + { + pp_state += 1; + continue; + } + if (!((path[i] >= 'A' && path[i] <= 'Z') || (path[i] >= 'a' && path[i] <= 'z') + || (path[i] >= '0' && path[i] <= '9') || path[i] == '+' || path[i] == '-' + || (path[i] == '.'))) + end = 1; + break; + case 1: + case 2: + if (path[i] == '/') + { + pp_state += 1; + continue; + } + end = 1; + break; + case 3: + post_scheme_part = &path[i]; + end = 1; + break; + default: + end = 1; + } + } + if (post_scheme_part == NULL) + return GNUNET_NO; + if (scheme_part) + { + *scheme_part = GNUNET_malloc (post_scheme_part - path + 1); + memcpy (*scheme_part, path, post_scheme_part - path); + (*scheme_part)[post_scheme_part - path] = '\0'; + } + if (path_part) + *path_part = post_scheme_part; + return GNUNET_YES; +} + + +/** + * Check whether 'filename' is absolute or not, and if it's an URI + * + * @param filename filename to check + * @param can_be_uri GNUNET_YES to check for being URI, GNUNET_NO - to + * assume it's not URI + * @param r_is_uri a pointer to an int that is set to GNUNET_YES if 'filename' + * is URI and to GNUNET_NO otherwise. Can be NULL. If 'can_be_uri' is + * not GNUNET_YES, *r_is_uri is set to GNUNET_NO. + * @param r_uri_scheme a pointer to a char * that is set to a pointer to URI scheme. + * The string is allocated by the function, and should be freed with + * GNUNET_free (). Can be NULL. + * @return GNUNET_YES if 'filename' is absolute, GNUNET_NO otherwise. + */ +int +GNUNET_STRINGS_path_is_absolute (const char *filename, int can_be_uri, + int *r_is_uri, char **r_uri_scheme) +{ +#if WINDOWS + size_t len; +#endif + const char *post_scheme_path; + int is_uri; + char * uri; + /* consider POSIX paths to be absolute too, even on W32, + * as plibc expansion will fix them for us. + */ + if (filename[0] == '/') + return GNUNET_YES; + if (can_be_uri) + { + is_uri = GNUNET_STRINGS_parse_uri (filename, &uri, &post_scheme_path); + if (r_is_uri) + *r_is_uri = is_uri; + if (is_uri) + { + if (r_uri_scheme) + *r_uri_scheme = uri; + else + GNUNET_free_non_null (uri); +#if WINDOWS + len = strlen(post_scheme_path); + /* Special check for file:///c:/blah + * We want to parse 'c:/', not '/c:/' + */ + if (post_scheme_path[0] == '/' && len >= 3 && post_scheme_path[2] == ':') + post_scheme_path = &post_scheme_path[1]; +#endif + return GNUNET_STRINGS_path_is_absolute (post_scheme_path, GNUNET_NO, NULL, NULL); + } + } + else + { + is_uri = GNUNET_NO; + if (r_is_uri) + *r_is_uri = GNUNET_NO; + } +#if WINDOWS + len = strlen (filename); + if (len >= 3 && + ((filename[0] >= 'A' && filename[0] <= 'Z') + || (filename[0] >= 'a' && filename[0] <= 'z')) + && filename[1] == ':' && (filename[2] == '/' || filename[2] == '\\')) + return GNUNET_YES; +#endif + return GNUNET_NO; +} + +#if MINGW +#define _IFMT 0170000 /* type of file */ +#define _IFLNK 0120000 /* symbolic link */ +#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK) +#endif + + +/** + * Perform 'checks' on 'filename' + * + * @param filename file to check + * @param checks checks to perform + * @return GNUNET_YES if all checks pass, GNUNET_NO if at least one of them + * fails, GNUNET_SYSERR when a check can't be performed + */ +int +GNUNET_STRINGS_check_filename (const char *filename, + enum GNUNET_STRINGS_FilenameCheck checks) +{ + struct stat st; + if ( (NULL == filename) || (filename[0] == '\0') ) + return GNUNET_SYSERR; + if (0 != (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE)) + if (!GNUNET_STRINGS_path_is_absolute (filename, GNUNET_NO, NULL, NULL)) + return GNUNET_NO; + if (0 != (checks & (GNUNET_STRINGS_CHECK_EXISTS + | GNUNET_STRINGS_CHECK_IS_DIRECTORY + | GNUNET_STRINGS_CHECK_IS_LINK))) + { + if (0 != STAT (filename, &st)) + { + if (0 != (checks & GNUNET_STRINGS_CHECK_EXISTS)) + return GNUNET_NO; + else + return GNUNET_SYSERR; + } + } + if (0 != (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY)) + if (!S_ISDIR (st.st_mode)) + return GNUNET_NO; + if (0 != (checks & GNUNET_STRINGS_CHECK_IS_LINK)) + if (!S_ISLNK (st.st_mode)) + return GNUNET_NO; + return GNUNET_YES; +} + + + +/** + * Tries to convert 'zt_addr' string to an IPv6 address. + * The string is expected to have the format "[ABCD::01]:80". + * + * @param zt_addr 0-terminated string. May be mangled by the function. + * @param addrlen length of zt_addr (not counting 0-terminator). + * @param r_buf a buffer to fill. Initially gets filled with zeroes, + * then its sin6_port, sin6_family and sin6_addr are set appropriately. + * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which + * case the contents of r_buf are undefined. + */ +int +GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, + uint16_t addrlen, + struct sockaddr_in6 *r_buf) +{ + char zbuf[addrlen + 1]; + int ret; + char *port_colon; + unsigned int port; + + if (addrlen < 6) + return GNUNET_SYSERR; + memcpy (zbuf, zt_addr, addrlen); + if ('[' != zbuf[0]) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("IPv6 address did not start with `['\n")); + return GNUNET_SYSERR; + } + zbuf[addrlen] = '\0'; + port_colon = strrchr (zbuf, ':'); + if (NULL == port_colon) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("IPv6 address did contain ':' to separate port number\n")); + return GNUNET_SYSERR; + } + if (']' != *(port_colon - 1)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("IPv6 address did contain ']' before ':' to separate port number\n")); + return GNUNET_SYSERR; + } + ret = SSCANF (port_colon, ":%u", &port); + if ( (1 != ret) || (port > 65535) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("IPv6 address did contain a valid port number after the last ':'\n")); + return GNUNET_SYSERR; + } + *(port_colon-1) = '\0'; + memset (r_buf, 0, sizeof (struct sockaddr_in6)); + ret = inet_pton (AF_INET6, &zbuf[1], &r_buf->sin6_addr); + if (ret <= 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Invalid IPv6 address `%s': %s\n"), + &zbuf[1], + STRERROR (errno)); + return GNUNET_SYSERR; + } + r_buf->sin6_port = htons (port); + r_buf->sin6_family = AF_INET6; +#if HAVE_SOCKADDR_IN_SIN_LEN + r_buf->sin6_len = (u_char) sizeof (struct sockaddr_in6); +#endif + return GNUNET_OK; +} + + +/** + * Tries to convert 'zt_addr' string to an IPv4 address. + * The string is expected to have the format "1.2.3.4:80". + * + * @param zt_addr 0-terminated string. May be mangled by the function. + * @param addrlen length of zt_addr (not counting 0-terminator). + * @param r_buf a buffer to fill. + * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which case + * the contents of r_buf are undefined. + */ +int +GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, uint16_t addrlen, + struct sockaddr_in *r_buf) +{ + unsigned int temps[4]; + unsigned int port; + unsigned int cnt; + + if (addrlen < 9) + return GNUNET_SYSERR; + cnt = SSCANF (zt_addr, "%u.%u.%u.%u:%u", &temps[0], &temps[1], &temps[2], &temps[3], &port); + if (5 != cnt) + return GNUNET_SYSERR; + for (cnt = 0; cnt < 4; cnt++) + if (temps[cnt] > 0xFF) + return GNUNET_SYSERR; + if (port > 65535) + return GNUNET_SYSERR; + r_buf->sin_family = AF_INET; + r_buf->sin_port = htons (port); + r_buf->sin_addr.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16) + + (temps[2] << 8) + temps[3]); +#if HAVE_SOCKADDR_IN_SIN_LEN + r_buf->sin_len = (u_char) sizeof (struct sockaddr_in); +#endif + return GNUNET_OK; +} + + +/** + * Tries to convert 'addr' string to an IP (v4 or v6) address. + * Will automatically decide whether to treat 'addr' as v4 or v6 address. + * + * @param addr a string, may not be 0-terminated. + * @param addrlen number of bytes in addr (if addr is 0-terminated, + * 0-terminator should not be counted towards addrlen). + * @param r_buf a buffer to fill. + * @return GNUNET_OK if conversion succeded. GNUNET_SYSERR otherwise, in which + * case the contents of r_buf are undefined. + */ +int +GNUNET_STRINGS_to_address_ip (const char *addr, + uint16_t addrlen, + struct sockaddr_storage *r_buf) +{ + if (addr[0] == '[') + return GNUNET_STRINGS_to_address_ipv6 (addr, addrlen, (struct sockaddr_in6 *) r_buf); + return GNUNET_STRINGS_to_address_ipv4 (addr, addrlen, (struct sockaddr_in *) r_buf); +} + /* end of strings.c */ diff --git a/src/util/test_client.c b/src/util/test_client.c index f9d961a..54881b2 100644 --- a/src/util/test_client.c +++ b/src/util/test_client.c @@ -109,7 +109,7 @@ recv_bounce (void *cls, const struct GNUNET_MessageHeader *got) msg.type = htons (MY_TYPE); msg.size = htons (sizeof (struct GNUNET_MessageHeader)); GNUNET_assert (0 == memcmp (got, &msg, sizeof (struct GNUNET_MessageHeader))); - GNUNET_CLIENT_disconnect (client, GNUNET_YES); + GNUNET_CLIENT_disconnect (client); client = NULL; GNUNET_SERVER_destroy (server); server = NULL; @@ -137,6 +137,10 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct sockaddr *sap[2]; socklen_t slens[2]; + /* test that ill-configured client fails instantly */ + GNUNET_assert (NULL == GNUNET_CLIENT_connect ("invalid-service", cfg)); + + /* test IPC between client and server */ sap[0] = (struct sockaddr *) &sa; slens[0] = sizeof (sa); sap[1] = NULL; diff --git a/src/util/test_common_logging_runtime_loglevels.c b/src/util/test_common_logging_runtime_loglevels.c index cdf1f66..b914ae1 100644 --- a/src/util/test_common_logging_runtime_loglevels.c +++ b/src/util/test_common_logging_runtime_loglevels.c @@ -55,7 +55,7 @@ end_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; GNUNET_DISK_pipe_close (pipe_stdout); if (ok == 1) diff --git a/src/util/test_configuration.c b/src/util/test_configuration.c index b1a446f..1242a5c 100644 --- a/src/util/test_configuration.c +++ b/src/util/test_configuration.c @@ -28,7 +28,6 @@ #include "gnunet_configuration_lib.h" #include "gnunet_disk_lib.h" -#define DEBUG GNUNET_EXTRA_LOGGING /* Test Configuration Diffs Options */ enum @@ -40,10 +39,8 @@ enum ADD_NEW_ENTRY, REMOVE_SECTION, REMOVE_ENTRY, - COMPARE -#if DEBUG - , PRINT -#endif + COMPARE, + PRINT }; static struct GNUNET_CONFIGURATION_Handle *cfg; diff --git a/src/util/test_connection.c b/src/util/test_connection.c index cb69f40..4568f8e 100644 --- a/src/util/test_connection.c +++ b/src/util/test_connection.c @@ -102,7 +102,8 @@ receive_check (void *cls, const void *buf, size_t available, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive closes accepted socket\n"); #endif *ok = 0; - GNUNET_CONNECTION_destroy (asock, GNUNET_YES); + GNUNET_CONNECTION_destroy (asock); + GNUNET_CONNECTION_destroy (csock); } } @@ -119,7 +120,7 @@ run_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys listen socket\n"); #endif - GNUNET_CONNECTION_destroy (lsock, GNUNET_YES); + GNUNET_CONNECTION_destroy (lsock); #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test asks to receive on accepted socket\n"); @@ -142,7 +143,6 @@ make_hello (void *cls, size_t size, void *buf) #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys client socket\n"); #endif - GNUNET_CONNECTION_destroy (csock, GNUNET_YES); return 12; } diff --git a/src/util/test_connection_addressing.c b/src/util/test_connection_addressing.c index 2d08acc..ba7acae 100644 --- a/src/util/test_connection_addressing.c +++ b/src/util/test_connection_addressing.c @@ -99,7 +99,8 @@ receive_check (void *cls, const void *buf, size_t available, else { *ok = 0; - GNUNET_CONNECTION_destroy (asock, GNUNET_YES); + GNUNET_CONNECTION_destroy (csock); + GNUNET_CONNECTION_destroy (asock); } } @@ -128,7 +129,7 @@ run_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) expect.sin_addr.s_addr = htonl (INADDR_LOOPBACK); GNUNET_assert (0 == memcmp (&expect, v4, alen)); GNUNET_free (addr); - GNUNET_CONNECTION_destroy (lsock, GNUNET_YES); + GNUNET_CONNECTION_destroy (lsock); GNUNET_CONNECTION_receive (asock, 1024, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check, @@ -143,6 +144,7 @@ make_hello (void *cls, size_t size, void *buf) return 12; } + static void task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -167,7 +169,6 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONNECTION_notify_transmit_ready (csock, 12, GNUNET_TIME_UNIT_SECONDS, &make_hello, NULL)); - GNUNET_CONNECTION_destroy (csock, GNUNET_YES); GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &run_accept, cls); } diff --git a/src/util/test_connection_receive_cancel.c b/src/util/test_connection_receive_cancel.c index aa16724..93fcd5f 100644 --- a/src/util/test_connection_receive_cancel.c +++ b/src/util/test_connection_receive_cancel.c @@ -86,11 +86,10 @@ dead_receive (void *cls, const void *buf, size_t available, static void run_accept_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls); GNUNET_assert (asock != NULL); GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock)); - GNUNET_CONNECTION_destroy (lsock, GNUNET_YES); + GNUNET_CONNECTION_destroy (lsock); GNUNET_CONNECTION_receive (asock, 1024, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), &dead_receive, cls); @@ -103,8 +102,8 @@ receive_cancel_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) int *ok = cls; GNUNET_CONNECTION_receive_cancel (asock); - GNUNET_CONNECTION_destroy (csock, GNUNET_YES); - GNUNET_CONNECTION_destroy (asock, GNUNET_YES); + GNUNET_CONNECTION_destroy (csock); + GNUNET_CONNECTION_destroy (asock); *ok = 0; } diff --git a/src/util/test_connection_timeout.c b/src/util/test_connection_timeout.c index 2338665..c0597b2 100644 --- a/src/util/test_connection_timeout.c +++ b/src/util/test_connection_timeout.c @@ -83,8 +83,8 @@ send_kilo (void *cls, size_t size, void *buf) #endif GNUNET_assert (buf == NULL); *ok = 0; - GNUNET_CONNECTION_destroy (lsock, GNUNET_YES); - GNUNET_CONNECTION_destroy (csock, GNUNET_YES); + GNUNET_CONNECTION_destroy (lsock); + GNUNET_CONNECTION_destroy (csock); return 0; } #if VERBOSE diff --git a/src/util/test_connection_transmit_cancel.c b/src/util/test_connection_transmit_cancel.c index d81c32a..fec72d2 100644 --- a/src/util/test_connection_transmit_cancel.c +++ b/src/util/test_connection_transmit_cancel.c @@ -56,7 +56,7 @@ task_transmit_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) ¬_run, cls); GNUNET_assert (NULL != th); GNUNET_CONNECTION_notify_transmit_ready_cancel (th); - GNUNET_CONNECTION_destroy (csock, GNUNET_YES); + GNUNET_CONNECTION_destroy (csock); *ok = 0; } diff --git a/src/util/test_disk.c b/src/util/test_disk.c index 5462772..149cec0 100644 --- a/src/util/test_disk.c +++ b/src/util/test_disk.c @@ -97,7 +97,7 @@ testOpenClose () GNUNET_break (5 == GNUNET_DISK_file_write (fh, "Hello", 5)); GNUNET_DISK_file_close (fh); GNUNET_break (GNUNET_OK == - GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO)); + GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO, GNUNET_YES)); if (size != 5) return 1; GNUNET_break (0 == UNLINK (".testfile")); diff --git a/src/util/test_os_start_process.c b/src/util/test_os_start_process.c index 54638c1..0d14818 100644 --- a/src/util/test_os_start_process.c +++ b/src/util/test_os_start_process.c @@ -51,13 +51,12 @@ static GNUNET_SCHEDULER_TaskIdentifier die_task; static void end_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } - GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc)); + GNUNET_OS_process_destroy (proc); proc = NULL; GNUNET_DISK_pipe_close (hello_pipe_stdout); GNUNET_DISK_pipe_close (hello_pipe_stdin); @@ -106,7 +105,7 @@ read_call (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void -task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { char *fn; const struct GNUNET_DISK_FileHandle *stdout_read_handle; @@ -160,22 +159,79 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, stdout_read_handle, &read_call, (void *) stdout_read_handle); - } + /** * Main method, starts scheduler with task1, * checks that "ok" is correct at the end. */ static int -check () +check_run () { ok = 1; - GNUNET_SCHEDULER_run (&task, &ok); + GNUNET_SCHEDULER_run (&run_task, &ok); return ok; } +/** + * Test killing via pipe. + */ +static int +check_kill () +{ + hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); + hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); + if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL)) + { + return 1; + } + proc = + GNUNET_OS_start_process (GNUNET_YES, hello_pipe_stdin, hello_pipe_stdout, "cat", + "gnunet-service-resolver", "-", NULL); + sleep (1); /* give process time to start and open pipe */ + if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + } + GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc)); + GNUNET_OS_process_destroy (proc); + proc = NULL; + GNUNET_DISK_pipe_close (hello_pipe_stdout); + GNUNET_DISK_pipe_close (hello_pipe_stdin); + return 0; +} + + +/** + * Test killing via pipe. + */ +static int +check_instant_kill () +{ + hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); + hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); + if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL)) + { + return 1; + } + proc = + GNUNET_OS_start_process (GNUNET_YES, hello_pipe_stdin, hello_pipe_stdout, "cat", + "gnunet-service-resolver", "-", NULL); + if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + } + GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc)); + GNUNET_OS_process_destroy (proc); + proc = NULL; + GNUNET_DISK_pipe_close (hello_pipe_stdout); + GNUNET_DISK_pipe_close (hello_pipe_stdin); + return 0; +} + + int main (int argc, char *argv[]) { @@ -188,7 +244,10 @@ main (int argc, char *argv[]) "WARNING", #endif NULL); - ret = check (); + ret = 0; + ret |= check_run (); + ret |= check_kill (); + ret |= check_instant_kill (); return ret; } diff --git a/src/util/test_pseudonym.c b/src/util/test_pseudonym.c index 20a3d3d..4ce8b38 100644 --- a/src/util/test_pseudonym.c +++ b/src/util/test_pseudonym.c @@ -39,6 +39,7 @@ static GNUNET_HashCode id1; static int iter (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { int *ok = cls; @@ -54,6 +55,7 @@ iter (void *cls, const GNUNET_HashCode * pseudonym, static int noti_callback (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { int *ret = cls; @@ -64,6 +66,7 @@ noti_callback (void *cls, const GNUNET_HashCode * pseudonym, static int fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { int *ret = cls; @@ -74,6 +77,7 @@ fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym, static int false_callback (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { return GNUNET_OK; @@ -95,7 +99,10 @@ main (int argc, char *argv[]) char *name1; char *name2; char *name3; + char *name1_unique; + char *name2_unique; char *noname; + int noname_is_a_dup; int notiCount, fakenotiCount; int count; static char m[1024 * 1024 * 10]; @@ -152,15 +159,21 @@ main (int argc, char *argv[]) strlen (m) + 1)); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &id3); GNUNET_PSEUDONYM_add (cfg, &id3, meta); - name3 = GNUNET_PSEUDONYM_id_to_name (cfg, &id3); - name2 = GNUNET_PSEUDONYM_id_to_name (cfg, &id2); + GNUNET_PSEUDONYM_get_info (cfg, &id3, NULL, NULL, &name3, NULL); + CHECK (name3 != NULL); + GNUNET_PSEUDONYM_get_info (cfg, &id2, NULL, NULL, &name2, NULL); CHECK (name2 != NULL); - name1 = GNUNET_PSEUDONYM_id_to_name (cfg, &id1); + GNUNET_PSEUDONYM_get_info (cfg, &id1, NULL, NULL, &name1, NULL); CHECK (name1 != NULL); - CHECK (0 != strcmp (name1, name2)); + CHECK (0 == strcmp (name1, name2)); + name1_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id1, name1, NULL); + name2_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id2, name2, NULL); + CHECK (0 != strcmp (name1_unique, name2_unique)); CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, "fake", &rid2)); - CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2)); - CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1)); + CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2)); + CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1)); + CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2_unique, &rid2)); + CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1_unique, &rid1)); CHECK (0 == memcmp (&id1, &rid1, sizeof (GNUNET_HashCode))); CHECK (0 == memcmp (&id2, &rid2, sizeof (GNUNET_HashCode))); @@ -168,14 +181,17 @@ main (int argc, char *argv[]) GNUNET_log_skip (1, GNUNET_NO); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &fid, 0)); GNUNET_log_skip (0, GNUNET_YES); - noname = GNUNET_PSEUDONYM_id_to_name (cfg, &fid); + CHECK (GNUNET_OK == GNUNET_PSEUDONYM_get_info (cfg, &fid, NULL, NULL, &noname, &noname_is_a_dup)); CHECK (noname != NULL); + CHECK (noname_is_a_dup == GNUNET_YES); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0)); CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5)); CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10)); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5)); GNUNET_free (name1); GNUNET_free (name2); + GNUNET_free (name1_unique); + GNUNET_free (name2_unique); GNUNET_free (name3); GNUNET_free (noname); /* END OF TEST CODE */ diff --git a/src/util/test_resolver_api.c b/src/util/test_resolver_api.c index 67d5f46..4a3a203 100644 --- a/src/util/test_resolver_api.c +++ b/src/util/test_resolver_api.c @@ -64,10 +64,8 @@ check_localhost_num (void *cls, const char *hostname) return; if (0 == strcmp (hostname, "127.0.0.1")) { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct hostname `%s'.\n", hostname); -#endif (*ok) &= ~4; } else @@ -88,10 +86,8 @@ check_localhost (void *cls, const char *hostname) return; if (0 == strcmp (hostname, "localhost")) { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct hostname `%s'.\n", hostname); -#endif (*ok) &= ~2; } else @@ -113,9 +109,7 @@ check_127 (void *cls, const struct sockaddr *sa, socklen_t salen) GNUNET_assert (sizeof (struct sockaddr_in) == salen); if (sai->sin_addr.s_addr == htonl (INADDR_LOOPBACK)) { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct address.\n"); -#endif (*ok) &= ~1; } else @@ -142,10 +136,8 @@ check_local_fqdn (void *cls, const char *gnunet_fqdn) "gethostname"); return; } -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our FQDN `%s'\n"), hostname); -#endif host = gethostbyname (hostname); if (NULL == host) { @@ -180,18 +172,14 @@ check_rootserver_ip (void *cls, const struct sockaddr *sa, socklen_t salen) if (0 == strcmp (inet_ntoa (sai->sin_addr), ROOTSERVER_IP)) { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct rootserver ip address.\n"); -#endif (*ok) &= ~1; } else { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received incorrect rootserver ip address.\n"); -#endif GNUNET_break (0); } } @@ -206,10 +194,8 @@ check_rootserver_name (void *cls, const char *hostname) if (0 == strcmp (hostname, ROOTSERVER_NAME)) { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct rootserver hostname `%s'.\n", hostname); -#endif (*ok) &= ~2; } else @@ -270,10 +256,8 @@ run (void *cls, char *const *args, const char *cfgfile, count_ips++; if (count_ips > 1) { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "IP received range for root name server, but a root name server has only 1 IP\n"); -#endif GNUNET_break (0); } @@ -286,11 +270,8 @@ run (void *cls, char *const *args, const char *cfgfile, "IP received and IP for root name server differ\n"); GNUNET_break (0); } -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_INFO, "System's own forward name resolution is working\n"); -#endif - /* Resolve the same using GNUNET */ GNUNET_RESOLVER_ip_get (ROOTSERVER_NAME, AF_INET, timeout, &check_rootserver_ip, cls); @@ -305,10 +286,8 @@ run (void *cls, char *const *args, const char *cfgfile, rootserver->h_name = ""; if (1 != inet_pton (AF_INET, ROOTSERVER_IP, &rootserver_addr)) { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Could not transform root name server IP address\n"); -#endif GNUNET_break (0); } @@ -326,19 +305,14 @@ run (void *cls, char *const *args, const char *cfgfile, { if (0 != strcmp (rootserver->h_name, ROOTSERVER_NAME)) { -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received hostname and hostname for root name server differ\n"); -#endif GNUNET_break (0); } } -#if DEBUG_RESOLVER GNUNET_log (GNUNET_ERROR_TYPE_INFO, "System's own reverse name resolution is working\n"); -#endif - /* Resolve the same using GNUNET */ memset (&sa, 0, sizeof (sa)); sa.sin_family = AF_INET; @@ -410,7 +384,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; if (ok != 0) FPRINTF (stderr, "Missed some resolutions: %u\n", ok); diff --git a/src/util/test_scheduler.c b/src/util/test_scheduler.c index 01982ee..9832ade 100644 --- a/src/util/test_scheduler.c +++ b/src/util/test_scheduler.c @@ -30,37 +30,25 @@ #define VERBOSE GNUNET_NO static void -task3 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +task2 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { int *ok = cls; - /* t4 should be ready (albeit with lower priority) */ + /* t3 should be ready (albeit with lower priority) */ GNUNET_assert (1 == GNUNET_SCHEDULER_get_load (GNUNET_SCHEDULER_PRIORITY_COUNT)); - GNUNET_assert (3 == *ok); - (*ok) = 4; -} - - -static void -task2 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - int *ok = cls; - GNUNET_assert (2 == *ok); (*ok) = 3; - /* t3 will go before t4: higher priority */ - GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI, &task3, - cls); } + static void -task4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +task3 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { int *ok = cls; - GNUNET_assert (4 == *ok); - (*ok) = 5; + GNUNET_assert (3 == *ok); + (*ok) = 4; } struct GNUNET_DISK_PipeHandle *p; @@ -113,11 +101,11 @@ taskRd (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void -task5 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +task4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { int *ok = cls; - GNUNET_assert (5 == *ok); + GNUNET_assert (4 == *ok); (*ok) = 6; p = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); GNUNET_assert (NULL != p); @@ -134,17 +122,13 @@ static void task1 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { int *ok = cls; - GNUNET_SCHEDULER_TaskIdentifier t2; - GNUNET_SCHEDULER_TaskIdentifier t4; GNUNET_assert (1 == *ok); (*ok) = 2; - /* t2 will go first -- prereq for all */ - t2 = GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_NO_TASK, &task2, cls); - /* t4 will go after t2 ('add after') and after t3 (priority) */ - t4 = GNUNET_SCHEDULER_add_after (t2, &task4, cls); - /* t5 will go last (after p4) */ - GNUNET_SCHEDULER_add_after (t4, &task5, cls); + GNUNET_SCHEDULER_add_now (&task3, cls); + GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI, &task2, + cls); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &task4, cls); } @@ -225,8 +209,8 @@ taskCancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (1 == *ok); *ok = 0; - GNUNET_SCHEDULER_cancel (GNUNET_SCHEDULER_add_after - (GNUNET_SCHEDULER_NO_TASK, &taskNeverRun, NULL)); + GNUNET_SCHEDULER_cancel (GNUNET_SCHEDULER_add_now + (&taskNeverRun, NULL)); } diff --git a/src/util/test_server.c b/src/util/test_server.c index 6718c65..0faf61b 100644 --- a/src/util/test_server.c +++ b/src/util/test_server.c @@ -54,7 +54,7 @@ finish_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (ok == 6); ok = 0; GNUNET_SERVER_destroy (server); - GNUNET_CLIENT_disconnect (cc, GNUNET_NO); + GNUNET_CLIENT_disconnect (cc); GNUNET_CONFIGURATION_destroy (cfg); } diff --git a/src/util/test_server_disconnect.c b/src/util/test_server_disconnect.c index 8010695..c54f9cb 100644 --- a/src/util/test_server_disconnect.c +++ b/src/util/test_server_disconnect.c @@ -51,7 +51,7 @@ finish_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (ok == 5); ok = 0; GNUNET_SERVER_destroy (server); - GNUNET_CLIENT_disconnect (cc, GNUNET_NO); + GNUNET_CLIENT_disconnect (cc); GNUNET_CONFIGURATION_destroy (cfg); } diff --git a/src/util/test_server_mst_interrupt.c b/src/util/test_server_mst_interrupt.c new file mode 100644 index 0000000..fd34bd0 --- /dev/null +++ b/src/util/test_server_mst_interrupt.c @@ -0,0 +1,81 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file util/test_server_mst_interrupt.c + * @brief test for interrupt message processing in server_mst.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_protocols.h" +#include "gnunet_client_lib.h" +#include "gnunet_scheduler_lib.h" +#include "gnunet_server_lib.h" +#include "gnunet_time_lib.h" + +static struct GNUNET_SERVER_MessageStreamTokenizer * mst; +static int ret; + +/* Callback destroying mst with data in buffer */ +static int +mst_cb (void *cls, void *client, + const struct GNUNET_MessageHeader * message) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MST gave me message, destroying\n"); + GNUNET_SERVER_mst_destroy (mst); + return GNUNET_SYSERR; +} + +/** + * Main method + */ +static int +check () +{ + + struct GNUNET_PeerIdentity id; + struct GNUNET_MessageHeader msg[2]; + + /* Prepare */ + memset (&id, sizeof (id), '\0'); + msg[0].size = htons (sizeof (msg)); + msg[0].type = htons (sizeof (GNUNET_MESSAGE_TYPE_DUMMY)); + + mst = GNUNET_SERVER_mst_create(mst_cb, NULL); + + GNUNET_SERVER_mst_receive(mst, &id, (const char *) &msg, 2 * sizeof (msg), GNUNET_NO, GNUNET_NO); + + /* If we reach this line, it did not crash */ + ret = 0; + + return ret; +} + +int +main (int argc, char *argv[]) +{ + ret = 1; + + GNUNET_log_setup ("test_server", "WARNING", NULL); + check (); + + return ret; +} + +/* 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 index 06a4b71..ad56071 100644 --- a/src/util/test_server_with_client.c +++ b/src/util/test_server_with_client.c @@ -89,7 +89,7 @@ recv_cb (void *cls, struct GNUNET_SERVER_Client *argclient, break; case 4: ok++; - GNUNET_CLIENT_disconnect (client, GNUNET_YES); + GNUNET_CLIENT_disconnect (client); GNUNET_SERVER_receive_done (argclient, GNUNET_OK); break; default: diff --git a/src/util/test_server_with_client_unix.c b/src/util/test_server_with_client_unix.c index 99af4e8..eae80e4 100644 --- a/src/util/test_server_with_client_unix.c +++ b/src/util/test_server_with_client_unix.c @@ -68,7 +68,7 @@ recv_cb (void *cls, struct GNUNET_SERVER_Client *argclient, break; case 4: ok++; - GNUNET_CLIENT_disconnect (client, GNUNET_YES); + GNUNET_CLIENT_disconnect (client); GNUNET_SERVER_receive_done (argclient, GNUNET_OK); break; default: diff --git a/src/util/test_service.c b/src/util/test_service.c index 049282d..5547249 100644 --- a/src/util/test_service.c +++ b/src/util/test_service.c @@ -41,18 +41,49 @@ static struct GNUNET_SERVICE_Context *sctx; static int ok = 1; +static struct GNUNET_CLIENT_Connection *client; + + + + +static void +do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (NULL != client) + { + GNUNET_CLIENT_disconnect (client); + client = NULL; + } + if (NULL != sctx) + { + GNUNET_SERVICE_stop (sctx); + sctx = NULL; + } + else + { + GNUNET_SCHEDULER_shutdown (); + } +} + static size_t build_msg (void *cls, size_t size, void *buf) { - struct GNUNET_CLIENT_Connection *client = cls; struct GNUNET_MessageHeader *msg = buf; + if (size < sizeof (struct GNUNET_MessageHeader)) + { + /* timeout */ + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&do_stop, NULL); + ok = 1; + return 0; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected, transmitting\n"); GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); msg->type = htons (MY_TYPE); msg->size = htons (sizeof (struct GNUNET_MessageHeader)); - GNUNET_CLIENT_disconnect (client, GNUNET_NO); return sizeof (struct GNUNET_MessageHeader); } @@ -61,7 +92,6 @@ static void ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; - struct GNUNET_CLIENT_Connection *client; GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service confirmed running\n"); @@ -72,27 +102,19 @@ ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CLIENT_notify_transmit_ready (client, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_SECONDS, GNUNET_NO, - &build_msg, client); -} - - -static void -do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_SERVICE_stop (sctx); + &build_msg, NULL); } static void -recv_cb (void *cls, struct GNUNET_SERVER_Client *client, +recv_cb (void *cls, struct GNUNET_SERVER_Client *sc, const struct GNUNET_MessageHeader *message) { + if (NULL == message) + return; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving client message...\n"); - GNUNET_SERVER_receive_done (client, GNUNET_OK); - if (sctx != NULL) - GNUNET_SCHEDULER_add_now (&do_stop, NULL); - else - GNUNET_SCHEDULER_shutdown (); + GNUNET_SERVER_receive_done (sc, GNUNET_OK); + GNUNET_SCHEDULER_add_now (&do_stop, NULL); ok = 0; } @@ -146,7 +168,6 @@ static void ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; - struct GNUNET_CLIENT_Connection *client; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 ready\n"); GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); @@ -156,7 +177,7 @@ ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CLIENT_notify_transmit_ready (client, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_SECONDS, GNUNET_NO, - &build_msg, client); + &build_msg, NULL); } static void @@ -206,7 +227,7 @@ start_stop_main (void *cls, char *const *args, const char *cfgfile, int *ret = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting service using start method\n"); - sctx = GNUNET_SERVICE_start ("test_service", cfg); + sctx = GNUNET_SERVICE_start ("test_service", cfg, GNUNET_SERVICE_OPTION_NONE); GNUNET_assert (NULL != sctx); runner (cls, GNUNET_SERVICE_get_server (sctx), cfg); *ret = 0; @@ -257,7 +278,6 @@ main (int argc, char *argv[]) NULL); ret += check (); ret += check (); - // FIXME #ifndef MINGW s = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); @@ -280,7 +300,6 @@ main (int argc, char *argv[]) ret += check6 (); } ret += check_start_stop (); - return ret; } diff --git a/src/util/test_speedup.c b/src/util/test_speedup.c new file mode 100644 index 0000000..03cffbd --- /dev/null +++ b/src/util/test_speedup.c @@ -0,0 +1,120 @@ +/* + This file is part of GNUnet. + (C) 2001, 2002, 2003, 2004, 2006, 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file util/test_speedup.c + * @brief testcase for speedup.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_program_lib.h" +#include "gnunet_time_lib.h" +#include "gnunet_strings_lib.h" + +/** + * Start time of the testcase + */ +static struct GNUNET_TIME_Absolute start; + +/** + * End-time of the testcase (affected by speed-up) + */ +static struct GNUNET_TIME_Absolute end; + +/** + * Number of cycles we have spent in 'run'. + */ +static unsigned int cycles; + + +/** + * Main task that is scheduled with the speed-up. + * + * @param cls NULL + * @param tc scheduler context, unused + */ +static void +run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + cycles++; + fprintf (stderr, "..%u", cycles); + if (cycles <= 5) + { + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &run, NULL); + return; + } + end = GNUNET_TIME_absolute_get(); + fprintf (stderr, "\n"); + fflush(stdout); +} + + +/** + * + */ +static void +check (void *cls, char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle * + cfg) +{ + fprintf (stderr, "0"); + fflush(stdout); + GNUNET_SCHEDULER_add_now(&run, NULL); +} + + +int +main (int argc, char *argv[]) +{ + static char *const argvn[] = { "test-speedup", + "-c", "test_speedup_data.conf", + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + time_t start_real; + time_t end_real; + struct GNUNET_TIME_Relative delta; + + start_real = time (NULL); + start = GNUNET_TIME_absolute_get(); + GNUNET_PROGRAM_run ((sizeof (argvn) / sizeof (char *)) - 1, argvn, "test-speedup", + "nohelp", options, &check, NULL); + + end_real = time (NULL); + delta = GNUNET_TIME_absolute_get_difference(start, end); + + if (delta.rel_value > ((end_real - start_real) * 1500LL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Execution time in GNUnet time: %llu ms\n", + (unsigned long long) delta.rel_value); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Execution time in system time: %llu ms\n", + (unsigned long long) ((end_real - start_real) * 1000LL)); + return 0; + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Execution time in GNUnet time: %llu ms\n", + (unsigned long long) delta.rel_value); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Execution time in system time: %llu ms\n", + (unsigned long long) ((end_real - start_real) * 1000LL)); + return 1; +} + +/* end of test_speedup.c */ diff --git a/src/util/test_speedup_data.conf b/src/util/test_speedup_data.conf new file mode 100644 index 0000000..699cdc9 --- /dev/null +++ b/src/util/test_speedup_data.conf @@ -0,0 +1,3 @@ +[testing] +SPEEDUP_INTERVAL = 100 ms +SPEEDUP_DELTA = 100 ms diff --git a/src/util/test_strings.c b/src/util/test_strings.c index 570776a..b662623 100644 --- a/src/util/test_strings.c +++ b/src/util/test_strings.c @@ -97,10 +97,12 @@ check () GNUNET_free (r); b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "ASCII"); WANT ("TEST", b); +#if ENABLE_NLS && HAVE_ICONV GNUNET_log_skip (2, GNUNET_NO); b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "unknown"); GNUNET_log_skip (0, GNUNET_YES); WANT ("TEST", b); +#endif return 0; } diff --git a/src/util/test_time.c b/src/util/test_time.c index 788884f..b4c7233 100644 --- a/src/util/test_time.c +++ b/src/util/test_time.c @@ -43,9 +43,9 @@ check () struct GNUNET_TIME_RelativeNBO reln; unsigned int i; - forever = GNUNET_TIME_absolute_get_forever (); - relForever = GNUNET_TIME_relative_get_forever (); - relUnit = GNUNET_TIME_relative_get_unit (); + forever = GNUNET_TIME_UNIT_FOREVER_ABS; + relForever = GNUNET_TIME_UNIT_FOREVER_REL; + relUnit = GNUNET_TIME_UNIT_MILLISECONDS; zero.abs_value = 0; last = now = GNUNET_TIME_absolute_get (); @@ -62,7 +62,7 @@ check () GNUNET_assert (rel.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value); /*check zero */ rel.rel_value = (UINT64_MAX) - 1024; - GNUNET_assert (GNUNET_TIME_relative_get_zero ().rel_value == + GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value == GNUNET_TIME_relative_multiply (rel, 0).rel_value); /* test infinity-check for relative to absolute */ @@ -77,7 +77,7 @@ check () GNUNET_TIME_relative_to_absolute (rel).abs_value); /*check forever */ rel.rel_value = UINT64_MAX; - GNUNET_assert (GNUNET_TIME_absolute_get_forever ().abs_value == + GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value == GNUNET_TIME_relative_to_absolute (rel).abs_value); /* check overflow for r2a */ rel.rel_value = (UINT64_MAX) - 1024; @@ -125,8 +125,8 @@ check () rel = GNUNET_TIME_absolute_get_remaining (future); GNUNET_assert (rel.rel_value > 0); GNUNET_assert (rel.rel_value <= 1000000); - forever = GNUNET_TIME_absolute_get_forever (); - GNUNET_assert (GNUNET_TIME_relative_get_forever ().rel_value == + forever = GNUNET_TIME_UNIT_FOREVER_ABS; + GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value == GNUNET_TIME_absolute_get_remaining (forever).rel_value); /* check endianess */ @@ -175,13 +175,13 @@ check () /* check Return absolute time of 0ms */ - zero = GNUNET_TIME_absolute_get_zero (); + zero = GNUNET_TIME_UNIT_ZERO_ABS; /* check GNUNET_TIME_calculate_eta */ last.abs_value = GNUNET_TIME_absolute_get ().abs_value - 1024; - forever = GNUNET_TIME_absolute_get_forever (); + forever = GNUNET_TIME_UNIT_FOREVER_ABS; forever.abs_value = forever.abs_value - 1024; - GNUNET_assert (GNUNET_TIME_absolute_get_zero ().abs_value == + GNUNET_assert (GNUNET_TIME_UNIT_ZERO_ABS.abs_value == GNUNET_TIME_calculate_eta (forever, 50000, 100000).rel_value); /* check zero */ GNUNET_log_skip (1, GNUNET_NO); @@ -199,11 +199,11 @@ check () GNUNET_assert (1024 == GNUNET_TIME_relative_subtract (relForever, rel).rel_value); /*check zero */ - GNUNET_assert (GNUNET_TIME_relative_get_zero ().rel_value == + GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value == GNUNET_TIME_relative_subtract (rel, relForever).rel_value); /*check forever */ rel.rel_value = UINT64_MAX; - GNUNET_assert (GNUNET_TIME_relative_get_forever ().rel_value == + GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value == GNUNET_TIME_relative_subtract (rel, relForever).rel_value); /*check GNUNET_TIME_relative_min */ diff --git a/src/util/time.c b/src/util/time.c index c57ccd1..7467b44 100644 --- a/src/util/time.c +++ b/src/util/time.c @@ -68,7 +68,7 @@ GNUNET_TIME_absolute_get () * Return relative time of 0ms. */ struct GNUNET_TIME_Relative -GNUNET_TIME_relative_get_zero () +GNUNET_TIME_relative_get_zero_ () { static struct GNUNET_TIME_Relative zero; @@ -80,28 +80,63 @@ GNUNET_TIME_relative_get_zero () * Return absolute time of 0ms. */ struct GNUNET_TIME_Absolute -GNUNET_TIME_absolute_get_zero () +GNUNET_TIME_absolute_get_zero_ () { static struct GNUNET_TIME_Absolute zero; return zero; } + /** * Return relative time of 1ms. */ struct GNUNET_TIME_Relative -GNUNET_TIME_relative_get_unit () +GNUNET_TIME_relative_get_unit_ () { static struct GNUNET_TIME_Relative one = { 1 }; return one; } + +/** + * Return relative time of 1s. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_second_ () +{ + static struct GNUNET_TIME_Relative one = { 1000 }; + return one; +} + + +/** + * Return relative time of 1 minute. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_minute_ () +{ + static struct GNUNET_TIME_Relative one = { 60 * 1000 }; + return one; +} + + +/** + * Return relative time of 1 hour. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_hour_ () +{ + static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 }; + return one; +} + + /** * Return "forever". */ struct GNUNET_TIME_Relative -GNUNET_TIME_relative_get_forever () +GNUNET_TIME_relative_get_forever_ () { static struct GNUNET_TIME_Relative forever = { UINT64_MAX }; return forever; @@ -111,7 +146,7 @@ GNUNET_TIME_relative_get_forever () * Return "forever". */ struct GNUNET_TIME_Absolute -GNUNET_TIME_absolute_get_forever () +GNUNET_TIME_absolute_get_forever_ () { static struct GNUNET_TIME_Absolute forever = { UINT64_MAX }; return forever; @@ -129,13 +164,13 @@ GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel) struct GNUNET_TIME_Absolute ret; if (rel.rel_value == UINT64_MAX) - return GNUNET_TIME_absolute_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_ABS; struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); if (rel.rel_value + now.abs_value < rel.rel_value) { GNUNET_break (0); /* overflow... */ - return GNUNET_TIME_absolute_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_ABS; } ret.abs_value = rel.rel_value + now.abs_value; return ret; @@ -193,7 +228,7 @@ GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1, * * @param t1 first timestamp * @param t2 other timestamp - * @return timestamp that is smaller + * @return timestamp that is bigger */ struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1, @@ -215,11 +250,11 @@ GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future) struct GNUNET_TIME_Relative ret; if (future.abs_value == UINT64_MAX) - return GNUNET_TIME_relative_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_REL; struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); if (now.abs_value > future.abs_value) - return GNUNET_TIME_relative_get_zero (); + return GNUNET_TIME_UNIT_ZERO; ret.rel_value = future.abs_value - now.abs_value; return ret; } @@ -238,9 +273,9 @@ GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative ret; if (end.abs_value == UINT64_MAX) - return GNUNET_TIME_relative_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_REL; if (end.abs_value < start.abs_value) - return GNUNET_TIME_relative_get_zero (); + return GNUNET_TIME_UNIT_ZERO; ret.rel_value = end.abs_value - start.abs_value; return ret; } @@ -260,7 +295,7 @@ GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence) now = GNUNET_TIME_absolute_get (); GNUNET_assert (whence.abs_value != UINT64_MAX); if (whence.abs_value > now.abs_value) - return GNUNET_TIME_relative_get_zero (); + return GNUNET_TIME_UNIT_ZERO; ret.rel_value = now.abs_value - whence.abs_value; return ret; } @@ -279,11 +314,11 @@ GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Absolute ret; if ((start.abs_value == UINT64_MAX) || (duration.rel_value == UINT64_MAX)) - return GNUNET_TIME_absolute_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_ABS; if (start.abs_value + duration.rel_value < start.abs_value) { GNUNET_break (0); - return GNUNET_TIME_absolute_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_ABS; } ret.abs_value = start.abs_value + duration.rel_value; return ret; @@ -325,12 +360,12 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel, struct GNUNET_TIME_Relative ret; if (factor == 0) - return GNUNET_TIME_relative_get_zero (); + return GNUNET_TIME_UNIT_ZERO; ret.rel_value = rel.rel_value * (unsigned long long) factor; if (ret.rel_value / factor != rel.rel_value) { GNUNET_break (0); - return GNUNET_TIME_relative_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_REL; } return ret; } @@ -401,11 +436,11 @@ GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative ret; if ((a1.rel_value == UINT64_MAX) || (a2.rel_value == UINT64_MAX)) - return GNUNET_TIME_relative_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_REL; if (a1.rel_value + a2.rel_value < a1.rel_value) { GNUNET_break (0); - return GNUNET_TIME_relative_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_REL; } ret.rel_value = a1.rel_value + a2.rel_value; return ret; @@ -426,9 +461,9 @@ GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative ret; if (a2.rel_value >= a1.rel_value) - return GNUNET_TIME_relative_get_zero (); + return GNUNET_TIME_UNIT_ZERO; if (a1.rel_value == UINT64_MAX) - return GNUNET_TIME_relative_get_forever (); + return GNUNET_TIME_UNIT_FOREVER_REL; ret.rel_value = a1.rel_value - a2.rel_value; return ret; } diff --git a/src/util/util.conf b/src/util/util.conf index ba9dfec..f3d301e 100644 --- a/src/util/util.conf +++ b/src/util/util.conf @@ -14,3 +14,5 @@ HOME = $SERVICEHOME [TESTING] WEAKRANDOM = NO +SPEEDUP_INTERVAL = 0 ms +SPEEDUP_DELTA = 0 ms diff --git a/src/util/winproc.c b/src/util/winproc.c index 7cd80a9..b75fc86 100644 --- a/src/util/winproc.c +++ b/src/util/winproc.c @@ -27,7 +27,6 @@ #include "platform.h" #include "gnunet_common.h" -#define DEBUG_WINPROC 0 #ifdef MINGW @@ -146,7 +145,7 @@ GNInitWinEnv () plibc_initialized (); plibc_set_panic_proc (plibc_panic); - ret = plibc_init ("GNU", PACKAGE); + ret = plibc_init_utf8 ("GNU", PACKAGE, 1); /* don't load other DLLs twice */ if (hNTDLL) diff --git a/src/vpn/Makefile.in b/src/vpn/Makefile.in index 575375b..54ca311 100644 --- a/src/vpn/Makefile.in +++ b/src/vpn/Makefile.in @@ -246,6 +246,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -279,6 +280,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 26deeee..b7756a3 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c @@ -460,7 +460,7 @@ send_client_reply (struct GNUNET_SERVER_Client *client, int result_af, const void *addr) { - char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)]; + char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)] GNUNET_ALIGN; struct RedirectToIpResponseMessage *res; size_t rlen; @@ -605,7 +605,7 @@ tunnel_peer_disconnect_handler (void *cls, "Peer %s disconnected from tunnel.\n", GNUNET_i2s (peer)); GNUNET_STATISTICS_update (stats, - gettext_noop ("# Peers connected to mesh tunnels"), + gettext_noop ("# peers connected to mesh tunnels"), -1, GNUNET_NO); if (NULL != ts->th) { @@ -642,7 +642,7 @@ tunnel_peer_connect_handler (void *cls, "Peer %s connected to tunnel.\n", GNUNET_i2s (peer)); GNUNET_STATISTICS_update (stats, - gettext_noop ("# Peers connected to mesh tunnels"), + gettext_noop ("# peers connected to mesh tunnels"), 1, GNUNET_NO); if (NULL == ts->client) return; /* nothing to do */ @@ -894,6 +894,8 @@ route_packet (struct DestinationEntry *destination, GNUNET_break (0); return; } + tcp = NULL; /* make compiler happy */ + icmp = NULL; /* make compiler happy */ udp = payload; if (udp->len < sizeof (struct GNUNET_TUN_UdpHeader)) { @@ -919,6 +921,8 @@ route_packet (struct DestinationEntry *destination, GNUNET_break (0); return; } + udp = NULL; /* make compiler happy */ + icmp = NULL; /* make compiler happy */ tcp = payload; if (tcp->off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) { @@ -950,6 +954,8 @@ route_packet (struct DestinationEntry *destination, GNUNET_break (0); return; } + tcp = NULL; /* make compiler happy */ + udp = NULL; /* make compiler happy */ icmp = payload; source_port = 0; destination_port = 0; @@ -1498,7 +1504,7 @@ route_packet (struct DestinationEntry *destination, * @param client NULL * @param message message we got from the client (VPN tunnel interface) */ -static void +static int message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, const struct GNUNET_MessageHeader *message) { @@ -1515,7 +1521,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, (mlen < sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader)) ) { GNUNET_break (0); - return; + return GNUNET_OK; } tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1]; mlen -= (sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader)); @@ -1529,7 +1535,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, { /* blame kernel */ GNUNET_break (0); - return; + return GNUNET_OK; } pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1]; get_destination_key_from_ip (AF_INET6, @@ -1551,7 +1557,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, &pkt6->destination_address, buf, sizeof (buf))); - return; + return GNUNET_OK; } route_packet (de, AF_INET6, @@ -1570,7 +1576,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, { /* blame kernel */ GNUNET_break (0); - return; + return GNUNET_OK; } pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; get_destination_key_from_ip (AF_INET, @@ -1592,13 +1598,13 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, &pkt4->destination_address, buf, sizeof (buf))); - return; + return GNUNET_OK; } if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header)) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received IPv4 packet with options (dropping it)\n")); - return; + return GNUNET_OK; } route_packet (de, AF_INET, @@ -1615,6 +1621,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, (unsigned int) ntohs (tun->proto)); break; } + return GNUNET_OK; } @@ -1736,7 +1743,7 @@ receive_icmp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, { /* reserve some extra space in case we have an ICMP type here where we will need to make up the payload ourselves */ - char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8]; + char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN; struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; @@ -1873,7 +1880,7 @@ receive_icmp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; { - char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8]; + char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; @@ -2077,7 +2084,7 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; { - char buf[size]; + char buf[size] GNUNET_ALIGN; struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; @@ -2122,7 +2129,7 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; { - char buf[size]; + char buf[size] GNUNET_ALIGN; struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; @@ -2235,7 +2242,7 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; { - char buf[size]; + char buf[size] GNUNET_ALIGN; struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; @@ -2274,7 +2281,7 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; { - char buf[size]; + char buf[size] GNUNET_ALIGN; struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; @@ -2476,6 +2483,65 @@ expire_destination (struct DestinationEntry *except) } +/** + * Allocate an IP address for the response. + * + * @param result_af desired address family; set to the actual + * address family; can initially be AF_UNSPEC if there + * is no preference; will be set to AF_UNSPEC if the + * allocation failed + * @param addr set to either v4 or v6 depending on which + * storage location was used; set to NULL if allocation failed + * @param v4 storage space for an IPv4 address + * @param v6 storage space for an IPv6 address + * @return GNUNET_OK normally, GNUNET_SYSERR if '*result_af' was + * an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC) + */ +static int +allocate_response_ip (int *result_af, + void **addr, + struct in_addr *v4, + struct in6_addr *v6) +{ + *addr = NULL; + switch (*result_af) + { + case AF_INET: + if (GNUNET_OK != + allocate_v4_address (v4)) + *result_af = AF_UNSPEC; + else + *addr = v4; + break; + case AF_INET6: + if (GNUNET_OK != + allocate_v6_address (v6)) + *result_af = AF_UNSPEC; + else + *addr = v6; + break; + case AF_UNSPEC: + if (GNUNET_OK == + allocate_v4_address (v4)) + { + *addr = v4; + *result_af = AF_INET; + } + else if (GNUNET_OK == + allocate_v6_address (v6)) + { + *addr = v6; + *result_af = AF_INET6; + } + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + /** * A client asks us to setup a redirection via some exit * node to a particular IP. Setup the redirection and @@ -2537,40 +2603,11 @@ service_redirect_to_ip (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *cl } /* allocate response IP */ - addr = NULL; result_af = (int) htonl (msg->result_af); - switch (result_af) + if (GNUNET_OK != allocate_response_ip (&result_af, + &addr, + &v4, &v6)) { - case AF_INET: - if (GNUNET_OK != - allocate_v4_address (&v4)) - result_af = AF_UNSPEC; - else - addr = &v4; - break; - case AF_INET6: - if (GNUNET_OK != - allocate_v6_address (&v6)) - result_af = AF_UNSPEC; - else - addr = &v6; - break; - case AF_UNSPEC: - if (GNUNET_OK == - allocate_v4_address (&v4)) - { - addr = &v4; - result_af = AF_INET; - } - else if (GNUNET_OK == - allocate_v6_address (&v6)) - { - addr = &v6; - result_af = AF_INET6; - } - break; - default: - GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } @@ -2673,40 +2710,11 @@ service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Clien msg = (const struct RedirectToServiceRequestMessage *) message; /* allocate response IP */ - addr = NULL; result_af = (int) htonl (msg->result_af); - switch (result_af) + if (GNUNET_OK != allocate_response_ip (&result_af, + &addr, + &v4, &v6)) { - case AF_INET: - if (GNUNET_OK != - allocate_v4_address (&v4)) - result_af = AF_UNSPEC; - else - addr = &v4; - break; - case AF_INET6: - if (GNUNET_OK != - allocate_v6_address (&v6)) - result_af = AF_UNSPEC; - else - addr = &v6; - break; - case AF_UNSPEC: - if (GNUNET_OK == - allocate_v4_address (&v4)) - { - addr = &v4; - result_af = AF_INET; - } - else if (GNUNET_OK == - allocate_v6_address (&v6)) - { - addr = &v6; - result_af = AF_INET6; - } - break; - default: - GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } diff --git a/src/vpn/test_gnunet_vpn.c b/src/vpn/test_gnunet_vpn.c index 005c7bd..4c941bd 100644 --- a/src/vpn/test_gnunet_vpn.c +++ b/src/vpn/test_gnunet_vpn.c @@ -35,7 +35,7 @@ #define VERBOSE GNUNET_NO -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 45) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) struct PeerContext { @@ -131,9 +131,7 @@ mhd_ahc (void *cls, return MHD_YES; } *unused = NULL; -#if VERBOSE - fprintf (stderr, "MHD sends respose for request to URL `%s'\n", url); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MHD sends respose for request to URL `%s'\n", url); response = MHD_create_response_from_buffer (strlen (url), (void *) url, MHD_RESPMEM_MUST_COPY); @@ -225,8 +223,9 @@ curl_main () { if (msg->data.result != CURLE_OK) { - printf ("%s failed at %s:%d: `%s'\n", - "curl_multi_perform", + fprintf (stderr, + "%s failed at %s:%d: `%s'\n", + "curl_multi_perform", __FILE__, __LINE__, curl_easy_strerror (msg->data.result)); global_ret = 1; @@ -238,12 +237,16 @@ curl_main () curl = NULL; multi = NULL; if (cbc.pos != strlen ("/hello_world")) + { + GNUNET_break (0); global_ret = 2; + } if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) + { + GNUNET_break (0); global_ret = 3; -#if VERBOSE - fprintf (stderr, "Download complete, shutting down!\n"); -#endif + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download complete, shutting down!\n"); do_shutdown (); return; } @@ -260,7 +263,6 @@ curl_main () &ws, max + 1); curl_task_id = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, delay, &nrs, &nws, @@ -313,9 +315,7 @@ allocation_cb (void *cls, multi = curl_multi_init (); GNUNET_assert (multi != NULL); GNUNET_assert (CURLM_OK == curl_multi_add_handle (multi, curl)); -#if VERBOSE - fprintf (stderr, "Beginning HTTP download from `%s'\n", url); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Beginning HTTP download from `%s'\n", url); curl_main (); } @@ -343,6 +343,7 @@ ctrl_c_shutdown (void *cls, { ctrl_c_task_id = GNUNET_SCHEDULER_NO_TASK; do_shutdown (); + GNUNET_break (0); global_ret = 1; } @@ -378,7 +379,6 @@ mhd_main () &ws, max_fd + 1); mhd_task_id = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_TASK, delay, &nrs, &nws, @@ -443,9 +443,6 @@ setup_peer (struct PeerContext *p, const char *cfgname) p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif "-c", cfgname, NULL); #endif GNUNET_assert (NULL != p->arm_proc); @@ -465,7 +462,7 @@ stop_peer (struct PeerContext *p) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_close (p->arm_proc); + GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; } #endif @@ -507,15 +504,12 @@ main (int argc, char *const *argv) "test_gnunet_vpn", "-c", "test_gnunet_vpn.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; - + if (0 != ACCESS ("/dev/net/tun", R_OK)) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, @@ -536,6 +530,7 @@ main (int argc, char *const *argv) "Change $PATH ('.' in $PATH before $GNUNET_PREFIX/bin is problematic) or permissions (run 'make install' as root) to fix this!\n"); return 0; } + GNUNET_CRYPTO_setup_hostkey ("test_gnunet_vpn.conf"); bin = argv[0]; if (NULL != strstr (bin, "lt-")) bin = strstr (bin, "lt-") + 4; @@ -585,14 +580,13 @@ main (int argc, char *const *argv) if (0 != curl_global_init (CURL_GLOBAL_WIN32)) + { + fprintf (stderr, "failed to initialize curl\n"); return 2; + } setup_peer (&p1, "test_gnunet_vpn.conf"); GNUNET_log_setup ("test_gnunet_vpn", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, "test_gnunet_vpn", "nohelp", options, &run, NULL); diff --git a/src/vpn/test_gnunet_vpn.conf b/src/vpn/test_gnunet_vpn.conf index 5aec0c5..bdac1a5 100644 --- a/src/vpn/test_gnunet_vpn.conf +++ b/src/vpn/test_gnunet_vpn.conf @@ -2,6 +2,8 @@ SERVICEHOME = /tmp/gnunet-test-vpn/ DEFAULTCONFIG = test_gnunet_vpn.conf +[transport] +PLUGINS = tcp [arm] DEFAULTSERVICES = statistics exit vpn @@ -19,7 +21,8 @@ EXIT_IFNAME = eth1 WEAKRANDOM = YES HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat - +[nse] +WORKBITS = 1 # repeating some values from the default configurations # here as the respective network addresses are also @@ -35,3 +38,6 @@ IPV6ADDR = FC5A:04E1:C2BA::1 IPV6PREFIX = 96 IPV4ADDR = 169.254.86.1 IPV4MASK = 255.255.255.0 + +[gns] +AUTOSTART = NO diff --git a/src/vpn/vpn.h b/src/vpn/vpn.h index e937f5e..bec3a5b 100644 --- a/src/vpn/vpn.h +++ b/src/vpn/vpn.h @@ -115,7 +115,7 @@ struct RedirectToServiceRequestMessage /** * Service descriptor identifying the service. */ - GNUNET_HashCode service_descriptor GNUNET_PACKED; + GNUNET_HashCode service_descriptor; /** * Unique ID to match a future response to this request. diff --git a/src/vpn/vpn_api.c b/src/vpn/vpn_api.c index 31d17f8..5b70d19 100644 --- a/src/vpn/vpn_api.c +++ b/src/vpn/vpn_api.c @@ -402,7 +402,7 @@ reconnect (struct GNUNET_VPN_Handle *vh) GNUNET_CLIENT_notify_transmit_ready_cancel (vh->th); vh->th = NULL; } - GNUNET_CLIENT_disconnect (vh->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (vh->client); vh->client = NULL; vh->request_id_gen = 0; for (rr = vh->rr_head; NULL != rr; rr = rr->next) @@ -591,7 +591,7 @@ GNUNET_VPN_disconnect (struct GNUNET_VPN_Handle *vh) } if (NULL != vh->client) { - GNUNET_CLIENT_disconnect (vh->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (vh->client); vh->client = NULL; } if (GNUNET_SCHEDULER_NO_TASK != vh->rt) -- cgit v1.2.3-18-g5258